UtilitiesImpl.mesa
Last Edited by: Gutknecht, July 2, !985 0:39:22 am PDT
Last Edited by: Gutknecht, September 12, 1985 5:44:16 pm PDT
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: REFNIL, msg: Rope.ROPENIL] =
{ DumpFile: PROC [file, outmed: Rope.ROPE] =
{ f, g: IO.STREAM; ch: CHAR; onFile, opened: BOOLEANTRUE;
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: REFNIL, msg: Rope.ROPENIL] =
{ 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: BOOLEANTRUE;
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.