home *** CD-ROM | disk | FTP | other *** search
- Program DisGusta;
- { This program is a disassembler for p-code programs produced with }
- { the public domain Augusta Ada subset compiler. }
-
- {$R+ } { turn on subscript and type checking }
-
- Const
- dis_version = '1.0';
- nl = #13#10; {characters to start a new line }
- Type
- String5 = string[5];
- Var
- header : record
- code_size : integer; {code size in bytes}
- max_record : integer; {number of 128-byte records in the file }
- max_proc : integer; {number of procedures }
- version : integer; {code file version number}
- end;
- proctable : array[1..256] of record
- offset : integer; { offset from CS to proc code}
- local_var_bytes : integer; { # of bytes needed for local vars }
- parm_bytes : integer; { # of bytes needed for parameters }
- level : byte; { lexical level of the procedure }
- end;
- code_file : file of byte; { the program file }
- listing : text; { the listing file }
- Z,CP : integer; { work variables }
-
-
- Procedure Load_Program;
- { gets the name of the p-code file, opens it, and reads in the }
- { header and procedure table; opens the listing file. }
- var
- name : string[32]; { filename }
- temp1,temp2 : byte; { work variables }
- temp3,temp4 : byte;
- I : integer;
- N : string[1];
- error,original: boolean; { true when an error occured somewhere }
- begin
- { loop through the opening process until a valid file is found }
- Repeat
- error := false;
-
- { present the intro screen }
- clrscr; writeln('D i s g u s t a',nl,'Version ',dis_version);
-
- { get the filename and make sure it's available }
- repeat
- sound(660); delay(300); nosound;
- write(nl,'Input filename ? ');
- {$I-} readln(name); assign(code_file,name); reset(code_file); {$I+}
- until IOResult=0;
-
- { load the header block and make sure it's an augusta code file }
- with header do begin
- read(code_file, temp1,temp2,temp3,temp4);
- code_size := temp2*256 + temp1 - 1920;
- max_record := temp4*256 + temp3;
- read(code_file, temp1,temp2,temp3,temp4);
- max_proc := temp2*256 + temp1; version := temp4*256 + temp3;
- end;
- read(code_file, temp1,temp2,temp3,temp4);
- if not ((temp1=89) and (temp2=4) and (temp3=0) and (temp4=0))
- or (filesize(code_file)<1921) then begin
- writeln(name,' is not a valid Augusta p-code file.');
- delay(1000); error := true;
- end
-
- { read in only as many proc table entries as the header says exist }
- else begin
- seek(code_file,128);{ skip 116 unused header bytes to the proc table}
- for I:=1 to header.max_proc do
- with proctable[i] do begin
- read(code_file, temp1,temp2,temp3,temp4);
- offset := (temp2 shl 8) + temp1;
- local_var_bytes := (temp4 shl 8) + temp3;
- read(code_file, temp1,temp2,level);
- parm_bytes := (temp2 shl 8) + temp1;
- end;
- end;
- close(code_file);
- Until error=false;
-
- { leave the code file open now that we know it's legal }
- assign(code_file,name); reset(code_file);
- { find an original name for the listing file }
- Z := pos('.',name);
- if Z>0 then delete(name,Z,31);
- name := name + '.dis';
- {$I-}
- Z := 0;
- repeat
- assign(listing,name); reset(listing);
- if ioresult<>0 then
- original := true
- else begin
- close(listing);
- str(Z,N);
- name[length(name)] := N;
- Z := Z + 1;
- original := false;
- end;
- until original or (Z>9);
- {$I+}
- assign(listing,name); rewrite(listing);
- writeln(nl,'Listing file will be named ',#39,name,#39);
- end;
-
- Function Get_byte(var offset: integer): integer;
- { gets the byte at Offset into Byte1 and increments Offset to the next byte }
- var
- ch: byte;
- begin
- offset := offset + 1; read(code_file,ch); get_byte := ch;
- end;
-
- Function Get_Word(offset: integer): integer;
- { gets the word at Offset, leaving Offset as it was on entry }
- var
- ch,ch2: byte;
- begin
- read(code_file,ch,ch2); get_word := ch + (ch2 shl 8);
- end;
-
- Procedure Interpret_Code;
- { interprets the op-code in byte1, using additional bytes and }
- { adjusting CP accordingly. }
- var
- byte1 : byte; { gets the op-code byte }
- temp1,temp2,I : integer; { local work variables }
-
- procedure Load_Or_Store;
- begin
- temp2 := get_word(CP);
- case byte1 of
- 1: writeln(listing,'LDCI ',temp2);
- 2: writeln(listing,'LDL ',temp2);
- 3: writeln(listing,'LLA ',temp2);
- 4: begin writeln(listing,'LDB'); CP := CP - 2; end;
- 5: writeln(listing,'LDO ',temp2);
- 6: writeln(listing,'LAO ',temp2);
- 8: begin
- temp1 := get_byte(CP);
- writeln(listing,'LOD ',temp1,' ',temp2);
- end;
- 9: begin
- temp1 := get_byte(CP);
- writeln(listing,'LOA ',temp1,' ',temp2);
- end;
- end;
- CP := CP + 2;
- end; { load_or_store }
-
- Procedure Jump;
- begin
- temp1 := get_word(CP); CP := CP + 2;
- case byte1 of
- 37: writeln(listing,'UJP ',temp1,' -> ',(temp1+CP));
- 38: writeln(listing,'FJP ',temp1,' -> ',(temp1+CP));
- 39: begin
- temp2 := get_word(CP); I := get_word(CP+2);
- writeln(listing,'XJP ',temp1,',',temp2,' ',I,' -> ',(I+CP));
- CP := CP + 4;
- end;
- end;
- end;
-
- begin
- { get an op-code byte from the buffer }
- byte1 := get_byte(CP);
- write(listing,(CP-1):5,': ',byte1:6,' ');
-
- case byte1 of { Note- indented procedures are repeats from }
- 1..10: load_or_store; { a previous line. }
- 11: writeln(listing,'STO');
- 12: writeln(listing,'SINDO');
- 13: begin
- temp1 := get_byte(CP);
- write(listing,'LCA ',temp1,#32#39);
- while temp1>0 do begin
- temp2 := get_byte(CP);
- write(listing,char(temp2)); temp1 := temp1 - 1;
- end;
- writeln(listing,#39);
- end;
- 14: writeln(listing,'SAS');
- 15: begin
- writeln(listing,'EOP'); CP := -1; { flag CP on end-of-proc }
- end;
- 16: writeln(listing,'AND');
- 17: writeln(listing,'OR');
- 18: writeln(listing,'NOT');
- 19: writeln(listing,'ADI');
- 20: writeln(listing,'NGI');
- 21: writeln(listing,'SBI');
- 22: writeln(listing,'MPI');
- 23: writeln(listing,'DVI');
- 24: writeln(listing,'IND');
- 25: writeln(listing,'EQUI');
- 26: writeln(listing,'NEQI');
- 27: writeln(listing,'LEQI');
- 28: writeln(listing,'LESI');
- 29: writeln(listing,'GEQI');
- 30: writeln(listing,'GTRI');
- 31: writeln(listing,'EQUSTR');
- 32: writeln(listing,'NEQSTR');
- 33: writeln(listing,'LEQSTR');
- 34: writeln(listing,'LESSTR');
- 35: writeln(listing,'GEQSTR');
- 36: writeln(listing,'GTRSTR');
- 37..39: jump;
- 40: begin temp1 := get_byte(CP); writeln(listing,'CLP ',temp1); end;
- 41: begin temp1 := get_byte(CP); writeln(listing,'CGP ',temp1); end;
- 43: writeln(listing,'RET');
- 45: writeln(listing,'MODI');
- 46: writeln(listing,'RNP');
- 42: begin temp1 := get_byte(CP); writeln(listing,'CSP ',temp1); end;
- 47: writeln(listing,'RNP');
- 48: begin temp1 := get_byte(CP); writeln(listing,'IXA ',temp1); end;
- 49..56: writeln(listing,'SLDL',(byte1-49));
- 57: begin temp1 := get_byte(CP); writeln(listing,'SLDO ',temp1); end;
- 58: begin temp1 := get_byte(CP); writeln(listing,'SLAO ',temp1); end;
- 59: begin temp1 := get_byte(CP); writeln(listing,'SLLA ',temp1); end;
- 60: begin temp1 := get_byte(CP); writeln(listing,'SLDL ',temp1); end;
- 61: begin temp1 := get_byte(CP); writeln(listing,'SLDC ',temp1); end;
- 63: writeln(listing,'SLDCN1');
- 64..79: writeln(listing,'SLDC',(byte1-64));
- 80: begin
- temp1 := get_word(CP);
- writeln(listing,'INCL ',temp1); CP := CP + 2;
- end;
- 81: begin
- temp1 := get_word(CP);
- writeln(listing,'DECL ',temp1); CP := CP + 2;
- end;
- else writeln(listing,'???');
- end;
- end;
-
- BEGIN
-
- load_program;
- Z := 0;
- while Z<header.max_proc do begin
- Z := Z + 1;
- writeln(listing,nl,'Procedure ',Z);
- with proctable[Z] do begin
- writeln(listing,' Offset=',offset,', ',local_var_bytes,
- ' bytes local variables, ',parm_bytes,' bytes parameters, Level ',
- level,nl);
- CP := offset; seek(code_file,CP+1920);
- end;
- writeln(listing,'Offset Opcode Mnemonic (and parameters)');
- while CP>-1 do interpret_code;
- end;
- writeln(listing);
- close(code_file);
- close(listing);
-
- END.