<> <> <> DIRECTORY Rope USING [ROPE], FS USING [StreamOpen, Error], ViewerIO USING [CreateViewerStreams], IO USING [STREAM, EndOf, GetChar, PutChar, Put, char, card, int, rope, Close], Commander USING [Handle, Register], CommandTool USING [ArgumentVector, Parse, Failed]; UtilitiesImpl: CEDAR PROGRAM IMPORTS FS, ViewerIO, IO, Commander, CommandTool = BEGIN Dump: PROC [cmd: Commander.Handle] RETURNS [result: REF _ NIL, msg: Rope.ROPE _ NIL] = { DumpFile: PROC [file, outmed: Rope.ROPE] = { f, g: IO.STREAM; ch: CHAR; onFile, opened: BOOLEAN _ TRUE; val, dig: CARDINAL; f _ FS.StreamOpen [file ! FS.Error => { opened _ FALSE; CONTINUE }]; IF opened THEN { IF outmed # "*" THEN { g _ FS.StreamOpen [outmed, $create]; onFile _ TRUE } ELSE { [out: g] _ ViewerIO.CreateViewerStreams ["Dump Files"]; onFile _ FALSE }; IO.Put [g, IO.rope[file], IO.char['\n]]; WHILE NOT f.EndOf DO ch _ f.GetChar; val _ ch.ORD; IF FALSE THEN -- hex { dig _ val/16; IF dig < 10 THEN IO.PutChar [g, 60C + dig] ELSE IO.PutChar [g, 67C + dig]; dig _ val MOD 16; IF dig < 10 THEN IO.PutChar [g, 60C + dig] ELSE IO.PutChar [g, 67C + dig] } ELSE -- octal { IO.PutChar [g, 0C + val/4]; IO.PutChar [g, 0C + (val/8) MOD 8]; IO.PutChar [g, 0C + val MOD 8]; IO.PutChar [g, ' ] } ENDLOOP; IF onFile THEN IO.Close [g]; IO.Close [f] } ELSE IO.Put [cmd.out, IO.rope ["failed"], IO.char['\n]] }; arg: CommandTool.ArgumentVector _ CommandTool.Parse [cmd: cmd ! CommandTool.Failed => msg _ "failed"]; i: CARDINAL _ 1; WHILE i+1 < arg.argc DO DumpFile [arg[i], arg[i+1]]; i _ i + 2 ENDLOOP; IF i < arg.argc THEN DumpFile [arg[i], "*"] }; Decode: PROC [cmd: Commander.Handle] RETURNS [result: REF _ NIL, msg: Rope.ROPE _ NIL] = { OBJFILE: CARDINAL = 220; codeTab: PACKED ARRAY [0..32*48) OF CHAR; id: CARDINAL _ 0; Enter: PROC [s: REF TEXT] = { i: CARDINAL _ 0; WHILE i < 48 DO codeTab[id] _ s[i]; id _ id+1; i _ i+1 ENDLOOP }; DecodeFile: PROC [file, outmed: Rope.ROPE] = { f, g: IO.STREAM; ch, ch1, ch2, ch3: CHAR; onFile, opened: BOOLEAN _ TRUE; n: LONG CARDINAL; N, i, j: CARDINAL; pc: CARDINAL _ 0; nextno: PROC RETURNS [CARDINAL] = { ch: CHAR _ f.GetChar; ch1: CHAR _ f.GetChar; RETURN [ch.ORD + ch1.ORD*256] }; PutTab: PROC = { ch, ch1: CHAR; n: CARDINAL _ 0; N: CARDINAL _ nextno []; WHILE n # N DO ch _ f.GetChar; ch1 _ f.GetChar; IO.Put [g, IO.card[ch.ORD + ch1.ORD*256], IO.char['\n]]; n _ n + 1 ENDLOOP; IO.PutChar [g, '\n] }; f _ FS.StreamOpen [file ! FS.Error => { opened _ FALSE; CONTINUE }]; IF opened THEN { IF outmed # "*" THEN { g _ FS.StreamOpen [outmed, $create]; onFile _ TRUE } ELSE { [out: g] _ ViewerIO.CreateViewerStreams ["Decode Files"]; onFile _ FALSE }; IO.Put [g, IO.rope[file], IO.char['\n], IO.char['\n]]; IF nextno [] = OBJFILE THEN { IO.Put [g, IO.rope["imports"], IO.char['\n]]; N _ nextno []; i _ 0; WHILE i # N DO IO.Put [g, IO.card[nextno []], IO.card[nextno []], IO.char[' ]]; ch _ f.GetChar; j _ ch.ORD-1; WHILE j # 0 DO IO.Put [g, IO.char [f.GetChar]]; j _ j - 1 ENDLOOP; IO.Put [g, IO.char['\n]]; i _ i + 1 ENDLOOP; IO.PutChar [g, '\n]; IO.Put [g, IO.rope["code"], IO.char['\n]]; N _ nextno []; WHILE pc # N DO IO.Put [g, IO.card[pc], IO.char[' ]]; ch _ f.GetChar; i _ ch.ORD*6; WHILE codeTab[i] < 'a DO IO.PutChar [g, codeTab[i]]; i _ i+1 ENDLOOP; IO.PutChar [g, ' ]; SELECT codeTab[i] FROM 'a, 'f => { pc _ pc + 1 }; 'b, 'g => { ch _ f.GetChar; IO.Put [g, IO.card[ch.ORD]]; pc _ pc + 2 }; 'c => { ch _ f.GetChar; ch1 _ f.GetChar; IO.Put [g, IO.card[ch.ORD+ch1.ORD*256]]; pc _ pc + 3 }; 'd => { ch _ f.GetChar; ch1 _ f.GetChar; ch2 _ f.GetChar; ch3 _ f.GetChar; n _ ch.ORD+(ch1.ORD+(ch2.ORD+ch3.ORD*256)*256)*256; IO.Put [g, IO.int[ LOOPHOLE [n, LONG INTEGER]]]; pc _ pc + 5 }; 'e => { ch _ f.GetChar; IF ch.ORD >= 128 THEN IO.Put [g, IO.int[ch.ORD - 256]] ELSE IO.Put [g, IO.int[ch.ORD]]; IO.PutChar [g, ' ]; ch _ f.GetChar; IO.Put [g, IO.card[ch.ORD]]; pc _ pc + 3 }; 'h => { ch _ f.GetChar; IO.Put [g, IO.card[ch.ORD], IO.char [' ]]; ch _ f.GetChar; IO.Put [g, IO.card[ch.ORD/16], IO.char [' ], IO.card[ch.ORD MOD 16]]; pc _ pc + 3 }; 'i => { ch _ f.GetChar; IO.Put [g, IO.card[ch.ORD/128], IO.card[(ch.ORD/64) MOD 2]]; IO.Put [g, IO.card[(ch.ORD/32) MOD 2], IO.card[(ch.ORD/16) MOD 2]]; IO.PutChar [g, ' ]; IO.Put [g, IO.card[ch.ORD MOD 16], IO.char [' ]]; ch _ f.GetChar; IO.Put [g, IO.card[ch.ORD/16], IO.char[' ], IO.card[ch.ORD MOD 16]]; pc _ pc + 3 }; 'j => { ch _ f.GetChar; IO.Put [g, IO.card[(ch.ORD/32) MOD 2], IO.char[' ]]; IO.Put [g, IO.card[(ch.ORD/16) MOD 2], IO.char[' ]]; IO.Put [g, IO.card[ch.ORD MOD 16]]; pc _ pc + 2 }; 'k => { ch _ f.GetChar; IO.Put [g, IO.card[ch.ORD/128], IO.card[(ch.ORD/64) MOD 2]]; IO.Put [g, IO.card[(ch.ORD/32) MOD 2], IO.card[(ch.ORD/16) MOD 2]]; IO.PutChar [g, ' ]; IO.Put [g, IO.card[ch.ORD MOD 16], IO.char [' ]]; ch _ f.GetChar; IF ch.ORD >= 128 THEN IO.Put [g, IO.int[ch.ORD - 256]] ELSE IO.Put [g, IO.int[ch.ORD]]; pc _ pc + 3 }; 'l => { ch _ f.GetChar; ch1 _ f.GetChar; IO.Put [g, IO.int[ch.ORD+ch1.ORD*256]]; pc _ pc + 3 }; ENDCASE; IO.PutChar [g, '\n] ENDLOOP; IO.PutChar [g, '\n]; IO.Put [g, IO.rope["entries"], IO.char['\n]]; PutTab; IO.Put [g, IO.rope["reloc"], IO.char['\n]]; PutTab; IO.Put [g, IO.rope["data"], IO.char['\n]]; IO.Put [g, IO.card[nextno []], IO.char['\n], IO.char['\n]]; IO.Put [g, IO.rope["literals"], IO.char['\n]]; N _ nextno []; IO.Put [g, IO.card[N], IO.char['\n]]; i _ 0; WHILE i # N DO ch _ f.GetChar; IF ch = 0C THEN ch _ '\n; IO.Put [g, IO.char [ch]]; i _ i + 1 ENDLOOP; IO.PutChar [g, '\n]; IF onFile THEN IO.Close [g]; IO.Close [f] } ELSE IO.Put [cmd.out, IO.rope ["not an obj file"], IO.char['\n]] } ELSE IO.Put [cmd.out, IO.rope ["failed"], IO.char['\n]] }; arg: CommandTool.ArgumentVector _ CommandTool.Parse [cmd: cmd ! CommandTool.Failed => msg _ "failed"]; i: CARDINAL _ 1; Enter ["XOPa XOPa XOPa XOPa XOPa XOPa XOPa XOPa "]; Enter ["XOPa XOPa XOPa XOPa XOPa XOPa XOPa XOPa "]; Enter ["XOPa XOPa XOPa XOPa XOPa XOPa XOPa XOPa "]; Enter ["XOPa XOPa XOPa XOPa XOPa XOPa XOPa XOPa "]; Enter ["XOPd XOPd XOPd XOPd XOPd XOPd XOPd XOPd "]; Enter ["XOPd XOPd XOPd XOPd XOPd XOPd XOPd XOPd "]; Enter ["XOPd DFCd LIQBd XOPd XOPd XOPd J5d DJd "]; Enter ["CALLd XOPd XOPd XOPd XOPd XOPd XOPd XOPd "]; Enter ["***a ***a RXa BCa ADDa SUBa LADDa LSUBa "]; Enter ["DUPa DISa EXCHa EXDISaSFCa SFCIa RETNa XOPa "]; Enter ["XOPa SMULa UDIVa XOPa KFCa XOPa J1a SJa "]; Enter ["LC0a LC1a LC2a LC3a LC4a LC5a LC6a LC7a "]; Enter ["LR0f LR1f LR2f LR3f LR4f LR5f LR6f LR7f "]; Enter ["LR8f LR9f LR10f LR11f LR12f LR13f LR14f LR15f "]; Enter ["SR0f SR1f SR2f SR3f SR4f SR5f SR6f SR7f "]; Enter ["SR8f SR9f SR10f SR11f SR12f SR13f SR14f SR15f "]; Enter ["QORj QANDj QRXj QBCj QADDj QSUBj QLADDjQLSUBj"]; Enter ["ALSb ALb ASLb ASb CSTb XOPb RETb RETKb "]; Enter ["LIPb SIPb LIBb SFPb ADDBb SUBBb J2b JBb "]; Enter ["RBb WBb RSBb WSBb PINb POUTb XOPb PSBb "]; Enter ["LRI0g LRI1g LRI2g LRI3g LRI4g LRI5g LRI6g LRI7g "]; Enter ["LRI8g LRI9g LRI10gLRI11gLRI12gLRI13gLRI14gLRI15g"]; Enter ["SRI0g SRI1g SRI2g SRI3g SRI4g SRI5g SRI6g SRI7g "]; Enter ["SRI8g SRI9g SRI10gSRI11gSRI12gSRI13gSRI14gSRI15g"]; Enter ["RORi RANDi RRXi RBCi RADDi RSUBi RLADDiRLSUBi"]; Enter ["RXORi ***i RFUi ***i RVADDiRVSUBiRUADDiRUSUBi"]; Enter ["LGFc LFCl LIDBc XOPc ADDDBcSUBDBcJ3c JDBl "]; Enter ["RAIh WAIh RRIh WRIh INb OUTb XOPh XOPh "]; Enter ["***k RJEBk RJLBk RJLEBk***k RJNEBkRJGEBkRJGBk "]; Enter ["***k RJNEJkRJGEJkRJGBJk***k RJEBJkRJLBJkRJLEJk"]; Enter ["JEBBe JNEBBeJEBBJeJNEBJeXOPe XOPe XOPe XOPe "]; Enter ["SHLc SHRc SHDc FSDBc FLIPc FLOPc XOPc XOPc "]; WHILE i+1 < arg.argc DO DecodeFile [arg[i], arg[i+1]]; i _ i + 2 ENDLOOP; IF i < arg.argc THEN DecodeFile [arg[i], "*"] }; Commander.Register[key: "dump", proc: Dump, doc: "Dump file in hex form"]; Commander.Register[key: "decode", proc: Decode, doc: "Decode object file"]; END.