ack/util/ass/asprint.p

386 lines
11 KiB
OpenEdge ABL
Raw Normal View History

1984-07-02 15:46:59 +00:00
#
{$d+}
program asprint(prog,output);
const
{ header words }
NTEXT = 1;
NDATA = 2;
NPROC = 3;
ENTRY = 4;
NLINE = 5;
SZDATA = 6;
escape1 = 254; { escape to secondary opcodes }
escape2 = 255; { escape to tertiary opcodes }
type
byte= 0..255; { memory is an array of bytes }
adr= {0..maxadr} long; { the range of addresses }
word= {0..maxuint} long;{ the range of unsigned integers }
size= 0..32766; { the range of sizes is the positive offsets }
sword= {-signbit..maxsint} long; { the range of signed integers }
full= {-maxuint..maxuint} long; { intermediate results need this range }
double={-maxdbl..maxdbl} long; { double precision range }
insclass=(prim,second,tert); { tells which opcode table is in use }
instype=(implic,explic); { does opcode have implicit or explicit operand }
iflags= (mini,short,sbit,wbit,zbit,ibit);
ifset= set of iflags;
mnem = ( NON,
AAR, ADF, ADI, ADP, ADS, ADU,XAND, ASP, ASS, BEQ,
BGE, BGT, BLE, BLM, BLS, BLT, BNE, BRA, CAI, CAL,
CFF, CFI, CFU, CIF, CII, CIU, CMF, CMI, CMP, CMS,
CMU, COM, CSA, CSB, CUF, CUI, CUU, DCH, DEC, DEE,
DEL, DUP, DUS, DVF, DVI, DVU, EXG, FEF, FIF, FIL,
GTO, INC, INE, INL, INN, IOR, LAE, LAL, LAR, LDC,
LDE, LDF, LDL, LFR, LIL, LIM, LIN, LNI, LOC, LOE,
LOF, LOI, LOL, LOR, LOS, LPB, LPI, LXA, LXL, MLF,
MLI, MLU, MON, NGF, NGI, NOP, RCK, RET, RMI, RMU,
ROL, ROR, RTT, SAR, SBF, SBI, SBS, SBU, SDE, SDF,
SDL,XSET, SIG, SIL, SIM, SLI, SLU, SRI, SRU, STE,
STF, STI, STL, STR, STS, TEQ, TGE, TGT, TLE, TLT,
TNE, TRP, XOR, ZEQ, ZER, ZGE, ZGT, ZLE, ZLT, ZNE,
ZRE, ZRF, ZRL);
dispatch = record
iflag: ifset;
instr: mnem;
case instype of
implic: (implicit:sword);
explic: (ilength:byte);
end;
var
{ variables indicating the size of words and addresses }
wsize: integer; { number of bytes in a word }
asize: integer; { number of bytes in an address }
pdsize: integer; { size of procedure descriptor in bytes = 2*asize }
pc,lb,sp,hp,pd: adr; { internal machine registers }
i: integer; { integer scratch variable }
s,t :word; { scratch variables }
sz:size; { scratch variables }
ss,st: sword; { scratch variables }
k :double; { scratch variables }
j:size; { scratch variable used as index }
a,b:adr; { scratch variable used for addresses }
dt,ds:double; { scratch variables for double precision }
found:boolean; { scratch }
opcode: byte;
iclass: insclass;
dispat: array[insclass, byte] of dispatch ;
insr: mnem; { holds the instructionnumber }
header: array[1..8] of adr;
prog: file of byte; { program and initialized data }
procedure getit; { start the ball rolling }
var cset:set of char;
f:ifset;
insno:byte;
iclass: insclass;
1984-07-02 15:46:59 +00:00
nops:integer;
opcode:byte;
i,j,n:integer;
wtemp:sword;
count:integer;
repc:adr;
nexta,firsta:adr;
elem:byte;
amount,ofst:size;
c:char;
function readb(n:integer):double;
var b:byte;
begin
if eof(prog) then
begin writeln('Premature EOF on EM load file') ; halt end;
read(prog,b); if n>1 then readb:=readb(n-1)*256+b else readb:=b
end;
function readbyte:byte;
begin readbyte:=readb(1) end;
procedure skipbyte;
var dummy: byte;
begin dummy:=readb(1) end;
function readword:word;
begin readword:=readb(wsize) end;
function readadr:adr;
begin readadr:=readb(asize) end;
function ifind(ordinal:byte):mnem;
var loopvar:mnem;
found:boolean;
begin ifind:=NON;
loopvar:=insr; found:=false;
repeat
if ordinal=ord(loopvar) then
begin found:=true; ifind:=loopvar end;
if loopvar<>ZRL then loopvar:=succ(loopvar) else loopvar:=NON;
until found or (loopvar=insr) ;
end;
procedure readhdr;
type hdrw=0..32767 ; { 16 bit header words }
var hdr: hdrw;
i: integer;
begin
for i:=0 to 7 do
begin hdr:=readb(2);
case i of
0: if hdr<>3757 then { 07255 }
begin writeln('Not an em load file'); halt end;
1: writeln('Test flags: ',hdr);
2: if hdr<>0 then
begin writeln('Unsolved references: ',hdr) end;
3: if hdr<>3 then
begin writeln('Incorrect load file version') end;
4: wsize:=hdr ;
5: begin asize:=hdr ; pdsize:= asize+asize end;
6,7:
if hdr<>0 then
begin writeln('First header entry ',i,', is ',hdr) end;
end
end;
writeln('word size',wsize,', pointer size',asize)
end;
procedure noinit;
begin writeln('Illegal initialization'); halt end;
procedure readint(a:adr;s:size);
const mrange = 4;
var i:size;
val:double;
cont: array[1..mrange] of byte;
begin { construct integer out of byte sequence }
if s<=mrange then
begin
for i:=1 to s do cont[i]:=readbyte ;
if cont[s]>=128 then val:=cont[s]-256 else val:=cont[s];
for i:= s-1 downto 1 do val:= val*256 + cont[i];
writeln(', value ',val)
end
else
begin
write(', bytes(little endian) ');
for i:=1 to s do write(readbyte:4) ;
writeln
end
end;
procedure readuns(a:adr;s:size);
const mrange=3;
var i:size;
val:double;
cont: array[1..mrange] of byte;
begin { construct unsigned integer out of byte sequence }
if s<=mrange then
begin
for i:=1 to s do cont[i]:=readbyte ;
val:=0;
for i:= s downto 1 do val:= val*256 + cont[i];
writeln(', value ',val)
end
else
begin
write(', bytes(little endian) ');
for i:=1 to s do write(readbyte:4) ;
writeln
end
end;
procedure readfloat(a:adr;s:size);
var i:size; b:byte;
begin { construct float out of string}
i:=0;
repeat { eat the bytes, construct the value and intialize at a }
write(chr(readbyte)); i:=i+1;
until b=0 ;
end;
begin
#ifdef INSRT
{ initialize tables }
for iclass:=prim to tert do
for i:=0 to 255 do
with dispat[iclass][i] do
begin instr:=NON; iflag:=[zbit] end;
{ read instruction table file. see appendix B }
{ The table read here is a simple transformation of the table on page xx }
{ - instruction names were transformed to numbers }
{ - the '-' flag was transformed to an 'i' flag for 'w' type instructions }
{ - the 'S' flag was added for instructions having signed operands }
reset(tables);
insr:=NON;
repeat
read(tables,insno) ; cset:=[]; f:=[];
insr:=ifind(insno);
if insr=NON then begin writeln('Incorrect table'); halt end;
repeat read(tables,c) until c<>' ' ;
repeat
cset:=cset+[c];
read(tables,c)
until c=' ' ;
if 'm' in cset then f:=f+[mini];
if 's' in cset then f:=f+[short];
if '-' in cset then f:=f+[zbit];
if 'i' in cset then f:=f+[ibit];
if 'S' in cset then f:=f+[sbit];
if 'w' in cset then f:=f+[wbit];
if (mini in f) or (short in f) then read(tables,nops) else nops:=1 ;
readln(tables,opcode);
if ('4' in cset) or ('8' in cset) then
begin iclass:=tert end
else if 'e' in cset then
begin iclass:=second end
else iclass:=prim;
for i:=0 to nops-1 do
begin
with dispat[iclass,opcode+i] do
begin
iflag:=f; instr:=insr;
if '2' in cset then ilength:=2
else if '4' in cset then ilength:=4
else if '8' in cset then ilength:=8
else if (mini in f) or (short in f) then
begin
if 'N' in cset then wtemp:=-1-i else wtemp:=i ;
if 'o' in cset then wtemp:=wtemp+1 ;
if short in f then wtemp:=wtemp*256 ;
implicit:=wtemp
end
end
end
until eof(tables);
#endif
{ read in program text, data and procedure descriptors }
reset(prog);
readhdr; { verify first header }
for i:=1 to 8 do header[i]:=readadr; { read second header }
writeln('textsize ',header[NTEXT],', datasize ',header[SZDATA]);
writeln('data descriptors: ',header[NDATA]);
writeln('procedure descriptors: ',header[NPROC]);
writeln('entry procedure: ',header[ENTRY]);
if header[7]<>0 then writeln('Second header entry 7 is ',header[7]);
if header[8]<>0 then writeln('Second header entry 8 is ',header[8]);
{ read program text }
for i:=0 to header[NTEXT]-1 do skipbyte;
{ read data blocks }
writeln; writeln('Data descriptors:');
nexta:=0;
for i:=1 to header[NDATA] do
begin
n:=readbyte;
write(nexta:5,'- ');
if n<>0 then
begin
elem:=readbyte; firsta:=nexta;
case n of
1: { uninitialized words }
begin
writeln(elem,' uninitialised word(s)');
nexta:= nexta+ elem*wsize ;
end;
2: { initialized bytes }
begin
write(elem,' initialised byte(s)');
for j:=1 to elem do
begin
if j mod 10 = 1 then
begin writeln ; write(nexta:6,':') end ;
write(readbyte:4); nexta:=nexta+1
end;
writeln
end;
3: { initialized words }
begin
write(elem,' initialised word(s)');
for j:=1 to elem do
begin
if j mod 8 = 1 then
begin writeln ; write(nexta:6,':') end ;
write(readword:9); nexta:=nexta+wsize
end;
writeln
end;
4,5: { instruction and data pointers }
begin
if n=4 then
write(elem,' initialised data pointers')
else
write(elem,' initialised instruction pointers');
for j:=1 to elem do
begin
if j mod 8 = 1 then
begin writeln ; write(nexta:6,':') end ;
write(readadr:9); nexta:=nexta+asize
end;
writeln
end;
6: { signed integers }
begin
write(elem,'-byte signed integer ');
readint(nexta,elem); nexta:=nexta+elem
end;
7: { unsigned integers }
begin
write(elem,'-byte unsigned integer ');
readuns(nexta,elem); nexta:=nexta+elem
end;
8: { floating point numbers }
begin
write(elem,'-byte floating point number ');
readfloat(nexta,elem); nexta:=nexta+elem
end;
end
end
else
begin
repc:=readadr;
amount:=nexta-firsta;
writeln(repc,' copies of the data from ',firsta:2,' to ',nexta:2);
nexta:= nexta + repc*amount ;
end
end;
if header[SZDATA]<>nexta then writeln('Data initialization error');
{ read descriptor table }
pd:=header[NTEXT];
for i:=1 to header[NPROC]*pdsize do skipbyte;
end;
begin getit;
#ifdef RTC
repeat
opcode := nextpc; { fetch the first byte of the instruction }
if opcode=escape1 then iclass:=second
else if opcode=escape2 then iclass:=tert
else iclass:=prim;
if iclass<>prim then opcode := nextpc;
with dispat[iclass][opcode] do
begin insr:=instr;
if not (zbit in iflag) then
if ibit in iflag then k:=pop else
begin
if mini in iflag then k:=implicit else
begin
if short in iflag then k:=implicit+nextpc else
begin k:=nextpc;
if (sbit in iflag) and (k>=128) then k:=k-256;
for i:=2 to ilength do k:=256*k + nextpc
end
end;
if wbit in iflag then k:=k*wsize;
end
end;
#endif
end.