|
|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 188160 (0x2df00)
Types: TextFile
Names: »hpasc1next«
└─⟦621cfb9a2⟧ Bits:30002817 RC8000 Dump tape fra HCØ. Detaljer om "HC8000" projekt.
└─⟦0364f57e3⟧
└─⟦this⟧ »hpasc1next«
(* L-*)
(* M20 *)
(* COPYRIGHTED 1980 BY MOTOROLA, INC. *)
PROGRAM direct(output,pcode,object,listing);
(* AUGUST 7, 1980 *)
(* GENERATES S-RECORDS *)
(* 370 VERSION *)
(* LONG ADDRESSES *)
(* DIRECT CODE VERSION *)
(* 01/08/82 @ REPLACED BY ^ *
* (. REPLACED BY Æ *
* .) REPLACED BY Å *
* EXTERNAL REPLACED BY XEXTERNAL *
* FILE OF CHAR REPLACED BY TEXT *
* HENRIK JACOBSEN HC *)
CONST strlength = 64;
linelngth = 133;
bitsperdigit = 8;
ldigit = 3;
topdigit = 255;
maxdigit = 256;
maxlabel = 400;
maxcore = 1044;
stkmax = 32;
ndregs = 5; naregs = 3; (*NBR OF REGS TO BE ALLOCATED FOR STACK*)
TYPE optyps = (op0, opli, opt, op2t, opti, opt2i, opi, optli,
op3i, optl2i, optl, opent, opentb, optv, oplab, endop);
pcodes=(xab, xad, xafi, xand, xarg,
xast, xatn, xchk, xchkf, xclo, xcos, xcsp,
xcspf,xcup, xcupf,xcvb, xcvt, xdas, xdata,xdatb,xdec, xdef, xdif,
xdis, xdv, xeio, xend, xent, xentb,xeof, xeol, xequ, xexi, xexp,
xext, xfjp, xgeq, xget, xgrt, xifd, xinc, xind, xinn, xins, xint,
xior, xisc, xixa, xlab, xlca, xlda, xldc, xleq, xles, xlod, xlog,
xlsc, xlspa,xlta, xlupa,xmod, xmov, xmovv,xmp, xmrk, xmst, xneq,
xnew, xng, xnot, xodd, xpag, xpee, xpok, xpos, xput, xrdb, xrdc,
(*604*) xrde, xrdh, xrdi, xrdj, xrdq, xrdr, xrds, xrdv, xret, xrln, xrls, xrnd,
xrst, xrwt, xsb, xscon,xscop,xsdel,xsee, xsgs, xsin, xsins,xslen,
(*RM*) xspos,xsqr, xsqt, xsto, xstp, xstr, xtrc, xujp, xuni, xvjp, xwln, xwrb,
(*604*) xwrc, xwre, xwrh, xwri, xwrj, xwrq, xwrr, xwrs, xwrv, xxjp, xstc, xnone,
xindv, xlodv, xstrv, xstov, xequv, xneqv, xlesv, xleqv,
xgrtv, xgeqv, xcvtsu, xcvtus, xldcv);
mns = xab .. xnone;
targetop = (tmove, tlink, tunlk, trts , ttst, tbgt, tneg, tsubq,
tbtst, tsnz, tadd, tsub, tand, tor, tmuls, tdivs,
tcmp, tclr, ttrap, tdcnt, tbsr, taddq,tcomp, tlbsr,
tmoveq,tseq, tsne, tslt, tsle, tsgt, tsge, tlea ,
tlbgt, tlbra, tlbne, tlbeq, tlblt, tasl, tblt, tjmp,
(*RM*) tpea, tbset, tbz, tswap, tcmpm, tjsr,
tbnz, tbge, tble, tchk, tlble, tlbge,
(*RM*) tldq, texte, tbra, tbne, tequ, tbeq, teor, tdc );
datatype = (atyp,ityp,jtyp,rtyp,qtyp,vtyp,styp,btyp,
(*RM*) ptyp,notatyp,ctyp,htyp,utyp);
message = PACKED ARRAYÆ1..15Å OF char;
errormessage = PACKED ARRAYÆ1..20Å OF char;
iptr = ^instruction;
instruction = RECORD inuse : boolean;
next : iptr;
(*PREV : IPTR;*)
opcode: mns;
optype: optyps;
dtype,d1type: datatype;
opand1: integer;
opand2: integer;
opand3: integer;
opand4: integer;
opstring: ^vstringv;
(*RM*) opset: ^setr
END;
vstringv = RECORD stringl: 0..strlength;
vstringa: PACKED ARRAY Æ 1..strlengthÅ OF char
END;
lint = ARRAY Æ0..ldigitÅ OF integer; (*MULTIPLE PRECISION*)
address = lint; (*SHOULD BE "RECORD BYTE1,BYTE2,BYTE3:0..255 END"*)
labelref = RECORD coreloc: address;
next: ^labelref
END;
labl = RECORD location: address;
defined: boolean;
refed: boolean;
refchain: ^labelref;
END;
labtable = ARRAYÆ0..maxlabelÅ OF labl;
esd = RECORD name: mns; (*XEXTERNAL SYMBOL DEFINITION LIST*)
reference: address;
next: ^esd
END;
eamode = (none,ddirect,adirect,defer,incr,decr,
(*RM*) based,index, pcindex, stshort,
relative,xexternal,labelled, labimmed,
(*RM*) pimmed,
limmed,
(*RM*) immed,absolute,stlong); (* THIS ORDER IS IMPORTANT *)
register = (dnone,d0,d1,d2,d3,d4,d5,d6,d7,
anone,a0,a1,a2,a3,a4,a5,a6,a7);
regkind = (areg, dreg);
effaddr = RECORD mode: eamode;
reg: register;
xreg: register;
displ: integer
END;
(*RM*) setr = RECORD
(*RM*) setv: PACKED ARRAYÆ1..16Å OF char
(*RM*) END;
VAR
debug: integer; (*DIAGNOTSIC FLAG *)
changed: boolean;
ascii: ARRAYÆcharÅ OF integer;
c: char;
errorwr: boolean;
listing: text;
pcode: text;
object: text;
chcnt,linelen: 1..linelngth;
linebuf: ARRAYÆ1..linelngthÅ OF char;
linecount: integer;
machindex: integer;
size: ARRAYÆdatatypeÅ OF integer;
(*RM*) dname: PACKED ARRAYÆdatatypeÅ OF char;
longtypes: SET OF datatype; (* = ÆPTYP,VTYP,STYPÅ*)
(*RM*) lastlabel: integer; (* LABEL OF LAST LABELLED PCODE *)
firsti, lasti, curri, optimi, tempi : iptr;
(*480*) fakei: iptr; (* DUMMY PCODE *)
optim2,optim3,optim4,optim5 : iptr;
curropcode: mns; curroptype: optyps;
templevel: integer; (*LEVEL OF DISPLAY VECTOR CURRENTLY IN A4*)
commutative, switch: boolean;
opsym: PACKED ARRAYÆ1..4Å OF char;
machcode: PACKED ARRAYÆ1..20Å OF char;
vstring, blanks: PACKED ARRAYÆ1..strlengthÅ OF char;
currlabel, highlabel, labeloffset, defvalue: integer;
toplabel : integer;
labeled, dollar, absol: boolean;
level, alength: integer;
flpc: boolean;
fmn: ARRAYÆ'A'..'Z'Å OF mns;
mn: ARRAYÆmnsÅ OF PACKED ARRAYÆ1..4Å OF char;
ot: ARRAYÆmnsÅ OF optyps;
subtype: ARRAYÆmnsÅ OF 0..255;
rt: ARRAYÆpcodesÅ OF integer; (* ADDRESSES OF RUNTIME ROUTINES*)
fl: ARRAYÆmnsÅ OF boolean;
tmn: ARRAYÆtargetopÅ OF PACKED ARRAYÆ1..5Å OF char;
labeltable, proctable: labtable;
pc: address;
ltemp: lint; (* TEMPORARY FOR LONG ARITHMETIC *)
core: ARRAYÆ1..maxcoreÅ OF integer;
genloc: lint; (* CURRENT CODEGEN ADDRESS *)
genstart: lint; (* FIRST ADDRESS OF CODE *)
gensave: lint; (*TEMP TO SAVE GENLOC *)
exproc: address; (* SLOT TO STORE JUMP TO DISTANT PROC IN *)
corecount: 0..maxcore;
coresave: 0..maxcore;
locount: 0..maxcore;
mainflg: boolean; (* MAIN PROGRAM ENCOUNTERED *)
corebase: address;
progstart: address;
rtjump: address; (* START OF RUNTIME JUMP TABLE *)
stkstart: address; (* START OF STACK *)
heapstart: address; (* START OF HEAP *)
jtsize: integer; (* NUMBER OF JUMP TABLE ELEMENTS *)
firstesd: ^esd;
sp: register;
dalloc,aalloc: 0..8;
dtop,dbot: dnone..d7;
atop,abot: anone..a7;
(*REGISTER ALLOCATION VARIABLES*)
(*VALUE OF -1 MEANS NONE CURRENTLY ASSIGNED*)
regtype: ARRAYÆregisterÅ OF datatype;
typestk: ARRAYÆ-1..stkmaxÅ OF datatype;
kindstk: ARRAYÆ-1..stkmaxÅ OF regkind;
stkptr: -1..stkmax;
dregs: ARRAYÆ0..ndregsÅ OF register;
aregs: ARRAYÆ0..naregsÅ OF register;
eaddir, eaadir, eapop, eapush, eaimmed, eaincr,
(*RM*) ealimm, earel, ealab, eapset, ealong,
eabased, eanone, eadefer: effaddr;
aalloccnt, dalloccnt, dpushcnt, apushcnt, dpopcnt, apopcnt: integer;
tempesd: ^esd;
templabref: ^labelref;
(*RM*) hexdata: PACKED ARRAYÆ1..16Å OF char;
FUNCTION succibm(ch:char):char; (* HANDLES EBCDIC ALPHABET *)
BEGIN
IF ch = 'I' THEN succibm := 'J'
ELSE IF ch ='R' THEN succibm := 'S'
ELSE succibm := succ(ch)
END (* SUCCIBM *) ;
FUNCTION hexbin(i: integer): integer; (* CONVERT HEX CHAR TO BINARY *)
BEGIN
IF i >= 65
THEN hexbin := i - 55
ELSE hexbin := i - 48
END; (* HEXBIN *)
PROCEDURE error(msg: errormessage);
BEGIN errorwr:=true;writeln(listing,'**ERROR** ',msg) END; (* ERROR *)
(*480*) FUNCTION nextpcod (pcode: iptr) : iptr;
(*480*) (* GIVEN A PCODE, FIND NEXT ACTIVE ONE; IF NONE, RETURN FAKE ONE *)
(*480*) BEGIN
(*480*) REPEAT
(*480*) pcode := pcode^.next;
(*480*) IF pcode = NIL THEN pcode := fakei
(*480*) UNTIL pcode^.inuse;
(*480*) nextpcod := pcode
(*480*) END; (*NEXTPCOD *)
FUNCTION conditional(inst:iptr):integer;
(* IF CONDITIONAL P-CODE, RETURN NUMBER, ELSE RETURN 0 *)
BEGIN
WITH inst^ DO
BEGIN
conditional := 0;
IF opcode = xneq THEN conditional := 1 ELSE
IF opcode = xequ THEN conditional := 2 ELSE
IF opcode = xles THEN conditional := 3 ELSE
IF opcode = xleq THEN conditional := 4 ELSE
IF opcode = xgrt THEN conditional := 5 ELSE
IF opcode = xgeq THEN conditional := 6
END (*WITH*)
END; (*CONDITIONAL*)
FUNCTION gethex:boolean;
VAR i: integer;
BEGIN
gethex := false;
WHILE (linebufÆchcntÅ=' ') AND (chcnt<linelen) DO chcnt := chcnt + 1;
IF linebufÆchcntÅ <> ' '
THEN BEGIN
gethex := true;
FOR i := 0 TO 3 DO
BEGIN
ltempÆiÅ := 16 * hexbin(asciiÆlinebufÆchcntÅÅ) +
hexbin(asciiÆlinebufÆchcnt + 1ÅÅ);
chcnt := chcnt + 2
END
END;
IF linebufÆchcntÅ <> ' ' THEN gethex := false;
END ; (*GETHEX*)
PROCEDURE getstring;
BEGIN
WHILE (linebufÆchcntÅ = ' ') AND (chcnt < linelen) DO
chcnt := chcnt + 1;
IF linebufÆchcntÅ <> '''' THEN
BEGIN error('STRING EXPECTED ');
vstring := blanks END
ELSE BEGIN
alength := 0;
REPEAT
REPEAT
chcnt := chcnt + 1;
alength := alength + 1;
IF alength <= strlength THEN
vstringÆalengthÅ := linebufÆchcntÅ;
UNTIL (linebufÆchcntÅ = '''') OR (chcnt = linelen);
chcnt := chcnt + 1
UNTIL linebufÆchcntÅ <> '''';
IF alength > strlength
THEN alength := strlength
ELSE alength := alength - 1;
END
END; (*GETSTRING*)
FUNCTION getinteger :integer;
VAR i: integer;
ch: char;
minus: boolean;
BEGIN
WHILE (linebufÆchcntÅ = ' ') AND (chcnt < linelen) DO
chcnt := chcnt + 1;
i := 0;
minus := linebufÆchcntÅ = '-';
IF minus THEN chcnt := chcnt + 1;
WHILE (linebufÆchcntÅ <> ' ') AND (chcnt < linelen) DO
BEGIN
ch := linebufÆchcntÅ;
IF (ch >= '0') AND (ch <= '9')
THEN i := i*10 + ord(ch)-ord('0')
(*RM*) ELSE IF linebufÆchcntÅ <> ',' THEN error('MALFORMED INTEGER ');
chcnt := chcnt + 1
END;
IF minus THEN getinteger := -1*i ELSE getinteger := i
END; (*GETINTEGER*)
PROCEDURE buildaddr (VAR addr: effaddr; kmode: eamode;
kreg, kxreg: register; kdispl: integer);
BEGIN WITH addr DO BEGIN
mode := kmode;
reg := kreg;
xreg := kxreg;
displ:= kdispl
END END; (*BUILDADDR*)
(*----------------------------------------------------------------------
MULTIPLE PRECISION ARITHMETIC ROUTINES
-----------------------------------------------------------------------*)
PROCEDURE plint(VAR fil:text; x:lint); (* WRITE LONG VALUE *)
VAR i: integer;
BEGIN
FOR i := 0 TO ldigit DO
write(fil,hexdataÆ(xÆiÅ DIV 16) + 1Å:1,
hexdataÆ(xÆiÅ MOD 16) + 1Å:1);
END; (*PLINT*)
FUNCTION sdv(VAR x: lint; s: integer): integer; (*DIVIDE LONG BY INTEGER *)
(* X := X / S (UNSIGNED) *)
VAR
i, carry: integer;
z: lint;
BEGIN
FOR i := ldigit DOWNTO 0 DO zÆiÅ := 0;
IF s > 0 THEN
BEGIN
carry := 0;
FOR i := 0 TO ldigit DO
BEGIN
carry := carry * maxdigit + xÆiÅ;
WHILE carry >= s DO
BEGIN
zÆiÅ := zÆiÅ + 1;
carry := carry - s;
END;
END;
END;
FOR i := ldigit DOWNTO 0 DO xÆiÅ := zÆiÅ;
sdv := carry;
END; (*SDV*)
FUNCTION short(VAR x:lint):boolean; (* DETERMINE IF LINT IS SHORT*)
VAR
i: integer;
BEGIN
short := false;
IF ((xÆ0Å=0) AND (xÆ1Å=0) AND (xÆ2Å<128))
OR ((xÆ0Å=255) AND (xÆ1Å=255) AND (xÆ2Å>127))
THEN short := true
END; (*SHORT*)
PROCEDURE clr(VAR x: lint); (* CLEAR LONG VALUE *)
(* X := 0 *)
VAR
i: integer;
BEGIN
FOR i := ldigit DOWNTO 0 DO xÆiÅ := 0;
END; (*CLR*)
PROCEDURE lsb(VAR x: lint; y: lint); (* SUBTRACT LONG FROM LONG *)
VAR
i, b: integer;
BEGIN
b := 0; (* SET BORROW TO 0 *)
FOR i := ldigit DOWNTO 0 DO
BEGIN
xÆiÅ := xÆiÅ - yÆiÅ - b;
b := 0; (* RESET CARRY *)
IF xÆiÅ < 0
THEN
BEGIN
xÆiÅ := xÆiÅ + 256;
b := 1
END (*THEN*)
END (*FOR*)
END; (*LSB*)
PROCEDURE ssb(VAR x: lint; s: integer); FORWARD;
PROCEDURE sad(VAR x: lint; s: integer); (* ADD INTEGER TO LONG *)
(* X := X + S *)
VAR
i,carry: integer;
z: lint;
BEGIN
IF s < 0
THEN ssb(x, -s)
ELSE
BEGIN
carry := s;
FOR i := ldigit DOWNTO 0 DO
BEGIN
zÆiÅ := xÆiÅ + carry;
IF zÆiÅ > topdigit
THEN
BEGIN
carry := zÆiÅ DIV maxdigit;
zÆiÅ := zÆiÅ MOD maxdigit;
END
ELSE carry := 0;
END;
FOR i := ldigit DOWNTO 0 DO xÆiÅ := zÆiÅ;
END
END; (*SAD*)
PROCEDURE ssb(* (VAR X: LINT; S: INTEGER) *); (* SUBTRACT INTEGER FROM LONG *)
(* X := X - S *)
VAR
i,borrow: integer;
z: lint;
BEGIN
(*0321D*) IF (s<0) AND (-s > 0) (* CHECKS FOR -32768 *)
THEN sad(x, -s)
ELSE
BEGIN
borrow := s;
FOR i := ldigit DOWNTO 0 DO
BEGIN
zÆiÅ := xÆiÅ - borrow;
IF zÆiÅ < 0
THEN
BEGIN
borrow := - (zÆiÅ DIV maxdigit);
zÆiÅ := zÆiÅ MOD maxdigit;
IF zÆiÅ < 0
THEN
BEGIN
borrow := borrow + 1;
zÆiÅ := zÆiÅ + maxdigit;
END; (*BEGIN*)
END (*THEN*)
ELSE borrow := 0;
END; (*FOR*)
FOR i := ldigit DOWNTO 0 DO xÆiÅ := zÆiÅ;
END (*ELSE*)
END; (*SSB*)
PROCEDURE lasgn(VAR x: integer; y: lint); (* MOVE LONG TO SHORT*)
VAR
i, j: integer;
BEGIN
j := yÆldigit -1Å;
IF j > 127 THEN j := j - 256;
x := 256 * j + yÆldigitÅ
END; (* LASGN *)
PROCEDURE asgn(VAR x: lint; y: lint); (* MOVE LONG TO LONG *)
(* X := Y *)
BEGIN
x := y;
END; (*ASGN*)
PROCEDURE sasgn(VAR x: lint; y: integer); (* MOVE INTEGER TO LONG *)
(* X := LINT Y *)
VAR
i: integer;
BEGIN
clr(x);
IF y > 0
THEN sad(x,y)
ELSE IF y < 0
THEN ssb(x,-y);
END; (*ASGN*)
PROCEDURE shl(VAR x: lint; s: integer); (* SHIFT LONG LEFT INTEGER TIMES*)
(* X := X SHIFTED LEFT BY S BITS *)
VAR
i,j,carry: integer;
z: lint;
BEGIN
FOR i := ldigit DOWNTO 0 DO zÆiÅ := xÆiÅ;
FOR j := 1 TO s DIV bitsperdigit DO
BEGIN
FOR i := 0 TO ldigit - 1 DO zÆiÅ := zÆi + 1Å;
zÆldigitÅ := 0;
END;
FOR j := 1 TO s MOD bitsperdigit DO
BEGIN
carry := 0;
FOR i := ldigit DOWNTO 0 DO
BEGIN
zÆiÅ := 2 * zÆiÅ + carry;
IF zÆiÅ > topdigit
THEN
BEGIN
zÆiÅ := zÆiÅ - maxdigit;
carry := 1;
END (*THEN*)
ELSE carry := 0;
END (*FOR*)
END; (*FOR*)
FOR i := ldigit DOWNTO 0 DO xÆiÅ := zÆiÅ;
END; (*SHL*)
(*-------------------------------------------------------------------------
CODE GENERATION SECTION
-------------------------------------------------------------------------*)
(*604*) PROCEDURE pcprint;
(*604*) BEGIN
(*604*) IF odd(debug)
(*604*) THEN
(*604*) BEGIN
(*604*) plint(listing,pc);
(*604*) write(listing,' ':21)
(*604*) END
(*604*) END; (* PCPRINT*)
PROCEDURE emitcode;
VAR
ii, i, j, hi, md, lo, chksum: integer;
save: lint;
PROCEDURE emitbyte(data: integer); (*EXPAND BYTE INTO TWO HEX DIGITS*)
VAR
hi, lo: integer;
ch: char;
BEGIN (*EMITBYTE*)
chksum := chksum + data;
hi := data DIV 16;
lo := data MOD 16;
IF hi < 10
THEN ch := chr(ord('0') + hi)
ELSE ch := chr(ord('A') + hi - 10);
write(object,ch);
IF lo < 10
THEN ch := chr(ord('0') + lo)
ELSE ch := chr(ord('A') + lo - 10);
write(object,ch);
END; (*EMITBYTE*)
BEGIN (*EMITCODE*)
IF (corecount>0)
THEN
BEGIN
i := locount;
WHILE i <= corecount DO
BEGIN
chksum := 0;
IF corecount - i >= 31
THEN j := i + 31
ELSE j := corecount;
asgn(save,genloc);
(* LO := GENLOCÆLDIGITÅ; *)
(* MD := GENLOCÆLDIGIT-1Å; *)
(* HI := GENLOCÆLDIGIT-2Å; *)
lo := sdv(genloc,256);
md := sdv(genloc,256);
hi := sdv(genloc,256);
asgn(genloc,save);
IF hi = 0
THEN BEGIN
write(object,'S1');
emitbyte(j-i+4)
END
ELSE BEGIN
write(object,'S2');
emitbyte(j-i+5)
END;
IF hi <> 0
THEN emitbyte(hi);
emitbyte(md);
emitbyte(lo); (* EMIT ADDRESS FIELD *)
FOR ii := i TO j DO
BEGIN
IF (coreÆiiÅ < 0) OR (coreÆiiÅ > 256)
THEN
BEGIN
error('BAD EMIT DATA ');
writeln(listing,'VALUE ',coreÆiiÅ,' AT ',ii,
' PC=') ;
plint(listing,pc)
END; (*THEN*)
emitbyte(coreÆiiÅ);
END; (*FOR*)
emitbyte(255-(chksum MOD 256));
writeln(object,' ');
sad(genloc,j-i+1);
i := j + 1;
END; (*WHILE*)
corecount := 0;
IF locount = 1 THEN corebase := pc;
END; (*THEN*)
END; (*EMITCODE*)
PROCEDURE emitend;
BEGIN
writeln(object,'S9030000FC');
END; (*EMITEND*)
PROCEDURE flush; (*CURRENTLY CALLED AT END OF EACH BASIC BLOCK*)
(*I.E. ONLY LOCAL OPTIMIZATION IS BEING DONE*)
PROCEDURE generate(instr: iptr);
VAR source, dest: effaddr;
tempesd: ^esd;
k: integer;
opcde: targetop;
PROCEDURE resetlabel;
VAR i: integer;
BEGIN
FOR i:= 0 TO highlabel DO
BEGIN labeltableÆiÅ.defined :=false;
labeltableÆiÅ.refchain := NIL;
labeltableÆiÅ.refed :=false
END;
IF toplabel < highlabel THEN toplabel := highlabel;
(*#*) labeloffset := labeloffset + highlabel; highlabel := 0;
END;
PROCEDURE genx(op: targetop; size: integer; ea1,ea2: effaddr); FORWARD;
(*RM*) PROCEDURE vstringimmed(startch,count: integer);
(*RM*) VAR k: integer;
(*RM*) BEGIN
WITH instr^ DO BEGIN
write(listing,'''':1);
k := startch;
(*RM*) WHILE k < startch + count DO BEGIN
eaimmed.displ := asciiÆopstring^.vstringaÆkÅÅ;
genx(tdc,1,eaimmed,eanone);
(*RM*) IF opstring^.vstringaÆkÅ = '''' THEN write(listing,'''''':2)
(*RM*) ELSE write(listing,opstring^.vstringaÆkÅ:1);
(*RM*) k := k + 1
(*RM*) END;
(*RM*) write(listing,'''':1)
(*RM*) END (* WITH *)
(*RM*) END; (* VSTRINGIMMED *)
(*RM*) PROCEDURE hexvstring(k:integer);
(*RM*) VAR i:integer;
ch:char;
(*RM*) BEGIN
(*RM*) WITH instr^ DO BEGIN
(*RM*) FOR i := 1 TO 8 DO
BEGIN
ch:=opset^.setvÆ k + 1 Å;
(*RM*) write(listing, ch :1) ;
IF NOT odd(i)
THEN BEGIN
eaimmed.displ := 16 *
hexbin(asciiÆopset^.setvÆk + i - 1ÅÅ) +
hexbin(asciiÆopset^.setvÆk + iÅÅ);
genx(tdc,1,eaimmed,eanone);
END; (*IF*)
(*RM*) END (*FOR*)
END; (*WITH*)
(*RM*) END; (* HEXVSTRING *)
PROCEDURE genx (* (OP:TARGETOP; SIZE: INTEGER; EA1,EA2: EFFADDR) *) ;
VAR i, subop, opc, opi: integer;
PROCEDURE printinstruction;
VAR bytes: integer;
PROCEDURE printea(ea: effaddr);
VAR ar: integer;
BEGIN WITH ea DO
BEGIN
ar := ord(reg)-ord(a0);
CASE mode OF
none: ;
ddirect: write(listing, 'D',ord(reg)-ord(d0):1);
adirect: write(listing, 'A', ar:1);
defer: write(listing, '(A', ar:1, ')');
incr: write(listing, '(A', ar:1,')+');
decr: write(listing, '-(A', ar:1,')');
based: write(listing, displ:1, '(A', ar:1,
')');
index: write(listing, displ:1,
'(A', ar:1, ',', 'D', ord(xreg)-ord(d0):1,')');
absolute: write(listing,displ:1);
immed: write(listing,'#',displ:1);
relative: BEGIN
write(listing,'*');
IF displ> 0 THEN
write(listing,'+',displ:1)
ELSE IF displ< 0 THEN write(listing,displ:1)
END;
labelled: IF curropcode = xcup
THEN write(listing,'USER':4,displ:1)
ELSE write(listing,
'L',displ + labeloffset:1);
labimmed: BEGIN
IF displ <0 THEN write(listing,'#-L',-displ:1)
ELSE write(listing,'#L',displ + labeloffset:1)
END;
(*RM*) pimmed: BEGIN
(*RM*) write(listing,'#$':2);
(*RM*) hexvstring(displ)
(*RM*) END;
(*RM*) stshort: BEGIN
(*RM*) write(listing,'#':1);
(*RM*) vstringimmed(displ,2)
(*RM*) END;
(*RM*) stlong : BEGIN
(*RM*) write(listing,'#':1);
(*RM*) vstringimmed(displ,4)
(*RM*) END;
limmed: BEGIN
WITH instr^ DO BEGIN
write(listing,'#$');
write(listing,hexdataÆopand1 DIV 16 + 1Å);
write(listing,hexdataÆopand1 MOD 16 + 1Å);
write(listing,hexdataÆopand2 DIV 16 + 1Å);
write(listing,hexdataÆopand2 MOD 16 + 1Å);
write(listing,hexdataÆopand3 DIV 16 + 1Å);
write(listing,hexdataÆopand3 MOD 16 + 1Å);
write(listing,hexdataÆopand4 DIV 16 + 1Å);
write(listing,hexdataÆopand4 MOD 16 + 1Å);
END
END;
(*RM*) xexternal: BEGIN write(listing,'X',mnÆinstr^.opcodeÅ:3);
IF instr^.d1type <> notatyp THEN
write(listing,dnameÆinstr^.d1typeÅ:1);
IF instr^.dtype <> notatyp THEN
write(listing,dnameÆinstr^.dtypeÅ:1);
END; (* XEXTERNAL *)
pcindex: BEGIN write(listing,'***PCINDEX***') END;
END END;
END; (*PRINTEA*)
BEGIN (*PRINTINSTRUCTION*)
write(listing, ' ':10);
FOR bytes:=1 TO 5 DO IF tmnÆop,bytesÅ<>' ' THEN write
(listing, tmnÆop,bytesÅ);
IF size = 1 THEN write(listing,'.B ')
ELSE IF size >= 4 THEN write(listing,'.L ')
ELSE write(listing,' ');
printea(ea1);
IF ea2.mode <> none THEN BEGIN
write(listing,',');
printea(ea2);
END;
IF flpc THEN
BEGIN
write(listing,' ':2,'***** FLUSH ',
mnÆinstr^.opcodeÅ);
flpc := false
END;
IF ea1.reg = a3
THEN write(listing,' ',mnÆinstr^.opcodeÅ:3,
dnameÆinstr^.d1typeÅ:1,
dnameÆinstr^.dtypeÅ:1);
writeln(listing,' ');
END; (*PRINTINSTRUCTION*)
PROCEDURE buffer(valu: lint; size: integer); (* PUT LONG VALUE IN CORE*)
VAR
i,b: integer;
v: lint;
PROCEDURE hexwrite(data: integer); (*WRITE CONTENTS OF CORE CELL*)
VAR hi, lo: integer;
ch: char;
BEGIN
IF (data < 0) OR (data > 256)
THEN error('BAD DATA IN HEXWRITE');
hi := data DIV 16;
lo := data MOD 16;
IF hi < 10
THEN ch := chr(ord('0') + hi)
ELSE ch := chr(ord('A') + hi - 10);
IF odd(debug) AND (op <> tdc) THEN
BEGIN
machcodeÆmachindexÅ := ch;
machindex := machindex + 1
END;
IF lo < 10
THEN ch := chr(ord('0') + lo)
ELSE ch := chr(ord('A') + lo - 10);
IF odd(debug) AND (op <> tdc) THEN
BEGIN
machcodeÆmachindexÅ := ch;
machindex := machindex + 1
END;
END; (*HEXWRITE*)
BEGIN (* BUFFER *)
IF size + corecount > maxcore - 22
THEN emitcode;
FOR i := 1 TO size DO
coreÆcorecount + iÅ := valuÆldigit - size + iÅ;
FOR i := 1 TO size DO hexwrite(coreÆcorecount + iÅ );
corecount := corecount + size;
sad(pc, size);
IF odd(debug) AND (op <> tdc) THEN machindex := machindex + 1;
END; (*BUFFER *)
PROCEDURE gen8(a: integer);
VAR
l: lint;
BEGIN
sasgn(l, a);
buffer(l, 1);
END; (* GEN8*)
PROCEDURE gen16(a: integer);
VAR
l: lint;
BEGIN
sasgn(l, a);
buffer(l, 2);
END; (*GEN16*)
PROCEDURE gen448(a,b,c: integer);
VAR
l: lint;
BEGIN
IF c < 0 THEN c := c + 256; (* ADJUST TO ONE BYTE *)
sasgn(l, a);
shl(l, 4); sad(l, b);
shl(l, 8); sad(l, c);
buffer(l, 2)
END; (*GEN448*)
PROCEDURE gen43333(a,b,c,d,e: integer);
VAR
l: lint;
BEGIN
sasgn(l, a);
shl(l, 3); sad(l, b);
shl(l, 3); sad(l, c);
shl(l, 3); sad(l, d);
shl(l, 3); sad(l, e);
buffer(l, 2);
END; (*GEN43333*)
PROCEDURE gen4318(a,b,c,d: integer);
VAR
l: lint;
BEGIN
IF d < 0 THEN d := d + 256; (* ADJUST LENGTH OF OPERAND *)
sasgn(l, a);
shl(l, 3); sad(l, b);
shl(l, 1); sad(l, c);
shl(l, 8); sad(l, d);
buffer(l, 2);
END; (*GEN4318*)
PROCEDURE gennull; (* WRITE SOME SPACES*)
BEGIN
END; (*GENNULL*)
PROCEDURE geneaext(e: effaddr);
VAR
r: integer;
k: lint;
BEGIN
IF e.mode >= based
THEN IF (e.mode=index) OR (e.mode=pcindex)
THEN
BEGIN
IF e.displ < 0 THEN e.displ := e.displ + 256;
IF e.xreg < anone
THEN r := ord(e.xreg) - ord(d0)
ELSE r := ord(e.xreg) - ord(a0) + 8;
sasgn(k, r);
shl(k, 1);
IF NOT(regtypeÆe.xregÅ IN Æityp,btyp,ctyp,htypÅ)
THEN sad(k, 1);
shl(k, 11); sad(k, e.displ);
buffer(k, 2);
END
ELSE
BEGIN
IF e.mode = relative THEN e.displ := e.displ - 2;
sasgn(k, e.displ);
IF (e.mode = immed) AND (size = 4) THEN buffer(k,4) ELSE
IF NOT ( e.mode IN Æpimmed, stshort, stlong,limmedÅ ) THEN
buffer(k, 2) (* 4 INSTEAD OF 2 FOR ABS/IMMED LONG*)
ELSE IF e.mode = limmed
THEN BEGIN
WITH instr^ DO BEGIN
kÆ0Å := opand1;
kÆ1Å := opand2;
kÆ2Å := opand3;
kÆ3Å := opand4;
buffer(k,4)
END
END
END
ELSE IF op <> tmove
THEN gennull
END; (*GENEAEXT*)
FUNCTION reg(ea: effaddr): integer;
(* GENERATE CODED VALUE OF REG FIELD FOR GIVEN EFFECTIVE ADDRESS *)
BEGIN
IF ea.mode < stshort
THEN IF (ea.reg = dnone) OR (ea.reg = anone)
THEN error('A/DNONE IN SUBR REG ')
ELSE IF ea.reg < anone
THEN reg := ord(ea.reg) - ord(d0)
ELSE reg := ord(ea.reg) - ord(a0)
ELSE CASE ea.mode OF
absolute: reg := 0;
relative: reg := 2;
pcindex: reg := 3;
immed: reg := 4;
limmed: reg := 4;
labelled: reg := 2; (*?*)
labimmed: reg := 4; (*?*)
pimmed: reg := 4;
stshort: reg := 4;
stlong: reg := 4;
xexternal: reg := 2;
END (*CASE*)
END; (*REG*)
FUNCTION mode(ea: effaddr): integer;
(* GENERATE CODED VALUE OF MODE FIELD FOR GIVEN EFFECTIVE ADDRESS*)
BEGIN
CASE ea.mode OF
ddirect: mode := 0;
adirect: mode := 1;
defer: mode := 2;
incr: mode := 3;
decr: mode := 4;
based: mode := 5;
index: mode := 6;
pcindex: mode := 7;
absolute:mode := 7;
immed: mode := 7;
limmed: mode := 7;
relative:mode := 7;
labelled:mode := 7; (*?*)
labimmed:mode := 7; (*?*)
none: mode := 7;
pimmed: mode := 7;
stshort: mode := 7;
stlong: mode := 7;
xexternal:mode := 7;
END (* CASE*)
END; (*MODE*)
BEGIN (*GENX*)
IF ea1.mode = limmed
THEN WITH instr^ DO
IF opand1 + opand2 + opand3 + opand4 = 0
THEN BEGIN
IF (op=tmove) OR (op=tcmp)
THEN BEGIN
ea1.mode := immed;
ea1.displ := 0
END
END
ELSE IF opand1 + opand2 + opand3 = 0
THEN BEGIN
IF (op=tadd) OR (op=tsub)
AND (opand4 > 0) AND (opand4 <= 8)
THEN BEGIN
ea1.mode := immed;
ea1.displ := opand4
END
ELSE
IF (op=tmove)
AND (opand4 > 0) AND (opand4 < 128)
THEN BEGIN
ea1.mode := immed;
ea1.displ := opand4
END
END
ELSE
IF (opand1 + opand2 + opand3 = 765)
AND (op=tmove)
AND (opand4 > 127) AND (opand4 < 256)
THEN BEGIN
ea1.mode := immed;
ea1.displ := opand4 -256
END;
(* CHECK FOR MOVEQ, ADDQ, SUBQ *)
IF op = tmove
THEN
BEGIN
IF ((ea1.mode=immed) AND (ea1.displ=0) AND (ea2.mode<>adirect))
THEN
BEGIN
ea1 := ea2;
ea2 := eanone;
op := tclr;
END
ELSE
(*0423A*) IF (ea2.mode = ddirect) AND (ea1.displ > -128)
AND (ea1.displ < 128)
AND (ea1.mode = immed)
THEN
BEGIN
op := tmoveq;
size := 4
END; (*THEN*)
END; (* THEN*)
IF (op = tadd) OR (op = tsub)
THEN
BEGIN
IF (ea1.mode=immed) AND (ea1.displ > 0) AND (ea1.displ<=8)
THEN
BEGIN
IF op = tadd
THEN op := taddq
ELSE op := tsubq
END (*THEN*)
END; (*THEN*)
(* CHECK FOR CMP THAT CAN BE TST *)
IF op = tcmp
THEN
BEGIN
IF ((ea1.mode=immed) AND (ea1.displ = 0) AND (ea2.mode<>adirect))
THEN
BEGIN
ea1 := ea2;
ea2 := eanone;
op := ttst
END
END;
IF odd(debug) AND (op <> tdc) AND (op<>tequ) THEN BEGIN plint(listing,pc);
write(listing,' ')
END ;
CASE op OF
tmove: BEGIN
CASE size OF 1: i:=1;
2: i:=3;
(*RM*) 4: i:=2
END; (*CASE*)
gen43333(i, reg(ea2), mode(ea2), mode(ea1), reg(ea1));
geneaext(ea1); geneaext(ea2);
IF (ea1.mode < based) AND (ea2.mode < based)
THEN gennull
END; (*TMOVE*)
tlink: BEGIN
gen43333(4,7,1,2,ord(ea1.reg)-ord(a0));
geneaext(ea2)
END; (*TLINK*)
tunlk: BEGIN
gen43333(4,7,1,3,ord(ea1.reg)-ord(a0));
gennull
END;
trts : BEGIN
gen43333(4,7,1,6,5);
gennull
END;
ttst, tclr, tneg, tcomp:
BEGIN
IF size = 1
THEN i := 0
ELSE IF size = 4
THEN i := 2
ELSE i := 1;
CASE op OF ttst: subop := 5;
tclr: subop := 1;
tneg: subop := 2;
tcomp: subop := 3
END (*CASE*);
gen43333(4,subop,i,mode(ea1),reg(ea1));
geneaext(ea1);
END; (*TTST*)
tbtst, tbset:
BEGIN
IF op = tbtst
THEN subop := 0 (*BTST*)
ELSE subop := 3; (*BSET*)
IF ea1.mode = immed
THEN
BEGIN
gen43333(0,4,subop,mode(ea2),reg(ea2));
geneaext(ea2);
geneaext(ea1) (* BIT NUMBER *)
END
ELSE
BEGIN
gen43333(0,reg(ea1),4+subop,mode(ea2),reg(ea2));
geneaext(ea2);
END
END; (*TBTST*)
tor, teor, tsub, tand, tadd, tcmp:
BEGIN
IF size = 1
THEN i := 0
ELSE IF size = 4
THEN i := 2
ELSE i := 1;
CASE op OF
tor: BEGIN opc := 8; opi := 0 END;
teor:BEGIN opc := 11; opi := 5 END;
tsub: BEGIN opc := 9; opi := 2 END;
tcmp: BEGIN opc := 11; opi := 6 END;
tand: BEGIN opc := 12; opi := 1 END;
tadd: BEGIN opc := 13; opi := 3 END
END; (*CASE*)
IF (ea1.mode IN Æimmed,labelled,labimmed,limmed,
pimmed,stshort,stlongÅ) AND (ea2.mode <> adirect)
THEN
BEGIN
gen43333(0,opi,i,mode(ea2),reg(ea2));
geneaext(ea1);
IF ea2.mode >= based
THEN geneaext(ea2);
END (*THEN*)
ELSE
IF ea2.mode = adirect
THEN
BEGIN
IF i = 2
THEN subop := 7
ELSE subop := 3;
gen43333(opc,reg(ea2),subop,mode(ea1),reg(ea1));
geneaext(ea1)
END (*THEN*)
ELSE
IF (ea2.mode=ddirect) AND (op<>teor)
THEN
BEGIN
gen43333(opc,reg(ea2),i,
mode(ea1),reg(ea1));
geneaext(ea1)
END (*THEN*)
ELSE
IF ea1.mode = ddirect
THEN
BEGIN
IF op = tcmp
THEN
error('TO MEMORY COMPARE ');
gen43333(opc,reg(ea1),4+i,
mode(ea2),reg(ea2));
geneaext(ea2)
END (*THEN*)
ELSE error('MEMORY/MEMORY +-ETC ')
END; (*TOR*)
tmuls, tdivs:
BEGIN
CASE op OF
tmuls: opc := 12;
tdivs: opc := 8
END; (*CASE*)
gen43333(opc,reg(ea2),7,mode(ea1),reg(ea1));
geneaext(ea1)
END; (*TMULS*)
ttrap: BEGIN
gen448(4,14,64 + ea1.displ);
gennull
END; (*TTRAP*)
tseq, tsne, tslt, tsnz, tsle, tsgt, tsge:
BEGIN
CASE op OF
tseq: subop := 7;
tsne: subop := 6;
tsnz: subop := 6;
tslt: subop := 13;
tsle: subop := 15;
tsgt: subop := 14;
tsge: subop := 12;
END; (*CASE*)
gen43333(5,subop DIV 2,4*(subop MOD 2) + 3,mode(ea1),reg(ea1));
geneaext(ea1)
END; (*TSEQ*)
tjmp, tjsr: BEGIN
CASE op OF
tjmp: subop := 3;
tjsr: subop := 2
END; (*CASE*)
gen43333(4,7,subop,mode(ea1),reg(ea1));
geneaext(ea1)
END; (*TJMP*)
tbra, tbne, tbnz, tbgt, tbge, tbsr, tbeq, tbz, tblt, tble:
BEGIN
CASE op OF
tbra: subop := 0;
tbsr: subop := 1;
tbne: subop := 6;
tbnz: subop := 6;
tbeq: subop := 7;
tbz: subop := 7;
tbge: subop := 12;
tblt: subop := 13;
tbgt: subop := 14;
tble: subop := 15
END; (*CASE*)
i := ea1.displ;
IF ea1.mode = relative
THEN i := i -2
ELSE IF ea1.mode = labelled
THEN IF ((labeltableÆiÅ.defined)
AND (curropcode <> xcup))
OR ((proctableÆiÅ.defined)
AND (curropcode = xcup))
THEN
BEGIN
IF curropcode = xcup
THEN ltemp := proctableÆiÅ.location
ELSE ltemp := labeltableÆiÅ.location;
lsb(ltemp, pc);
ssb(ltemp, 2);
lasgn(i, ltemp)
END
ELSE i := 0; (* FORWARD REFERENCE*)
gen448(6,subop,i);
gennull
END; (*TBRA*)
tmoveq, tldq: BEGIN
gen4318(7,reg(ea2),0,ea1.displ);
gennull
END; (*TMOVEQ*)
taddq, tsubq:
BEGIN
IF size = 1
THEN i := 0
ELSE IF size = 4
THEN i := 2
ELSE i := 1;
IF op = taddq
THEN subop := 0
ELSE subop := 4; (* SUBQ*)
IF ea1.displ = 8 THEN ea1.displ := 0; (* ADJUST FOR IMMED 8 *)
gen43333(5,ea1.displ,subop+i,mode(ea2),reg(ea2));
IF ea1.displ = 0 THEN ea1.displ := 8; (*REPAIR IMMED 8*)
geneaext(ea2)
END; (*TADDQ*)
tlea, tchk:
BEGIN
IF op = tlea
THEN subop := 7
ELSE subop := 6; (*CHK*)
gen43333(4,reg(ea2),subop,mode(ea1),reg(ea1));
geneaext(ea1)
END; (*TLEA*)
tpea: BEGIN
gen43333(4,4,1,mode(ea1),reg(ea1));
geneaext(ea1)
END; (*TPEA*)
tdc: BEGIN
IF size = 1
THEN gen8(ea1.displ);
IF size = 2
THEN gen16(ea1.displ);
END; (*TDC*)
tlbsr, tlblt, tlbeq, tlbra, tlbgt, tlbne, tlble, tlbge:
BEGIN
CASE op OF
tlbra: subop := 0;
tlbsr: subop := 1;
tlbne: subop := 6;
tlbeq: subop := 7;
tlbge: subop := 12;
tlblt: subop := 13;
tlbgt: subop := 14;
tlble: subop := 15;
END; (*CASE*)
i := ea1.displ;
IF ea1.mode = relative
THEN i := i
ELSE IF ea1.mode = labelled
THEN IF (labeltableÆiÅ.defined
AND (curropcode <> xcup))
OR (proctableÆiÅ.defined
AND (curropcode = xcup))
THEN
BEGIN
IF curropcode = xcup
THEN ltemp := proctableÆiÅ.location
ELSE ltemp := labeltableÆiÅ.location;
lsb(ltemp, pc);
ssb(ltemp, 2);
lasgn(i, ltemp)
END
ELSE i := 0 (*FORWARD REF*)
ELSE IF ea1.mode = xexternal
THEN i := -(i );
gen448(6,subop,0);
subop := ea1.displ;
ea1.displ := i;
geneaext(ea1);
ea1.displ := subop;
END; (*TLBSR*)
tswap: BEGIN
gen43333(4,4,1,0,reg(ea1));
gennull
END; (*TSWAP*)
texte: BEGIN
IF size = 4
THEN i := 3
ELSE i := 2;
gen43333(4,4,i,0,reg(ea1));
gennull
END; (*TEXTE*)
tcmpm: BEGIN
CASE size OF
1: i := 4;
2: i := 5;
4: i := 6
END; (*CASE*)
gen43333(11,reg(ea2),i,1,reg(ea1));
gennull
END; (*TCMPM*)
tdcnt: BEGIN (* WARNING: THIS IS OLD DCNT *)
gen4318(7,reg(ea1),1,256 - ea2.displ);
gennull
END (*TDCNT*) ;
tasl: writeln(listing,'****ASL NOT SUPPORTED YET***');
tequ: ;
END; (*CASE*)
IF op <> tdc THEN
BEGIN
IF (op <> tequ) AND odd(debug) THEN write(listing,machcode);
machcode := ' ';
machindex := 1;
printinstruction
END;
END; (*GENX*)
PROCEDURE pushdreg;
VAR k: integer;
BEGIN IF dalloc <= 0 THEN error('NO D REG TO PUSH ')
ELSE BEGIN k := sizeÆregtypeÆdbotÅÅ;
(*1204B*) IF k = 8 THEN k := 4; (* POWERSETS*)
eaddir.reg := dbot;
genx(tmove,k,eaddir,eapush);
stkptr:=stkptr + 1;
IF stkptr > stkmax THEN error('TOO MANY REG PUSHES ');
kindstkÆstkptrÅ := dreg;
typestkÆstkptrÅ := regtypeÆdbotÅ;
dalloc := dalloc - 1;
IF dalloc = 0 THEN
BEGIN
dbot := dnone;
dtop := dnone
END
ELSE
dbot := dregsÆ(ord(dbot)-ord(d0)+1) MOD ndregsÅ;
END
END; (*PUSHDREG*)
PROCEDURE pushareg;
VAR k: integer;
BEGIN IF aalloc <= 0 THEN error('NO A REG TO PUSH ')
ELSE BEGIN k := sizeÆregtypeÆabotÅÅ;
eaadir.reg := abot;
genx(tmove,k,eaadir,eapush);
stkptr:=stkptr + 1;
IF stkptr > stkmax THEN error('TOO MANY REG PUSHES ');
kindstkÆstkptrÅ := areg;
typestkÆstkptrÅ := regtypeÆabotÅ;
aalloc := aalloc -1;
IF aalloc = 0 THEN BEGIN abot := anone; atop := anone END
ELSE
abot := aregsÆ(ord(abot)-ord(a0) + 1) MOD naregsÅ;
END
END; (*PUSHAREG*)
PROCEDURE pushalld;
BEGIN WHILE dalloc > 0 DO pushdreg END;
PROCEDURE pushall;
BEGIN WHILE aalloc > 0 DO pushareg;
WHILE dalloc > 0 DO pushdreg
END;
PROCEDURE freeall;
BEGIN
dalloc := 0; dtop := dnone; dbot := dnone;
aalloc := 0; atop := anone; abot := anone
END; (*FREEALL*)
PROCEDURE popreg(kind: regkind);
PROCEDURE popd;
VAR k: integer;
(*RM*) BEGIN
(*RM*) IF dbot = dnone THEN
(*RM*) BEGIN
(*RM*) dbot := d0;
(*RM*) dtop := d0
(*RM*) END ELSE
dbot :=
dregsÆ (ord(dbot)-ord(d0)-1+ndregs) MOD ndregsÅ;
dalloc := dalloc + 1;
IF stkptr < 0 THEN error('POPPING EMPTY STACK ')
ELSE BEGIN
k := sizeÆtypestkÆstkptrÅÅ;
(*1204B*) IF k = 8 THEN k := 4; (*POWERSETS*)
eaddir.reg := dbot;
genx(tmove,k,eapop, eaddir);
regtypeÆdbotÅ := typestkÆstkptrÅ;
IF stkptr >= 0 THEN stkptr := stkptr -1;
dpopcnt := dpopcnt + 1;
END
END; (*POPD*)
PROCEDURE popa;
VAR k: integer;
(*RM*) BEGIN IF abot = anone THEN
(*RM*) BEGIN
(*RM*) abot := a0;
(*RM*) atop := a0
(*RM*) END
ELSE abot :=
aregsÆ (ord(abot)-ord(a0)-1+naregs) MOD naregsÅ;
aalloc := aalloc + 1;
IF stkptr < 0 THEN error('POPPING EMPTY STACK ')
ELSE BEGIN
k := sizeÆtypestkÆstkptrÅÅ;
eaadir.reg := abot;
genx(tmove,k,eapop, eaadir);
regtypeÆabotÅ := typestkÆstkptrÅ;
IF stkptr >= 0 THEN stkptr := stkptr -1;
apopcnt := apopcnt + 1;
END
END; (*POPA*)
BEGIN IF kind = dreg THEN
BEGIN WHILE kindstkÆstkptrÅ <> dreg DO popa;
(*RM*) IF stkptr >= 0 THEN popd
ELSE error('NO D REG TO POP ')
END
ELSE
BEGIN WHILE kindstkÆstkptrÅ <> areg DO popd;
(*RM*) IF stkptr >= 0 THEN popa
ELSE error('NO A REG TO POP ')
END
END;
FUNCTION previous(r:register):register;
BEGIN
previous := dregsÆ(ord(r)-ord(d0)-1+ndregs) MOD ndregsÅ
END; (* PREVIOUS *)
PROCEDURE allocdreg;
BEGIN
dalloccnt := dalloccnt + 1;
IF dalloc >= ndregs THEN BEGIN pushdreg;
dpushcnt:=dpushcnt+1
END;
dalloc := dalloc + 1;
dtop := dregsÆ(ord(dtop)-ord(d0)+1) MOD ndregsÅ;
IF dbot = dnone THEN dbot := dtop;
regtypeÆdtopÅ := instr^.dtype;
END; (*ALLOCDREG*)
PROCEDURE allocareg;
BEGIN
aalloccnt := aalloccnt + 1;
IF aalloc >= naregs THEN BEGIN pushareg;
apushcnt:=apushcnt+1
END;
aalloc := aalloc + 1;
atop := aregsÆ(ord(atop)-ord(a0)+1) MOD naregsÅ;
IF abot = anone THEN abot := atop;
(*1011*) regtypeÆatopÅ := atyp;
END; (*ALLOCAREG*)
PROCEDURE freedreg;
BEGIN IF dalloc > 1 THEN BEGIN
dalloc := dalloc -1;
dtop := dregsÆ(ord(dtop)-ord(d0)+ndregs-1) MOD ndregsÅ
(*-1 AND WRAPAROUND*)
END
ELSE IF dalloc = 1 THEN BEGIN
dalloc := 0;
(*RM*) dbot := dnone;
dtop := dnone
END
ELSE error('FREE NONALLOC''D DREG')
END; (*FREEDREG*)
PROCEDURE freeareg;
BEGIN IF aalloc > 1 THEN BEGIN
aalloc := aalloc -1;
atop := aregsÆ(ord(atop)-ord(a0)+naregs-1) MOD naregsÅ
(*-1 AND WRAPAROUND*)
END
ELSE IF aalloc = 1 THEN BEGIN
aalloc := 0;
(*RM*) abot := anone;
atop := anone
END
ELSE error('FREE NONALLOC''D AREG')
END; (*FREEAREG*)
PROCEDURE effaddress(instr: iptr; VAR opaddr: effaddr);
(*USED BY LOD, LDA, STR, TAKES LEVEL, OFFSET
IN OPAND1 AND OPAND2 AND RETURNS MODE,
REGISTER, AND DISPLACEMENT OF CORRESPONDING
68000 ADDRESS*)
VAR src: effaddr;
BEGIN WITH instr^ DO
BEGIN IF opand1 (*LEVEL*) = 0 THEN (*GLOBAL ACCESS*)
opaddr.reg := a5 (*GLOBAL BASE REGISTER*)
ELSE IF opand1 = level THEN (*LOCAL ACCESS*)
opaddr.reg := a6 (*FRAME POINTER*)
ELSE BEGIN
IF templevel <> opand1 THEN
BEGIN
eaadir.reg := a4;
buildaddr(src,based,a5,anone,4*opand1 + 8);
genx(tmove,4,src,eaadir);
templevel := opand1
(*SAVE LEVEL OF DISPLAY ENTRY
CURRENTLY HELD IN A4*)
END;
opaddr.reg := a4; (*TEMPORARY INTERMEDIATE PTR*)
END;
opaddr.mode := based;
opaddr.displ := opand2; (*OFFSET*)
IF (opaddr.reg = a4) OR (opaddr.reg = a6) THEN
IF opand2 >= 0 THEN opaddr.displ := opand2 + 12;
IF opaddr.displ = 0 THEN opaddr.mode := defer
END;
END; (*EFFADDRESS*)
PROCEDURE doubleop(VAR src, dst:effaddr; commutative: boolean;
VAR switch: boolean);
(*RM*) BEGIN
(*RM*) IF instr^.dtype = atyp THEN BEGIN
(*RM*) IF NOT commutative OR (aalloc>=2) THEN
(*RM*) BEGIN
(*RM*) WHILE aalloc <= 1 DO popreg(areg);
(*RM*) buildaddr(src,adirect,atop,anone,0);
(*RM*) freeareg;
(*RM*) buildaddr(dst,adirect,atop,anone,0);
(*RM*) switch := false
(*RM*) END ELSE
(*RM*) BEGIN
(*RM*) IF aalloc < 1 THEN popreg(areg);
(*RM*) (*AALLOC = 1 AT THIS POINT *)
(*RM*) buildaddr(dst,adirect,atop,anone,0);
(*RM*) buildaddr(src,incr,sp,anone,0);
(*RM*) switch := true;
(*RM*) IF NOT (instr^.dtype IN longtypes) THEN stkptr := stkptr -1;
(*RM*) END
(*RM*) END ELSE
BEGIN IF NOT commutative OR (dalloc >= 2) THEN
BEGIN
WHILE dalloc <= 1 DO popreg(dreg);
buildaddr(src,ddirect,dtop,anone,0);
freedreg;
buildaddr(dst,ddirect,dtop,anone,0);
switch := false
END
ELSE BEGIN
IF dalloc < 1 THEN popreg(dreg);
(*DALLOC = 1 AT THIS POINT*)
buildaddr(dst,ddirect,dtop,anone,0);
buildaddr(src,incr,sp,anone,0);
switch := true;
(*RM*) IF NOT (instr^.dtype IN longtypes) THEN stkptr := stkptr -1;
END
(*RM*) END
(*RM*) END;
PROCEDURE singleop(VAR src:effaddr);
(*RM*) BEGIN
(*RM*) IF instr^.dtype = atyp THEN
(*RM*) BEGIN IF aalloc = 0 THEN popreg(areg);
(*RM*) buildaddr(src,adirect,atop,anone,0)
(*RM*) END ELSE
BEGIN IF dalloc = 0 THEN popreg(dreg);
buildaddr(src,ddirect,dtop,anone,0);
(*RM*) END
END;
PROCEDURE loadbig(addr: effaddr; bytes: integer);
(* PROCEDURE TO LOAD POWERSETS ONTO STACK *)
BEGIN
allocdreg;
eaddir.reg := dtop;
genx(tmove,4,addr,eaddir);
IF addr.mode = based
THEN addr.displ := addr.displ + 4
ELSE IF addr.mode=defer
THEN BEGIN
addr.mode := based;
addr.displ := 4
END
ELSE error('LOADBIG W/BAD MODE ');
allocdreg;
eaddir.reg := dtop;
genx(tmove,4,addr,eaddir);
END; (*LOADBIG*)
PROCEDURE storebig(addr: effaddr; bytes: integer);
(* PROCEDURE TO STORE POWERSETS OFF THE STACK *)
BEGIN
eaddir.reg := previous(dtop);
genx(tmove,4,eaddir,addr);
IF addr.mode = based
THEN addr.displ := addr.displ + 4
ELSE IF addr.mode = defer
THEN BEGIN
addr.mode := based;
addr.displ := 4
END
ELSE error('STOREBIG W/BAD MODE ');
eaddir.reg := dtop;
freedreg;
genx(tmove,4,eaddir,addr);
freedreg
END; (*STOREBIG*)
PROCEDURE storelittle; (*GEN CODE TO MOVE TOP DATA ITEM TO MEMORY*)
BEGIN IF dalloc > 0 THEN
BEGIN eaddir.reg := dtop;
genx(tmove,sizeÆinstr^.dtypeÅ,eaddir,source);
freedreg;
END
ELSE BEGIN genx(tmove,sizeÆinstr^.dtypeÅ,eapop,source);
stkptr := stkptr - 1;
END
END; (*STORELITTLE*)
PROCEDURE referencelabel(labl: integer; where: address);
(* CALLED TO SAVE FORWARD REFERENCE INFO *)
BEGIN
new(templabref);
WITH templabref^ DO
BEGIN
IF instr^.opcode=xcup
THEN next := proctableÆlablÅ.refchain
ELSE next := labeltableÆlablÅ.refchain;
coreloc := where
END; (*WITH*)
IF instr^.opcode=xcup
THEN BEGIN
proctableÆlablÅ.refchain := templabref;
proctableÆlablÅ.refed := true;
clr (proctableÆlablÅ.location);
proctableÆlablÅ.locationÆ0Å := 1
END (*ELSE*)
ELSE BEGIN
labeltableÆlablÅ.refchain := templabref ;
labeltableÆlablÅ.refed := true;
IF instr^.opcode = xent
THEN sasgn(labeltableÆlablÅ.location, -1)
ELSE clr(labeltableÆlablÅ.location);
END; (*ELSE*)
END; (*REFERENCELABEL*)
PROCEDURE longbsr; (* RUNTIME ROUTINE BRANCH CALCULATION *)
VAR
i: integer;
rtname: pcodes;
BEGIN
WITH instr^ DO
BEGIN
rtname := opcode;
IF dtype = vtyp
THEN BEGIN
IF rtname = xind THEN rtname := xindv
ELSE IF rtname = xlod THEN rtname := xlodv
ELSE IF rtname = xstr THEN rtname := xstrv
ELSE IF rtname = xsto THEN rtname := xstov
ELSE IF rtname = xequ THEN rtname := xequv
ELSE IF rtname = xneq THEN rtname := xneqv
ELSE IF rtname = xles THEN rtname := xlesv
ELSE IF rtname = xleq THEN rtname := xleqv
ELSE IF rtname = xgrt THEN rtname := xgrtv
ELSE IF rtname = xgeq THEN rtname := xgeqv
ELSE IF rtname = xldc THEN rtname := xldcv
END
ELSE IF rtname = xcvt
THEN IF (d1type=styp) AND (dtype=utyp)
THEN rtname := xcvtsu
ELSE IF (d1type=utyp) AND (dtype=styp)
THEN rtname := xcvtus;
clr(ltemp);
lsb(ltemp,rtjump);
sad(ltemp,rtÆrtnameÅ);
ssb(ltemp,4096);
lasgn(source.displ,ltemp);
buildaddr(source,based,a3,anone,source.displ);
genx(tjsr,2,source,eanone)
END (*WITH*)
END; (*LONGBSR*)
PROCEDURE main;
BEGIN
IF instr^.opand1 = 0 THEN
BEGIN
progstart := pc;
mainflg := true;
writeln(listing,'MAIN',' ':6,'EQU *');
END
ELSE writeln(listing,'USER':4,currlabel:1,' EQU *')
END ; (* MAIN *)
PROCEDURE genxxjp;
BEGIN
(*0421B*) IF dalloc = 0 THEN popreg(dreg);
eaddir.reg := dtop;
ealimm.displ := instr^.opand1 + 1;
genx(tcmp,2,ealimm,eaddir);
ltemp := pc;
ssb(ltemp, 2);
referencelabel(ealimm.displ,ltemp);
(*RM*) earel.displ := 20;
genx(tbgt,2,earel,eanone);
ealimm.displ := instr^.opand1;
genx(tsub,2,ealimm,eaddir);
ltemp := pc;
ssb(ltemp, 2);
referencelabel(ealimm.displ,ltemp);
(*RM*) earel.displ := 14;
genx(tblt,2,earel,eanone);
ealab.displ := instr^.opand1 + 2;
allocareg;
eaadir.reg := atop;
genx(tlea,2,ealab,eaadir);
ltemp := pc;
ssb(ltemp, 2);
referencelabel(ealab.displ,ltemp);
genx(tadd,2,eaddir,eaddir);
buildaddr(source,index,atop,dtop,0);
genx(tadd,2,source,eaadir);
eadefer.reg := atop;
genx(tjmp,2,eadefer,eanone);
freedreg; freeareg
END (* GENXXJP *) ;
(*RM*) PROCEDURE loadpset;
(*RM*) BEGIN
(*RM*) WITH instr^ DO BEGIN
(*RM*) allocdreg;
(*RM*) eaddir.reg := dtop;
(*RM*) eapset.displ := 0;
(*RM*) genx(tmove,4,eapset,eaddir);
(*RM*) allocdreg;
(*RM*) eaddir.reg := dtop;
(*RM*) eapset.displ := 8;
(*RM*) genx(tmove,4,eapset,eaddir)
(*RM*) END
(*RM*) END; (* LOADPSET *)
PROCEDURE setops;
BEGIN
WITH instr^ DO BEGIN
WHILE dalloc < 4 DO popreg(dreg);
IF opcode = xdif THEN BEGIN
eaddir.reg := dtop;
(*1324A*) genx(tcomp,4,eaddir,eanone);
eaddir.reg := previous(dtop);
(*1324A*) genx(tcomp,4,eaddir,eanone);
END;
IF opcode = xuni THEN opcde := tor
ELSE opcde := tand;
buildaddr(source,ddirect,dtop,dnone,0);
eaddir.reg := previous(previous(dtop));
genx(opcde,4,source,eaddir);
source.reg := previous(dtop);
eaddir.reg := previous(previous(previous(dtop)));
genx(opcde,4,source,eaddir);
freedreg;freedreg;
END
END; (* SETOPS *)
PROCEDURE pxlab;
BEGIN WITH instr^ DO BEGIN
IF opand1 = 0 THEN opand1 := -1;
(*604*) pcprint;
write(listing,'L',opand1 + labeloffset:1);
buildaddr(source,relative,anone,anone,0);
genx(tequ,0,source,eanone)
END;
END; (* PXLAB *)
PROCEDURE pxend;
VAR i: integer;
BEGIN
emitcode;
IF mainflg THEN BEGIN
genloc := genstart;
write(listing,' RORG $');
plint(listing,genstart);
ltemp := pc;
writeln(listing,' ');
lsb(ltemp,genstart);
ssb(ltemp,20);
gensave := pc;
pc := genstart;
(* LOAD STACK *)
write(listing,' ':39,'MOVE.L $');
plint(listing,stkstart);
writeln(listing,',A7');
eaimmed.displ := 11900; (* TMOVE 2E7C *)
genx(tdc,2,eaimmed,eanone);
eaimmed.displ := stkstartÆ0Å;
genx(tdc,1,eaimmed,eanone);
eaimmed.displ := stkstartÆ1Å;
genx(tdc,1,eaimmed,eanone);
eaimmed.displ := stkstartÆ2Å;
genx(tdc,1,eaimmed,eanone);
eaimmed.displ := stkstartÆ3Å;
genx(tdc,1,eaimmed,eanone);
(* LEA 11EA,A3 *)
write(listing,' ':39,'LEA $');
ltemp := rtjump;
sad(ltemp,4096);
plint(listing,ltemp);
writeln(listing,',A3');
eaimmed.displ := 18425; (* LEA 47F9 *)
genx(tdc,2,eaimmed,eanone);
eaimmed.displ := ltempÆ0Å;
genx(tdc,1,eaimmed,eanone);
eaimmed.displ := ltempÆ1Å;
genx(tdc,1,eaimmed,eanone);
eaimmed.displ := ltempÆ2Å;
genx(tdc,1,eaimmed,eanone);
eaimmed.displ := ltempÆ3Å;
genx(tdc,1,eaimmed,eanone);
(* JSR -490(A3) INITIALIZE ENVIRONMENT *)
longbsr;
IF (heapstartÆ0Å=255) AND (heapstartÆ1Å=255)
AND (heapstartÆ2Å=255) AND (heapstartÆ3Å=255)
THEN BEGIN
heapstart := gensave;
sad(heapstart,10)
END;
write(listing,' ':10,'DC.L ':7,'$':1);
plint(listing,heapstart);
writeln(listing,' ');
FOR i := 0 TO 3 DO
BEGIN
eaimmed.displ := heapstartÆiÅ;
genx(tdc,1,eaimmed,eanone)
END;
(* BRA OR JSR TO MAIN *)
ltemp := progstart;
lsb(ltemp,pc);
IF short(ltemp) THEN BEGIN
lasgn(earel.displ, ltemp);
genx(tlbra,2,earel,eanone);
END ELSE
BEGIN
eadefer.reg := a3;
ssb(ltemp,2);
genx(tjsr,2,eadefer,eanone);
write(listing,' ':10,'DC.L ':7,'$':1);
plint(listing,ltemp);
writeln(listing,' ');
FOR i := 0 TO 3 DO
BEGIN
eaimmed.displ := ltempÆiÅ;
genx(tdc,1,eaimmed,eanone)
END
END;
pc := gensave;
emitcode;
END; (*BEGIN*)
emitend
;writeln(listing,' END');
END; (*PXEND*)
PROCEDURE pxdef;
BEGIN WITH instr^ DO BEGIN
IF labeled AND NOT dollar THEN
BEGIN
IF opand1= 0 THEN opand1 := 1-labeloffset;
(*604*) pcprint;
write(listing,'L',opand1 + labeloffset:1);
buildaddr(source,absolute,anone,anone,opand2);
genx(tequ,0,source,eanone)
END;
IF labeled AND dollar THEN
BEGIN getstring;
write(output,'***** REFERENCE TO EXTERNAL PROCEDURE ',
vstring:alength,' AT LOCATION ');
ltemp := exproc;
ssb(ltemp,10);
plint(output,ltemp);
writeln(output,' ');
END
ELSE IF NOT labeled THEN
error('DEF WITH NO LABEL ')
END;
END; (*PXDEF*)
PROCEDURE pxent; (* OPAND1 IS NEW LEVEL*)
BEGIN WITH instr^ DO BEGIN
(*OPAND2 IS LABEL WHICH GIVES LOCAL DATA SZ*)
(*VSTRING IS NEW PROC/FUNC NAME*)
emitcode;
resetlabel;
main;
level := opand1;
IF templevel = level THEN templevel := -1;
(*INVALIDATE A4 (POINTER TO INTERMEDIATE
LEXICAL LEVEL) IF DISPLAY ENTRY CHANGES*)
IF level = 1 THEN
BEGIN
write(output,'*****ENTRY TO PROCEDURE ':25,
vstring:alength,' AT LOCATION ');
plint(output,pc);
writeln(output,' ')
END;
(*1212A*) IF level = 0 THEN
(*1212A*) BEGIN
(*1212A*) eaadir.reg := a7;
(*1212A*) ealimm.displ := -opand2;
(*1212A*) genx(tadd,0,ealimm,eaadir);
ltemp := pc;
ssb(ltemp, 2);
(*1212A*) referencelabel(opand2 - labeloffset,ltemp)
(*1212A*) END
(*1212A*) ELSE BEGIN
buildaddr(source,based,a5,anone,8+4*level);
(*DISPLAY IS ^A5(6)*)
genx(tmove,4,source,eapush);
eaadir.reg := a6; (*FRAME POINTER*)
ealimm.displ := -opand2 ;
genx(tlink,0,eaadir,ealimm) ;
ltemp := pc;
ssb( ltemp, 2);
referencelabel(opand2 - labeloffset,ltemp);
genx(tmove,4,eaadir,source);
(*1212A*) END;
END;
END; (* PXENT *)
PROCEDURE pxret;
BEGIN WITH instr^ DO BEGIN
IF opand1 <> level THEN
error('ENT/RET LEVELS NOT =');
eaadir.reg := a6; (*FRAME POINTER*)
genx(tunlk,0,eaadir,eanone);
buildaddr(source,based,a5,anone,8+4*level);
genx(tmove,4,eapop,source);
(*RM*) (* CODE TO FLUSH ARGUMENTS FROM STACK *)
(*RM*) IF opand2 <> 0 THEN
(*RM*) BEGIN
(*RM*) allocareg;
(*RM*) eaadir.reg := atop;
(*RM*) genx(tmove,4,eapop,eaadir);
(*RM*) eaimmed.displ := opand2;
(*RM*) eaadir.reg := sp;
(*RM*) genx(tadd,4,eaimmed,eaadir);
(*RM*) eadefer.reg := atop;
(*RM*) genx(tjmp,0,eadefer,eanone);
(*RM*) freeareg
(*RM*) END ELSE
genx(trts,0,eanone,eanone)
END;
END; (*PXRET*)
(*604*) PROCEDURE pxad; FORWARD;
PROCEDURE pxab;
BEGIN WITH instr^ DO BEGIN
singleop(source);
(*RM*) k := sizeÆdtypeÅ;
CASE subtypeÆopcodeÅ OF
(*604*) 1 (*AB *): BEGIN genx(ttst,k,source,eanone);
(*RM*) earel.displ := 4;
genx(tbgt,0,earel,eanone);
(*604*) genx(tneg,k,source,eanone)
END;
(*604*) 2 (*NG *): genx(tneg,k,source,eanone);
(*RM*) 3 (*DEC*): BEGIN eaimmed.displ := opand1;
genx(tsub,k,eaimmed,source)
(*RM*) END;
(*RM*) 4 (*INC*): BEGIN eaimmed.displ := opand1;
(*480*) IF dtype = atyp THEN k := 2;
(*RM*) genx(tadd,k,eaimmed,source) END;
5 (*NOT*): BEGIN
optimi := nextpcod(instr);
IF optimi^.opcode=xfjp
THEN BEGIN
optimi^.opand3 := 102; (*BEQ TO FJP*)
END
ELSE BEGIN
(*RM*) eaimmed.displ := 1;
(*RM*) genx(teor,1,eaimmed,source)
END
(*RM*) END;
(*0421C*) 6 (*ODD*): BEGIN eaimmed.displ := 1;(*BIT # = 0*)
(*0421C*) genx(tand,1,eaimmed,source);
(*0421C*) regtypeÆdtopÅ := btyp;
END;
(*RM*) 7 (*SQR*): (*CHECK SIZES??*)
(*604*) IF dtype = jtyp
(*604*) THEN BEGIN
(*604*) IF dalloc < 1
(*604*) THEN popreg(dreg);
(*604*) eaddir.reg := dtop;
(*604*) allocdreg;
(*604*) buildaddr(dest,ddirect,
(*604*) dtop,anone,0);
(*604*) genx(tmove,4,eaddir,dest);
(*604*) opcode := xmp;
(*604*) pxad;
(*604*) END ELSE
(*604*) BEGIN
(*604*) IF dtype = htyp
(*604*) THEN BEGIN
(*604*) IF dalloc<1 THEN popreg(dreg);
(*604*) buildaddr(source,ddirect,dtop,
(*604*) anone,0);
(*604*) genx(texte,2,source,eanone)
(*604*) END;
(*RM*) genx(tmuls,2,source,source);
(*604*) END;
(* CHECK OVFL
MOV.W TO TEMP
EXT.L TEMP
CMP TEMP WITH SOURCE
BNE *+2
TRAP OVFL *)
END
END;
END; (*PXAB*)
PROCEDURE pxad;
BEGIN WITH instr^ DO BEGIN
CASE subtypeÆopcodeÅ OF
(*604*) 1,3,4: commutative := true;
(*604*) 5: IF dtype IN Æjtyp,htypÅ THEN commutative := false
(*604*) ELSE commutative := true;
2,6,7: commutative := false
END;
doubleop(source,dest,commutative,switch);
k := sizeÆdtypeÅ;
IF dtype = notatyp THEN k := 1; (* ASSUME BOOLEAN*)
(*604*) IF (dtype = jtyp)
(*604*) AND (subtypeÆopcodeÅ IN Æ5,6,7Å)
(*604*) THEN BEGIN
(*604*) longbsr;
(*604*) eaimmed.displ := ord(dest.reg) - ord(d0);
(*604*) pcprint;
(*604*) writeln(listing,' ':10,'DC.W ',
(*604*) eaimmed.displ:0);
(*604*) genx(tdc,2,eaimmed,eanone);
(*604*) END ELSE
CASE subtypeÆopcodeÅ OF
1 (*ADD*): genx(tadd,k,source, dest);
2 (*SB *): genx(tsub,k,source, dest);
3 (*AND*): genx(tand,k,source, dest);
4 (*IOR*): genx(tor, k,source, dest);
(*604*) 5 (*MP *): BEGIN
(***CHECK OVFL; SEE CODE FOR SQR*)
(*604*) IF dtype = htyp
(*604*) THEN genx(texte,2,source,eanone);
(*604*) IF (dtype = htyp)
(*604*) THEN genx(texte,2,dest,eanone);
(*604*) genx(tmuls,2,source,dest)
END;
(*604*) 6 (*DV *): BEGIN
(*604*) IF dtype = htyp
(*604*) THEN BEGIN
(*604*) genx(texte,2,source,eanone);
(*604*) genx(texte,2,dest,eanone)
(*604*) END;
(*604*) genx(texte,4,dest,eanone);
(*RM*) genx(tdivs,2,source,dest)
END;
(*604*) 7 (*MOD*): BEGIN
(*604*) IF dtype = htyp
(*604*) THEN BEGIN
(*604*) genx(texte,2,source,eanone);
(*604*) genx(texte,2,dest,eanone)
(*604*) END;
(*604*) genx(texte,4,dest,eanone);
(*RM*) genx(tdivs,2,source,dest);
(*RM*) genx(tswap,2,dest,eanone)
END;
END
END;
END; (*PXAD*)
PROCEDURE pxclo;
VAR i:integer;
BEGIN WITH instr^ DO BEGIN
IF short(firstesd^.reference)
AND (firstesd^.referenceÆ2Å=0)
AND (firstesd^.referenceÆ3Å=0) THEN
BEGIN tempesd:= firstesd;
new(firstesd); firstesd^.next:=tempesd;
END;
ltemp := pc;
sad(ltemp, 2);
firstesd^.reference := ltemp;
firstesd^.name := opcode;
IF (opcode=xwrb) OR (opcode=xwrc) OR (opcode=xwri)
(*604*) OR (opcode=xwrh) OR (opcode=xwrj)
THEN BEGIN
(*0610B*) IF opcode=xwrc THEN dtype := ctyp
(*0610B*) ELSE IF opcode=xwri THEN dtype := ityp
(*0610B*) ELSE IF opcode=xwrh THEN dtype := htyp
(*0610B*) ELSE IF opcode=xwrj THEN dtype := jtyp;
IF dalloc + aalloc = 0
THEN BEGIN
eaddir.reg := d1;
genx(tmove,2,eapop,eaddir);
eaddir.reg := d0;
(*0610B*) genx(tmove,sizeÆdtypeÅ,eapop,eaddir);
eaadir.reg := a0;
genx(tmove,4,eapop,eaadir);
stkptr := stkptr - 3;
dpopcnt := dpopcnt + 3;
END
ELSE IF (dalloc=1) AND (aalloc=0)
THEN BEGIN
buildaddr(source,ddirect,dtop,anone,0);
eaddir.reg := d1;
genx(tmove,2,source,eaddir);
eaddir.reg := d0;
(*0610B*) genx(tmove,sizeÆdtypeÅ,eapop,eaddir);
eaadir.reg := a0;
genx(tmove,4,eapop,eaadir);
stkptr := stkptr -2;
dpopcnt := dpopcnt +2;
(*1015E*) END
(*1015E*) ELSE IF (dalloc=2) AND (aalloc=0)
(*1015E*) THEN BEGIN
(*1015E*) eaadir.reg := a0;
(*1015E*) genx(tmove,4,eapop,eaadir);
(*1015E*) stkptr := stkptr -1;
(*1015E*) dpopcnt := dpopcnt +1;
(*1015E*) END;
END;
IF (opcode=xwrv) OR (opcode=xwrs)
(*1205B*) THEN BEGIN pushalld; stkptr := stkptr -2 END;
(*1207C*) IF opcode = xwrv THEN stkptr := stkptr - 1;
IF (opcode=xpee)
THEN
BEGIN
IF aalloc = 0 THEN popreg(areg)
END;
(*MAKE SURE PARAMETERS ARE IN RIGHT PLACE?*)
dtype := notatyp;
(*RM*) IF opcode <> xeio THEN longbsr
ELSE IF aalloc = 0 THEN BEGIN
(* REMOVE FILE POINTER FROM STACK *)
eaimmed.displ := 4;
eaadir.reg := sp;
genx(tadd,2,eaimmed,eaadir)
END;
(*RM*) freeall ;
(*1031A*) IF (opcode=xeol) OR (opcode=xeof) OR (opcode=xpos)
(*1031A*) THEN
(*1031A*) BEGIN
(*1031A*) allocdreg;
(*1031A*) IF opcode=xpos
(*1031A*) THEN regtypeÆdtopÅ := ityp
(*1031A*) ELSE regtypeÆdtopÅ := btyp;
(*1031A*) END
(*RM*) ELSE IF (opcode <> xeio) AND (opcode<>xclo) AND (opcode<>xifd)
(*RM*) AND (opcode<>xsee) AND (opcode<>xrst) AND (opcode<>xrwt)
(*RM*) AND (opcode<>xrln) AND (opcode<>xwln)
(*1023A*) AND (opcode<>xget) AND (opcode<>xput)
(*1206A*) AND (opcode<>xpag)
(*RM*) THEN allocareg;
(*1207H*) IF opcode = xafi THEN stkptr := stkptr - 1;
END;
END (*PXCLO*) ;
PROCEDURE pxlod;
BEGIN WITH instr^ DO BEGIN
effaddress(instr,source);
CASE subtypeÆopcodeÅ OF
1 (*LOD*): BEGIN IF dtype = atyp THEN
BEGIN
optimi := nextpcod(instr);
IF optimi^.opcode=xarg
THEN BEGIN genx(tmove,4,source,eapush);
optimi^.inuse := false END
ELSE IF ( optimi^.opcode=xstr)
AND ((optimi^.opand1=level)
OR (optimi^.opand1=0)
OR (optimi^.opand1=opand1))
THEN BEGIN
effaddress(optimi,dest);
optimi^.inuse := false;
genx(tmove,4,source,dest)
END
ELSE
BEGIN allocareg;
eaadir.reg := atop;
genx(tmove,4,source,eaadir);
END;
END
ELSE IF NOT (dtype IN longtypes) THEN
BEGIN
optimi := nextpcod(instr);
eaddir.reg := dtop;
optimi^.inuse := false;
optim2 := nextpcod(optimi);
IF ((optimi^.opcode=xad)
OR (optimi^.opcode=xsb)
OR (optimi^.opcode=xand)
OR (optimi^.opcode=xior))
AND (dtop<>dnone)
THEN BEGIN
CASE subtypeÆoptimi^.opcodeÅ OF
1: opcde := tadd;
2: opcde := tsub;
3: opcde := tand;
4: opcde := tor;
END; (*CASE*)
genx(opcde,sizeÆdtypeÅ,source,eaddir);
END
ELSE IF (optimi^.opcode = xldc)
AND (conditional(optim2)>0)
THEN BEGIN
eaimmed.displ := optimi^.opand1;
IF dtype = ctyp
THEN eaimmed.displ :=
asciiÆoptimi^.opstring^.vstringaÆ1ÅÅ;
IF optimi^.dtype=jtyp
THEN BEGIN
opand1 := optimi^.opand1;
opand2 := optimi^.opand2;
opand3 := optimi^.opand3;
opand4 := optimi^.opand4;
genx(tcmp,4,ealong,source);
END
ELSE
IF eaimmed.displ = 0
THEN genx(ttst,sizeÆdtypeÅ,
source,eanone)
ELSE genx(tcmp,sizeÆdtypeÅ,
eaimmed,source);
optim2^.opand3 := 200; (*FLAG SET*)
END
ELSE IF optimi^.opcode=xarg
THEN genx(tmove,sizeÆdtypeÅ,source,eapush)
ELSE IF optimi^.opcode=xsto
THEN BEGIN
eadefer.reg := atop;
genx(tmove,sizeÆdtypeÅ,source,eadefer)
;freeareg
END
ELSE IF (optimi^.opcode = xstr)
AND ((optimi^.opand1 = level)
OR (optimi^.opand1 = 0)
OR (optimi^.opand1 = opand1))
THEN BEGIN
eabased.displ :=optimi^.opand2;
IF (eabased.displ >=0) AND
(optimi^.opand1=level)
THEN eabased.displ := eabased.displ+12;
IF optimi^.opand1 = 0
THEN eabased.reg := a5
ELSE IF optimi^.opand1 = level
THEN eabased.reg := a6
ELSE eabased.reg := a4;
genx(tmove,sizeÆdtypeÅ,source,eabased)
END
ELSE IF (((optimi^.opcode=xinc)
OR (optimi^.opcode=xdec))
AND ((optim2^.opcode=xstr)
AND (optim2^.opand1=opand1)
AND (optim2^.opand2=opand2)))
THEN BEGIN
optim2^.inuse := false;
IF optimi^.opcode = xdec
THEN opcde := tsub
ELSE opcde := tadd;
eaimmed.displ := optimi^.opand1;
genx(opcde,sizeÆdtypeÅ,eaimmed,source)
END
ELSE IF ( conditional(optimi) > 0)
AND (dtop<>dnone)
THEN BEGIN
genx(tcmp,sizeÆdtypeÅ,source,eaddir);
optimi^.opand3 := 100; (*SET FLAG *)
optimi^.inuse := true
END
ELSE BEGIN
allocdreg;
eaddir.reg := dtop;
genx(tmove,sizeÆdtypeÅ,
source,eaddir) ;
optimi^.inuse:= true
END
END
ELSE (*LONG TYPE: P, S, OR V*)
(*RM*) BEGIN IF dtype = ptyp THEN opand3:=8;
IF dtype IN Æstyp,vtypÅ THEN BEGIN
(*1015D*) pushall;
eaadir.reg := a0;
genx(tlea,2,source,eaadir);
IF (aalloc<>0) OR (dalloc<>0)
THEN error
('REGISTERS NOT EMPTY ');
freeall;
longbsr;
IF dtype = vtyp THEN BEGIN
(*604*) pcprint;
writeln(listing,' ':10,
'DC.W ',opand3:0);
eaimmed.displ := opand3;
genx(tdc,2,eaimmed,eanone);
END
END ELSE
loadbig(source,opand3 (*SIZE*))
(*RM*) END
END;
2 (*LDA*): BEGIN
(*480*) optimi := nextpcod(instr);
IF (optimi^.opcode=xarg) OR (optimi^.opcode=xmst)
(*480*) OR (((optimi^.opcode=xldc) OR (optimi^.opcode=xlod)
(*480*) OR (optimi^.opcode=xind))
(*480*) AND (optimi^.dtype IN Æstyp,vtypÅ))
THEN BEGIN
optimi^.inuse := false;
(*480*) IF (optimi^.opcode<>xmst)AND(optimi^.opcode<>xarg)
(*480*) THEN optimi^.inuse := true;
(*480*) IF optimi^.opcode <> xarg
THEN BEGIN
pushall;
stkptr := stkptr + 1;
kindstkÆstkptrÅ := areg;
typestkÆstkptrÅ := atyp;
END;
genx(tpea,2,source,eanone)
END ELSE BEGIN
allocareg;
eaadir.reg := atop;
genx(tlea,2,source,eaadir)
END
END;
3 (*STR*): BEGIN IF dtype = atyp THEN
BEGIN IF aalloc > 0 THEN
BEGIN eaadir.reg := atop;
genx(tmove,4,eaadir,source);
freeareg
END
ELSE BEGIN
genx(tmove,4,eapop,source);
stkptr := stkptr - 1;
END
END ELSE (*DTYPE <> ATYP*)
IF NOT (dtype IN longtypes) THEN
storelittle
(*RM*) ELSE BEGIN
(*RM*) IF dtype = ptyp THEN opand3:=8;
IF dtype IN Æstyp,vtypÅ THEN BEGIN
eaddir.reg := d0;
eaimmed.displ := opand3;
IF dtype = styp THEN
genx(tmove,4,eaimmed,eaddir);
eaadir.reg := a0;
genx(tlea,2,source,eaadir);
IF (aalloc<>0) OR (dalloc<>0)
THEN error
('REGISTERS NOT EMPTY ');
freeall;
longbsr;
IF dtype = vtyp THEN BEGIN
pcprint;
writeln(listing,' ':10,'DC.W ',
opand3:0);
genx(tdc,2,eaimmed,eanone)
END
END ELSE
(*RM*) storebig(source,opand3)
(*RM*) END
END
END
END;
END; (*PXLOD*)
PROCEDURE pxixa;
BEGIN WITH instr^ DO BEGIN
(*T <- T' + T * OPAND1; WHERE T' IS ADDR AND T IS DATA*)
IF dalloc <= 0 THEN popreg(dreg);
eaddir.reg := dtop;
IF opand1 = 2 THEN
genx(tadd,2,eaddir,eaddir)
(***MORE OPTIMIZATION POSSIBLE FOR SMALL OPAND1'S*)
ELSE BEGIN eaimmed.displ := opand1;
(*OP*) IF opand1 <> 1 THEN
genx(tmuls,2,eaimmed,eaddir) END;
IF aalloc <= 0 THEN popreg(areg);
eaadir.reg := atop;
(*OP*) eaddir.reg := dtop;
(*OP*) genx(tadd,2,eaddir,eaadir);
freedreg;
END;
END; (*PXIXA*)
PROCEDURE pxind;
BEGIN WITH instr^ DO BEGIN
(*T <- MEMÆT + OPAND1Å*)
IF aalloc <= 0 THEN popreg(areg);
buildaddr(source,based,atop,anone,opand1);
IF opand1 = 0 THEN source.mode := defer;
IF dtype = atyp
THEN
BEGIN
optimi := nextpcod(instr);
IF optimi^.opcode = xstr
THEN
BEGIN
effaddress(optimi,dest);
optimi^.inuse := false;
genx(tmove,4,source,dest)
;freeareg
END
ELSE
BEGIN
eaadir.reg := atop;
genx(tmove,4,source,eaadir)
END
END
ELSE BEGIN
IF NOT (dtype IN longtypes) THEN
BEGIN
optimi := nextpcod(instr);
optimi^.inuse := false;
(*0610A*) IF (dtop=dnone) AND ((optimi^.opcode=xad)
(*0610A*) OR (optimi^.opcode=xsb) OR
(*0610A*) (optimi^.opcode=xand) OR
(*0610A*) (optimi^.opcode=xior))
(*0610A*) THEN popreg(dreg);
eaddir.reg := dtop;
freeareg;
optim2 := nextpcod(optimi);
IF optimi^.opcode = xarg
THEN genx(tmove,sizeÆdtypeÅ,
source,eapush)
ELSE
IF optimi^.opcode=xad
THEN genx(tadd,sizeÆdtypeÅ,source,eaddir)
ELSE IF optimi^.opcode=xsb
THEN genx(tsub,sizeÆdtypeÅ,source,eaddir)
ELSE IF optimi^.opcode=xand
THEN genx(tand,sizeÆdtypeÅ,source,eaddir)
ELSE IF optimi^.opcode=xior
THEN genx(tor,sizeÆdtypeÅ,source,eaddir)
ELSE IF optimi^.opcode = xstr
THEN
BEGIN
effaddress(optimi,dest);
genx(tmove,sizeÆdtypeÅ,
source,dest)
END
ELSE IF (optimi^.opcode = xldc)
AND (conditional(optim2)>0)
THEN
BEGIN
eaimmed.displ :=
optimi^.opand1;
IF dtype = ctyp
THEN eaimmed.displ :=
asciiÆoptimi^.opstring^.vstringaÆ1ÅÅ;
IF optimi^.dtype=jtyp
THEN BEGIN
opand1 := optimi^.opand1;
opand2 := optimi^.opand2;
opand3 := optimi^.opand3;
opand4 := optimi^.opand4;
genx(tcmp,4,ealong,source);
END
ELSE
IF eaimmed.displ = 0
THEN genx(ttst,sizeÆdtypeÅ
,source,eanone)
ELSE genx(tcmp,sizeÆdtypeÅ
,eaimmed,source);
optim2^.opand3 :=200
END
ELSE BEGIN
optimi^.inuse := true;
allocdreg;
eaddir.reg := dtop;
genx(tmove,sizeÆdtypeÅ,source,eaddir);
END;
END
ELSE BEGIN IF dtype = ptyp THEN opand2 :=8;
IF dtype IN Æstyp,vtypÅ THEN BEGIN
freeareg;
pushall;
eaadir.reg := a0;
genx(tlea,2,source,eaadir);
longbsr;
IF dtype = vtyp THEN BEGIN
(*604*) pcprint;
writeln(listing,' ':10,
'DC.W ',opand2:0);
eaimmed.displ := opand2;
genx(tdc,2,eaimmed,eanone)
END
END ELSE BEGIN (*PTYP*)
loadbig(source,opand2);
(*1207E*) IF dtype = ptyp THEN freeareg;
END;
END;
END
END;
END ; (*PXIND*)
PROCEDURE pxsto;
BEGIN WITH instr^ DO BEGIN
(* MEMÆT'Å <- T *)
IF dtype IN Æstyp,vtypÅ THEN BEGIN
IF (aalloc<>0) OR (dalloc<>0) THEN
error('REGISTERS NOT EMPTY ');
freeall;
IF dtype = styp THEN BEGIN
allocdreg;
eaimmed.displ := opand1;
eaddir.reg := dtop;
genx(tmove,2,eaimmed,eaddir);
END;
longbsr;
IF dtype = vtyp THEN BEGIN
(*604*) pcprint;
writeln(listing,'DC.W ',opand1:0);
eaimmed.displ := opand1;
genx(tdc,2,eaimmed,eanone)
END ELSE
freedreg;
(*1207D*) stkptr := stkptr - 1;
END ELSE
IF dtype = ptyp THEN BEGIN
WHILE dalloc<2 DO popreg(dreg);
IF aalloc < 1 THEN popreg(areg);
(*1303A*) buildaddr(source,defer,atop,anone,0);
storebig(source,8);
freeareg;
END ELSE
IF dtype = atyp THEN
BEGIN WHILE aalloc < 2 DO popreg(areg);
eaadir.reg := atop;
freeareg;
buildaddr(source,defer,atop,anone,0);
genx(tmove,4,eaadir,source);
freeareg
END
ELSE BEGIN IF dalloc < 1 THEN popreg(dreg);
IF aalloc < 1 THEN popreg(areg);
buildaddr(source,defer,atop,anone,0);
storelittle;
freeareg;
END
END;
END; (*PXSTO *)
PROCEDURE pxldc;
VAR j,k: integer;
BEGIN WITH instr^ DO BEGIN
IF dtype = atyp THEN
BEGIN allocareg;
eaadir.reg := atop;
(*604*) genx(tmove,4,ealong,eaadir) (* LOAD 4 CONSTS *)
END ELSE
(*604*) IF dtype = jtyp
(*604*) THEN BEGIN
(*604*) allocdreg;
(*604*) eaddir.reg := dtop;
(*604*) genx(tmove,4,ealong,eaddir)
(*604*) END ELSE
(*480*) IF dtype IN Æstyp,vtypÅ THEN
BEGIN
(*480*) IF dtype = vtyp THEN
(*480*) BEGIN
(*480*) k := opstring^.stringl; (* STRING LEN*)
(*480*) (*IF STC THRU HERE *) IF opcode = xldc THEN opand3:=opand1;
(*480*) opstring^.stringl := opand3; (*VEC *)
(*480*) IF k < opand3
(*480*) THEN FOR j := k + 1 TO opand3 DO
(*480*) opstring^.vstringaÆjÅ := ' '
(*480*) END;
pushall;
longbsr;
k := opstring^.stringl;
eaimmed.displ := k;
IF odd(k) THEN k := k + 1;
(*604*) pcprint;
writeln(listing,' ':10,'DC.W ',
eaimmed.displ:0);
genx(tdc,2,eaimmed,eanone);
(*604*) pcprint;
write(listing,' ':10,'DC.W ');
vstringimmed(1,k);
writeln(listing,' ');
END
ELSE
(*RM*) IF dtype = ptyp THEN
(*RM*) loadpset
(*RM*) ELSE
BEGIN
IF dtype = ctyp THEN
eaimmed.displ := asciiÆopstring^.vstringaÆ1ÅÅ
ELSE
eaimmed.displ := opand1;
optimi := nextpcod(instr);
optimi^.inuse := false;
IF (optimi^.opcode=xarg) OR (optimi^.opcode=xexi)
OR (optimi^.opcode=xwrs) OR (optimi^.opcode=xwrv)
THEN BEGIN
IF (optimi^.opcode=xwrs) OR (optimi^.opcode=xwrv)
THEN pushalld;
IF optimi^.opcode<>xarg THEN BEGIN
optimi^.inuse := true;
optimi^.dtype := dtype
(*1205B*) ;
(*1205B*) IF optimi^.opcode<>xexi THEN BEGIN
(*1205B*) stkptr := stkptr +1;
(*1205B*) typestkÆstkptrÅ := dtype;
(*1205B*) kindstkÆstkptrÅ := dreg;
(*1205B*) END END;
genx(tmove,sizeÆoptimi^.dtypeÅ,eaimmed,eapush)
; optimi^.dtype := notatyp
END
ELSE IF optimi^.opcode=xsto
THEN BEGIN
eadefer.reg := atop;
genx(tmove,sizeÆoptimi^.dtypeÅ,eaimmed,eadefer)
;freeareg
END
ELSE IF (optimi^.opcode = xstr)
AND ((optimi^.opand1 = level)
OR (optimi^.opand1 = 0))
THEN BEGIN
eabased.displ := optimi^.opand2;
IF (eabased.displ>=0) AND (optimi^.opand1=level)
THEN eabased.displ := eabased.displ+12;
IF optimi^.opand1 = 0
THEN eabased.reg := a5
ELSE eabased.reg := a6;
genx(tmove,sizeÆoptimi^.dtypeÅ,eaimmed,eabased)
END
ELSE IF (conditional(optimi) > 0)
AND (dtop<>dnone)
THEN BEGIN
eaddir.reg := dtop;
IF eaimmed.displ=0 THEN
genx(ttst,sizeÆdtypeÅ,eaddir,eanone)
ELSE
genx(tcmp,sizeÆdtypeÅ,eaimmed,eaddir);
optimi^.opand3 := 100; (* SET FLAG *)
optimi^.inuse := true
END
ELSE IF optimi^.opcode=xixa
THEN BEGIN
eaimmed.displ := opand1 * optimi^.opand1;
eaadir.reg := atop;
genx(tadd,2,eaimmed,eaadir)
END
ELSE
BEGIN
allocdreg;
optimi^.inuse := true;
eaddir.reg := dtop;
genx(tmove ,2,eaimmed,eaddir);
END
END
END;
END; (*PXLDC*)
(*480*) PROCEDURE pxstc;
(*480*) BEGIN WITH instr^ DO BEGIN
(*480*) effaddress(instr,source);
(*480*) pushall;
(*480*) eaadir.reg := a0;
(*480*) genx(tlea,2,source,eaadir);
(*480*) pxldc (* LET LOAD CONSTANT PROCESSOR DO REST *)
(*480*) END (* WITH *)
(*480*) END; (*PXSTC*)
PROCEDURE pxlta;
BEGIN WITH instr^ DO BEGIN
allocareg;
eaadir.reg := sp;
buildaddr(source,defer,atop,anone,0);
genx(tmove,4,eaadir,source)
END;
END; (*PXLTA*)
PROCEDURE pxlca;
BEGIN
;(*LEAVE INDICATION TO ALLOCATE STORAGE AT END
OF THIS BLOCK; GEN LEA ATOP WITH PC^(DISPL)*)
END; (* PXLCA*)
PROCEDURE pxisc;
BEGIN WITH instr^ DO BEGIN
eaimmed.displ := 1;
eadefer.reg := a5;
genx(tadd,4,eaimmed,eadefer) (*'SC' IS ^A5*)
END;
END; (*PXISC*)
PROCEDURE pxlsc;
BEGIN WITH instr^ DO BEGIN
eaimmed.displ := opand1;
eadefer.reg := a5;
genx(tmove,4,eaimmed,eadefer) (*'SC' IS ^A5*)
END;
END; (*PXLSC*)
PROCEDURE pxequ;
VAR flag: boolean; (* TRUE MEANS NO DREG WAS ALLOC YET *)
BEGIN WITH instr^ DO BEGIN
flag := false;
IF opand3 = 200
THEN BEGIN
flag := true;
opand3 := 100
END;
IF dtype IN Æstyp,vtypÅ THEN BEGIN
longbsr;
IF dtype = vtyp
THEN
BEGIN
eaimmed.displ := opand1; (* VEC LEN *)
(*604*) pcprint;
IF debug <> 0 THEN
writeln(listing,' ':10,'DC.W ',
opand1:0);
genx(tdc,2,eaimmed,eanone)
(*604*) END;
IF (aalloc<>0) OR (dalloc<>0) THEN
error('REGISTERS NOT EMPTY ');
freeall;
allocdreg;
(*0326A*) regtypeÆdtopÅ := btyp;
END ELSE IF dtype = ptyp THEN BEGIN
WHILE dalloc < 4 DO popreg(dreg);
(*THE BELOW SHOULD BE OPTIMIZED FOR THE CASE
WHEN ONE ARGUMENT IS A CONSTANT*)
CASE subtypeÆopcodeÅ OF
1 (*EQU*) : opcde := teor;
2 (*NEQ*) : opcde := teor;
4 (*LEQ*) : BEGIN
opcde := tand;
eaddir.reg := dtop;
genx(tcomp,4,eaddir,eanone);
eaddir.reg := previous(dtop);
genx(tcomp,4,eaddir,eanone);
END;
6 (*GEQ*) : BEGIN
opcde := tand;
eaddir.reg :=
previous(previous(dtop));
genx(tcomp,4,eaddir,eanone);
eaddir.reg :=
previous(previous(previous(dtop)));
genx(tcomp,4,eaddir,eanone);
END;
END; (*CASE*)
buildaddr(source,ddirect,dtop,anone,0);
freedreg;
buildaddr(dest,ddirect,previous(dtop),anone,0);
genx(opcde,4,source,dest);
source.reg := dtop;
freedreg;
dest.reg := previous(dtop);
genx(opcde,4,source,dest);
source.reg := dtop;
freedreg;
dest.reg := dtop;
genx(tor,4,source,dest);
switch := false;
IF opcode <> xneq THEN opcode := xequ;
END ELSE BEGIN
optimi := nextpcod(instr);
switch := false;
IF opand3<>100 THEN BEGIN (*CMP ALREADY DONE*)
doubleop(source,dest,true(*COMMUTATIVITY*),switch);
k := sizeÆdtypeÅ;
genx(tcmp,k,source,dest);
(*1207A*) IF dtype = atyp THEN freeareg;
END
END;
IF dtype <> styp THEN BEGIN
eaddir.reg := dtop;
CASE subtypeÆopcodeÅ OF
1 (*EQU*) : opcde:=tseq;
2 (*NEQ*) : opcde:=tsne;
3 (*LES*) : IF switch THEN
opcde:=tsgt
ELSE opcde:=tslt;
4 (*LEQ*) : IF switch THEN
opcde:=tsge
ELSE opcde:=tsle;
5 (*GRT*) : IF switch THEN
opcde:=tslt
ELSE opcde:=tsgt;
6 (*GEQ*) : IF switch THEN
opcde:=tsle
ELSE opcde:=tsge;
END;
(*RM*) IF dtype = atyp THEN BEGIN
(*RM*) allocdreg;
(*RM*) eaddir.reg := dtop
(*RM*) END;
IF optimi = NIL THEN optimi:=instr; (*FORCE NOTEQ*)
IF optimi^.opcode = xfjp
THEN
BEGIN
optimi^.opand3 := 100 + conditional(instr)
;IF flag
THEN optimi^.opand3 := optimi^.opand3 + 100
END
ELSE BEGIN
IF flag
THEN BEGIN
allocdreg;
eaddir.reg := dtop
END;
IF dtype <> vtyp
THEN
BEGIN
genx(opcde,2,eaddir,eanone);
regtypeÆdtopÅ := btyp;
genx(tneg,1,eaddir,eanone)
END
END
END;
END;
END; (*PXEQU*)
PROCEDURE pxstp;
BEGIN WITH instr^ DO BEGIN
pushall;
(*PUSH ZERO ARGUMENT ON STACK*)
genx(tclr,2,eapush,eanone);
eaimmed.displ := 14;
genx(ttrap,2,eaimmed,eanone);
eaimmed.displ := 3;
genx(tdc,2,eaimmed,eanone);
END;
END; (*PXSTP*)
PROCEDURE pxexi;
BEGIN WITH instr^ DO BEGIN
pushall;
(*EXIT ARGUMENT ALREADY ON STACK*)
eaimmed.displ := 14;
genx(ttrap,2,eaimmed,eanone);
eaimmed.displ := opand1 + 3;
genx(tdc,2,eaimmed,eanone);
END;
END; (*PXEXI*)
PROCEDURE pxdis;
BEGIN WITH instr^ DO BEGIN
IF aalloc < 1 THEN popreg(areg);
(*604*) longbsr;
(*604*) eaimmed.displ := opand1;
(*604*) pcprint;
(*604*) writeln(listing,' ':10,'DC.W ',opand1:0);
(*604*) genx(tdc,2,eaimmed,eanone);
freeareg;
END;
END; (*PXDIS*)
PROCEDURE pxnew;
BEGIN WITH instr^ DO BEGIN
(*RM*) (*HEAP POINTER IS ^A5(4) *)
IF aalloc < 1 THEN popreg(areg);
(*604*) longbsr;
(*604*) eaimmed.displ := opand1; (* LENGTH TO ALLOC *)
(*604*) pcprint;
(*604*) writeln(listing,' ':10,'DC.W ',opand1:0);
(*604*) genx(tdc,2,eaimmed,eanone);
(*604*) freeareg;
END;
END; (*PXNEW*)
PROCEDURE pxmrk;
BEGIN WITH instr^ DO BEGIN
IF aalloc < 1 THEN popreg(areg);
(*604*) longbsr;
freeareg;
END;
END; (*PXMRK*)
PROCEDURE pxrls;
BEGIN WITH instr^ DO BEGIN
(*604*) IF aalloc < 1 THEN popreg(areg);
(*604*) longbsr;
(*604*) freeareg;
END;
END; (*PXRLS*)
PROCEDURE pxmst;
BEGIN
pushall;
END; (*PXMST*)
PROCEDURE pxarg;
BEGIN WITH instr^ DO BEGIN
(*604*) IF opand1 <> 0 THEN BEGIN
(*RM*) IF (dalloc=2) AND (dtype=ptyp) THEN
(*1205A*) BEGIN
(*1205A*) eaddir.reg := dtop;
(*1205A*) genx(tmove,4,eaddir,eapush);
(*1205A*) eaddir.reg := dbot;
(*1205A*) genx(tmove,4,eaddir,eapush);
(*1205A*) freedreg;freedreg
(*1205A*) END;
(*1205G*) IF (NOT (dtype IN longtypes)) AND (dalloc=0) AND (aalloc=0)
(*1205G*) THEN stkptr := stkptr -1;
(*RM*) IF aalloc = 1 THEN BEGIN pushareg;
stkptr:=stkptr-1 END;
(*RM*) IF dalloc = 1 THEN BEGIN pushdreg;
stkptr := stkptr -1 END;
IF (dalloc <> 0) OR (aalloc <> 0)
THEN error('STK NONEMPTY IN ARG ')
(*604*) END
END;
END; (*PXARG*)
PROCEDURE pxast;
BEGIN WITH instr^ DO BEGIN
(*ASSUMES PREVIOUS 'MST' HAS DONE PUSHALL*)
IF odd(opand1) THEN opand1:=opand1+1;
eaimmed.displ := opand1;(*SHOULD BE LONG #*)
eaadir.reg := sp;
genx(tsub,4,eaimmed,eaadir);
(*0416A*) IF NOT (dtype IN longtypes) THEN BEGIN
stkptr := stkptr +1;
IF stkptr>stkmax THEN
error('TOO MANY REG PUSHES ');
IF opand1=4 THEN kindstkÆstkptrÅ
:= areg ELSE kindstkÆstkptrÅ
:= dreg;
IF opand1=4 THEN typestkÆstkptrÅ:=atyp
ELSE IF opand1=2 THEN typestkÆstkptrÅ:=ityp
ELSE IF opand1=1 THEN typestkÆstkptrÅ:=btyp
ELSE IF opand1=8 THEN typestkÆstkptrÅ:=ptyp
ELSE typestkÆstkptrÅ:=vtyp;
IF dtype <> notatyp THEN BEGIN
typestkÆstkptrÅ:=dtype;
IF dtype = atyp
THEN kindstkÆstkptrÅ := areg
ELSE kindstkÆstkptrÅ := dreg;
END;
(*0416A*) END; (* LONGTYPES CODE *)
END;
END; (*PXAST*)
PROCEDURE pxmov;
BEGIN WITH instr^ DO BEGIN
WHILE aalloc < 2 DO popreg(areg);
IF opcode = xmov THEN
BEGIN allocdreg;
eaimmed.displ := opand1;
eaddir.reg := dtop;
genx(tmove,2,eaimmed,eaddir)
END
ELSE IF dalloc < 1 THEN popreg(dreg);
(*BYTE COUNT IS NOW IN DTOP*)
buildaddr(source,incr,atop,anone,0);
freeareg;
buildaddr(dest,incr,atop,anone,0);
(*RM*) genx(tmove,1,source,dest);
(*ONLY MOVES BYTE AT A TIME NOW*)(*FIX LIKE '_BIG'*)
eaddir.reg := dtop;
(*RM*) eaimmed.displ := 1;
(*RM*) genx(tsub,2,eaimmed,eaddir);
(*RM*) earel.displ := -4;
(*RM*) genx(tbne,0,earel,eanone);
freeareg;freedreg;
END;
END; (*PXMOV*)
PROCEDURE pxcup;
BEGIN WITH instr^ DO BEGIN
IF NOT proctableÆcurrlabelÅ.defined THEN
BEGIN
ltemp := pc;
sad(ltemp, 2);
referencelabel(currlabel,ltemp)
END;
proctableÆcurrlabelÅ.refed := true;
pushall;
ltemp := proctableÆcurrlabelÅ.location ;
lsb(ltemp, pc);
IF short(ltemp) THEN BEGIN
lasgn(earel.displ, ltemp);
IF (earel.displ >-128) AND (earel.displ < 127) THEN
BEGIN
ealab.displ := currlabel;
genx(tbsr, 2,ealab,eanone) ;
END
ELSE BEGIN
ealab.displ := currlabel;
genx(tlbsr,2,ealab,eanone);
END;
END ELSE
BEGIN
eadefer.reg := a3;
genx(tjsr,2,eadefer,eanone);
(*604*) pcprint;
write(listing,' ':10,'DC.L ':7,'$':1);
ssb(ltemp,2);
plint(listing,ltemp);
writeln(listing,' ');
FOR k := 0 TO 3 DO
BEGIN
eaimmed.displ := ltempÆkÅ;
genx(tdc,1,eaimmed,eanone)
END
END
END;
END; (*PXCUP*)
PROCEDURE pxvjp;
BEGIN WITH instr^ DO BEGIN
(*604*) pcprint;
(*RM*) writeln(listing,' ':10,'DC.W L',
(*RM*) opand1 + labeloffset:0,'-L',
(*RM*) lastlabel + labeloffset:0); (* GENX!!*)
IF labeltableÆopand1Å.defined
THEN
BEGIN
ltemp := labeltableÆopand1Å.location;
lsb(ltemp,labeltableÆlastlabelÅ.location);
lasgn(eaimmed.displ, ltemp)
END
ELSE
BEGIN
ltemp := labeltableÆlastlabel-1Å.location;
lsb(ltemp,labeltableÆlastlabel-2Å.location);
sad(ltemp,1);
shl(ltemp,1); (*TIMES 2*)
(*0401A*)
lasgn(eaimmed.displ,ltemp)
END;
genx(tdc,2,eaimmed,eanone);
(*RM*) END;
END; (*PXVJP*)
PROCEDURE pxujp;
VAR flag: boolean; (* INDICATES THAT CMP ALREADY DONE *)
BEGIN WITH instr^ DO BEGIN
flag := opand3 >= 200;
IF flag THEN opand3 := opand3 - 100;
IF labeltableÆopand1Å.defined = true
THEN
BEGIN
ltemp := labeltableÆopand1Å.location;
lsb(ltemp, pc);
ssb(ltemp,2);
lasgn(k, ltemp)
END
ELSE k := 200;
CASE subtypeÆopcodeÅ OF
1 (*UJP*) : BEGIN opcde := tbra;
IF (k<-127) OR (k>127) THEN opcde := tlbra END;
2 (*FJP*) : BEGIN opcde := tbeq ;
IF (k<-127) OR (k>127) THEN opcde := tlbeq ;
IF (dalloc = 0) AND (opand3 < 100)
THEN popreg(dreg);
END
END;
buildaddr(source,labelled,anone,anone,opand1);
IF opand3 >100
THEN BEGIN
opand3 := opand3 - 100;
IF switch THEN
BEGIN
IF (opand3=3) OR (opand3=4) THEN opand3:=opand3+2
ELSE IF (opand3=5) OR (opand3=6) THEN opand3:=opand3-2;
END ;
CASE opand3 OF
1: ; (* NEQ ALREADY TURNED AROUND *)
2: IF opcde = tbeq THEN opcde := tbne
ELSE opcde := tlbne;
3: IF opcde = tbeq THEN opcde := tbge
ELSE opcde := tlbge;
4: IF opcde = tbeq THEN opcde := tbgt
ELSE opcde := tlbgt;
5: IF opcde = tbeq THEN opcde := tble
ELSE opcde := tlble;
6: IF opcde = tbeq THEN opcde := tblt
ELSE opcde := tlblt;
END; (*CASE*)
END;
genx(opcde,0,source,eanone) ;
IF labeltableÆopand1Å.defined = false THEN
BEGIN
ltemp := pc;
ssb(ltemp, 2);
referencelabel(opand1,ltemp);
END;
IF (opcode = xfjp) AND (NOT flag) THEN freedreg;
END;
END; (*PXUJP*)
PROCEDURE pxdif;
BEGIN
(*THE BELOW SHOULD BE OPTIMIZED FOR THE CASE
WHEN ONE ARGUMENT IS A CONSTANT *)
setops;
END; (*PXDIF*)
(*604*) PROCEDURE pxspos;
(*604*) BEGIN
(*604*) WITH instr^ DO
(*604*) BEGIN
(*604*) longbsr;
(*604*) IF opcode <> xscon
THEN BEGIN
dtype := ityp;
allocdreg
END
(*604*) END
(*604*) END; (* PXSPOS *)
PROCEDURE pxsdel;
BEGIN
WITH instr^ DO
BEGIN
IF dalloc = 0
THEN BEGIN
eaddir.reg := d1;
genx(tmove,2,eapop,eaddir);
eaddir.reg := d0;
genx(tmove,2,eapop,eaddir);
stkptr := stkptr - 2;
dpopcnt := dpopcnt + 2
END ELSE
IF dalloc = 1
THEN BEGIN
buildaddr(source,ddirect,dtop,anone,0);
eaddir.reg := d1;
genx(tmove,2,source,eaddir);
eaddir.reg := d0;
genx(tmove,2,eapop,eaddir);
stkptr := stkptr - 1;
dpopcnt := dpopcnt + 1
END;
longbsr
END;
freedreg;freedreg
END; (* PXSDEL *)
(*604*) PROCEDURE pxsins;
BEGIN
WITH instr^ DO
BEGIN
IF dalloc = 0 THEN popreg(dreg);
IF dtop <> d0
THEN BEGIN
buildaddr(source,ddirect,dtop,anone,0);
eaddir.reg := d0;
genx(tmove,2,source,eaddir)
END;
longbsr;
freedreg;
END
END; (* PXSINS *)
PROCEDURE pxinn;
BEGIN WITH instr^ DO BEGIN
WHILE dalloc < 3 DO popreg(dreg);
(* THE BELOW SHOULD BE OPTIMIZED FOR THE CASE
WHERE ONE ARGUMENT IS A CONSTANT*)
(*RM*) eaddir.reg := previous(previous(dtop));
eaimmed.displ := 32;
(*RM*) genx(tcmp,1,eaimmed,eaddir);
(*RM*) earel.displ := 6;
(*RM*) genx(tblt,0,earel,eanone);
buildaddr(dest,ddirect,previous(dtop),dnone,0);
genx(tbtst,0,eaddir,dest);
(*RM*) earel.displ := 4;
(*RM*) genx(tbra,0,earel,eanone);
(*RM*) buildaddr(dest,ddirect,dtop,dnone,0);
genx(tbtst,0,eaddir,dest);
freedreg; freedreg;
eaddir.reg := dtop;
(*RM*) genx(tsne,0,eaddir,eanone);
(*1015A*) genx(tneg,1,eaddir,eanone);
(*1323A*) regtypeÆdtopÅ := btyp;
END;
END; (*PXINN*)
PROCEDURE pxsgs;
BEGIN WITH instr^ DO BEGIN
IF dalloc < 1 THEN popreg(dreg);
(*THE BELOW SHOULD BE OPTIMIZED FOR THE CASE
WHEN ONE ARGUMENT IS A CONSTANT*)
(*RM*) allocdreg;allocdreg;
(*RM*) eaddir.reg := dtop;
(*RM*) genx(tclr,4,eaddir,eanone);
(*RM*) eaddir.reg := previous(dtop);
(*RM*) genx(tclr,4,eaddir,eanone);
(*RM*) eaddir.reg := previous(previous(dtop));
(*RM*) eaimmed.displ := 32;
(*RM*) genx(tcmp,1,eaimmed,eaddir);
(*RM*) earel.displ := 6;
(*1204A*) genx(tbge,0,earel,eanone);
(*RM*) buildaddr(dest,ddirect,previous(dtop),dnone,0);
(*RM*) genx(tbset,0,eaddir,dest);
(*RM*) earel.displ := 4;
(*RM*) genx(tbra,0,earel,eanone);
(*RM*) buildaddr(dest,ddirect,dtop,dnone,0);
(*RM*) genx(tbset,0,eaddir,dest);
(*1204A*) genx(tmove,4,dest,eaddir);
(*1204A*) freedreg;
END;
END; (*PXSGS*)
PROCEDURE pxchk;
BEGIN
WITH instr^ DO
BEGIN
eaddir.reg := d7; (* USE D7 FOR CHECKING *)
source := eaddir;
(*604*) IF ((dtype<>atyp) AND (dtop=dnone)) OR ((dtype=atyp) AND (atop=anone))
THEN BEGIN
source.reg := a7;
source.mode := defer
END
(*604*) ELSE IF dtype=atyp THEN BEGIN
(*604*) source.reg := atop;
(*604*) source.mode := adirect
(*604*) END
(*604*) ELSE source.reg := dtop;
(*604*) genx(tmove,sizeÆdtypeÅ,source,eaddir);
IF sizeÆdtypeÅ = 1
THEN genx(texte,2,eaddir,eanone);
(*604*) IF dtype IN Æatyp,jtypÅ
(*604*) THEN BEGIN opand1:=1; opand2:=1 END; (* FAKE OUT NEXT INSTRS*)
IF opand2 = 0
THEN BEGIN
genx(tneg,2,eaddir,eanone);
eaimmed.displ := -opand1
END;
IF opand1 = 0 THEN eaimmed.displ := opand2;
IF (opand1=0) OR (opand2=0)
THEN genx(tchk,2,eaimmed,eaddir)
ELSE
(*604*) IF NOT (dtype IN Æjtyp,atypÅ)
(*604*) THEN BEGIN
sasgn(ltemp,opand2);
IF opand1 > 0
THEN sad (ltemp,opand1)
ELSE ssb(ltemp,opand1);
IF short(ltemp)
THEN BEGIN
eaimmed.displ := opand1;
genx(tsub,2,eaimmed,eaddir);
eaimmed.displ := opand2 - opand1;
genx(tchk,2,eaimmed,eaddir)
END
ELSE BEGIN
eaimmed.displ := opand1;
genx(tcmp,2,eaimmed,eaddir);
earel.displ := 8;
genx(tblt,0,earel,eanone);
eaimmed.displ := opand2;
genx(tcmp,2,eaimmed,eaddir);
earel.displ := 2;
genx(tble,0,earel,eanone);
eaimmed.displ := 13;
genx(ttrap,2,eaimmed,eanone)
END
END
(*604*) ELSE IF dtype=jtyp THEN BEGIN (*JTYP*)
(*604*) eapset.displ := 0;
(*604*) genx(tcmp,4,eapset,eaddir);
(*604*) earel.displ := 10;
(*604*) genx(tblt,0,earel,eanone);
(*604*) eapset.displ := 8;
(*604*) genx(tcmp,4,eapset,eaddir);
(*604*) earel.displ := 4;
(*604*) genx(tble,0,earel,eanone);
(*604*) eaimmed.displ := 13;
(*604*) genx(ttrap,2,eaimmed,eanone)
(*604*) END
(*604*) ELSE BEGIN (*ATYP*)
(*604*) eabased.displ := 368;
(*604*) eabased.reg := a5;
(*604*) genx(tcmp,4,eabased,eaddir);
(*604*) earel.displ := 6;
(*604*) genx(tblt,0,earel,eanone);
(*604*) eabased.displ := 4;
(*604*) genx(tcmp,4,eabased,eaddir);
(*604*) earel.displ := 4;
(*604*) genx(tble,0,earel,eanone);
(*604*) eaimmed.displ := 13;
(*604*) genx(ttrap,2,eaimmed,eanone)
(*604*) END
END (* WITH *)
END; (*PXCHK*)
(*RM*) PROCEDURE pxcvb;
BEGIN WITH instr^ DO BEGIN
(*604*) IF (NOT (dtype IN longtypes))
(*604*) THEN BEGIN
(*604*) IF dalloc < 1 THEN popreg(dreg);
(*604*) IF opcode = xcvb
(*604*) THEN BEGIN
(*604*) IF dalloc < 2 THEN popreg(dreg);
(*604*) eaddir.reg := previous(dtop)
(*604*) END
(*604*) ELSE eaddir.reg := dtop;
(*604*) regtypeÆeaddir.regÅ := dtype;
(*604*) IF (d1type=htyp) AND (dtype=jtyp)
(*604*) THEN genx(texte,2,eaddir,eanone);
(*604*) IF sizeÆdtypeÅ > sizeÆd1typeÅ
(*604*) THEN genx(texte,sizeÆdtypeÅ,eaddir,eanone);
(*604*) END;
(*604*) IF (d1type=ctyp) AND (dtype=styp)
(*604*) THEN BEGIN
(*604*) IF dalloc<1 THEN popreg(dreg);
(*604*) eaddir.reg := dtop;
(*604*) freedreg;
pushall;
genx(tmove,1,eaddir,eapush);
(*604*) eaimmed.displ := 1;
(*604*) genx(tmove,2,eaimmed,eapush)
(*604*) END;
(*RM*) IF ((d1type=vtyp) AND (dtype=styp)) THEN BEGIN
(*RM*) eaimmed.displ := opand1;
(*RM*) genx(tmove,2,eaimmed,eapush);
(*RM*) END;
(*RM*) IF ((d1type=styp) AND (dtype=vtyp))
(*RM*) OR ((d1type=styp) AND (dtype=utyp))
(*RM*) OR ((d1type=utyp) AND (dtype=styp)) THEN BEGIN
(*RM*) allocdreg;
(*RM*) eaddir.reg := dtop;
(*RM*) eaimmed.displ := opand1;
(*RM*) genx(tmove,4,eaimmed,eaddir);
(*RM*) freedreg;
longbsr;
(*RM*) END
(*RM*) END;
END; (*PXCVB*)
BEGIN (* GENERATE *)
CASE instr^.opcode OF
xatn,xcos,xsin,xexp,xsqt,xlog,xrnd,xtrc:
error('REAL NOT IMPLEMENTED');
(*604*) xscon,xspos,xslen: pxspos;
(*604*) xsins : pxsins;
xsdel,xscop : pxsdel;
xlab: pxlab;
(*RM*) xend: pxend;
xdef: pxdef;
xent,xentb: pxent;
xret: pxret;
xab,xng,xsqr,xnot,xdec,xinc,xodd: pxab;
xad,xsb,xmp,xdv,xmod,xior,xand: pxad;
xclo,xifd,xafi,xeol,xeof,xget,xput,xpos,xsee,xpee,xpok,
(*604*) xrdh, xwrh,
xrst,xrwt,xrln,xwln,xpag,xeio,
xrdb,xrdc,xrde,xrdi,xrdj,xrdq,xrdr,xrds,xrdv,
xwrb,xwrc,xwre,xwri,xwrj,xwrq,xwrr,xwrs,xwrv: pxclo;
xlod,xlda,xstr: pxlod;
xixa: pxixa;
xind: pxind;
xsto: pxsto;
(*480*) xstc: pxstc;
xldc: pxldc;
xlta: pxlta;
xlca: pxlca;
xisc: pxisc;
xlsc: pxlsc;
xequ,xneq,xles,xleq,xgrt,xgeq: pxequ;
xstp: pxstp;
xexi: pxexi;
xdis: pxdis;
xnew: pxnew;
xmrk: pxmrk;
xrls: pxrls;
xmst: pxmst;
xarg: pxarg;
xast: pxast;
xmov,xmovv: pxmov;
xcup: pxcup;
xxjp: genxxjp;
xvjp: pxvjp;
xujp,xfjp: pxujp;
xdif,xint,xuni: pxdif;
xinn: pxinn;
xsgs: pxsgs;
xchk:pxchk ;
xcvb,xcvt: pxcvb;
xchkf,xdas,xext,xins,xlupa,xlspa,xcsp,xcspf,xcupf,xdata,xdatb: ;
(*NOT CURRENTLY GEN'ED BY COMPILER*)
xnone: ;
END (*CASES*)
END; (*GENERATE*)
BEGIN (*FLUSH*)
optimi := firsti;
changed := false;
WHILE optimi <> NIL DO
BEGIN
WITH optimi^ DO
BEGIN
(*480*) IF inuse AND ((opcode = xldc) OR (opcode = xinc)
(*480*) OR (opcode = xlda))
THEN
BEGIN
CASE opcode OF
(*480*) xlda: BEGIN
(*480*) IF NOT (dtype IN longtypes)
(*480*) THEN
(*480*) BEGIN
(*480*) optim2 := nextpcod(optimi);
(*480*) optim3 := nextpcod(optim2);
(*480*) IF (optim2^.opcode=xldc)
(*480*) AND (optim2^.dtype=ityp)
(*480*) AND(optim3^.opcode=xixa)
(*480*) THEN BEGIN
(*480*) optim2^.inuse :=false;
(*480*) optim3^.inuse := false;
(*480*) optimi^.opand2 :=
(*480*) optimi^.opand2 +
(*480*) optim2^.opand1 *
(*480*) optim3^.opand1;
(*480*) changed := true
(*480*) END
(*480*) ELSE IF ((optim2^.opcode=xldc)
(*480*) OR (optim2^.opcode=xlod))
(*480*) AND (optim3^.opcode=xsto)
(*480*) THEN BEGIN
(*480*) inuse := false;
(*480*) changed := true;
(*480*) optim3^.opand3 :=
(*480*) optim3^.opand1;
(*480*) optim3^.opand1:=opand1;
(*480*) optim3^.opand2:=opand2;
(*480*) optim3^.opcode:=xstr
(*480*) END
(*480*) ELSE IF optim2^.opcode=xind
(*480*) THEN BEGIN
(*480*) optim2^.inuse :=false;
(*480*) changed := true;
(*480*) optimi^.opcode := xlod;
(*480*) optimi^.dtype :=
(*480*) optim2^.dtype;
(*480*) optimi^.optype := optli;
(*480*) optimi^.opand2 :=
(*480*) optimi^.opand2 +
(*480*) optim2^.opand1;
(*480*) optimi^.opand3 :=
(*480*) optim2^.opand2;
(*480*) END
(*480*) END
(*480*) END; (* XLDA*)
xldc: BEGIN
IF NOT (dtype IN longtypes)
AND (dtype <> jtyp) AND (dtype<>atyp)
THEN
BEGIN
changed := true; (*ASSUME*)
(*480*) tempi := nextpcod(optimi);
IF tempi^.opcode=xdec
THEN
BEGIN
opand1:=opand1
- tempi^.opand1;
tempi^.inuse:=false;
END (*THEN*)
ELSE IF tempi^.opcode=xinc
THEN BEGIN
opand1:=opand1+
tempi^.opand1;
tempi^.inuse:=false
END
ELSE IF tempi^.opcode=xad
THEN BEGIN
opcode := xinc;
tempi^.inuse:=false
END
ELSE IF tempi^.opcode=xsb
THEN BEGIN
opcode:= xdec;
tempi^.inuse := false
END
(*480*) ELSE IF tempi^.opcode=xng
(*480*) THEN BEGIN
(*480*) opand1 := -opand1;
(*480*) tempi^.inuse:=false
(*480*) END
ELSE IF (opand1=0)
AND (tempi^.opcode=xixa)
THEN BEGIN
inuse := false;
tempi^.inuse:=false
END
(*480*) ELSE IF (tempi^.opcode=xcvt)
(*480*) AND (tempi^.d1type=ctyp)
(*480*) AND (tempi^.dtype=ityp)
(*480*) THEN BEGIN
(*480*) tempi^.inuse := false;
(*480*) dtype := ityp;
(*480*) opand1 :=asciiÆ
(*480*) opstring^.
(*480*) vstringaÆ1ÅÅ
(*480*) END
ELSE changed := false;
END (*THEN*)
(*480*) ELSE
(*480*) BEGIN (* S OR V *)
(*480*) changed := true;
(*480*) optim2 := nextpcod(optimi);
(*480*) IF (optim2^.opcode=xcvt)
(*480*) AND (dtype = styp)
(*480*) AND (optim2^.d1type=styp)
(*480*) AND (optim2^.dtype=vtyp)
AND (optim2^.opand1<=strlength)
(*480*) THEN BEGIN
(*480*) optim2^.inuse := false;
(*480*) opand1 := optim2^.opand1;
(*480*) dtype := vtyp;
(*480*) END
(*480*) ELSE IF (optim2^.opcode=xstr)
(*480*) AND (optim2^.dtype=vtyp)
(*480*) AND(dtype = vtyp)
AND (opand1<=strlength)
(*480*) THEN BEGIN
(*480*) optim2^.inuse := false;
(*480*) opcode := xstc;
(*480*) opand3 := opand1;
(*480*) opand1:=optim2^.opand1;
(*480*) opand2:=optim2^.opand2
(*480*) END
(*480*) ELSE changed := false
(*480*) END (* S OR V *)
END; (*XLDC*)
xinc: BEGIN
IF NOT (dtype IN longtypes)
AND (dtype<>jtyp) AND (dtype <> atyp)
THEN BEGIN
tempi := nextpcod(optimi);
IF tempi^.opcode=xdec
THEN BEGIN
opand1:=opand1
- tempi^.opand1;
tempi^.inuse:=false;
IF opand1 = 0
THEN inuse := false
ELSE changed :=true;
END
END
END; (*XINC*)
END; (*CASE*)
END; (*THEN*)
END; (*WITH*)
IF NOT changed THEN optimi := optimi^.next ELSE optimi:=firsti;
changed := false;
END; (*WHILE*)
tempi := firsti;
WHILE tempi <> NIL DO
BEGIN
IF tempi^.inuse THEN BEGIN
IF odd(debug DIV 2) THEN flpc := true;
generate(tempi);
tempi^.inuse := false END;
tempi := tempi^.next
END;
lasti := firsti;
templevel := -1; (*INVALIDATE A4 (POINTER TO INTERMED LEXICAL LEVEL*)
END; (*FLUSH*)
(*-------------------------------------------------------------------------
INPUT SCANNER SECTION
-------------------------------------------------------------------------*)
PROCEDURE nextline ;
VAR i: integer ;
BEGIN
IF eof(pcode) THEN writeln(output,'**** EOF ENCOUNTERED':24) ;
(* HALT NEEDED INSIDE THIS 'THEN' *)
REPEAT
linelen := 1 ;
WHILE NOT eoln(pcode) AND (linelen < linelngth) DO
BEGIN
read(pcode,linebufÆlinelenÅ);
linelen := linelen + 1
END;
readln(pcode);
linebufÆlinelenÅ := ' ' ;
IF linebufÆ1Å = '.' THEN linecount := linecount+1 ;
IF (odd(debug DIV 8) AND (linebufÆ1Å='.'))
OR (odd(debug DIV 4) AND (linebufÆ1Å<>'.'))
THEN BEGIN
write(listing, '*' );
FOR i:=1 TO linelen DO write(listing, linebufÆiÅ) ;
IF linebufÆ1Å = '.'
THEN write(listing,' ':(95 - linelen),linecount:6);
writeln(listing,' ')
END;
UNTIL (linebufÆ1Å <> '.') OR eof(pcode);
chcnt := 1 ;
END (* NEXTLINE *) ;
PROCEDURE getheader;
VAR
i: integer;
okval: boolean;
BEGIN
nextline;
linebufÆlinelen+1Å := ' ';
IF linebufÆ3Å<>'2'
THEN writeln(output,' ***** INPUT NOT M68000 PCODES!',
' COMPILER PHASE 2 ABORTING. *****');
chcnt := 5;
getstring; (* MODULE NAME *)
mainflg := linebufÆ17Å <> 'S'; (* MAIN OR SUBPROGRAM *)
chcnt := 18; (* POINT BEYOND OPTIONS *)
okval := gethex;
IF okval THEN exproc := ltemp; (* NUMBER OF ENTRIES IN JUMP TABLE *)
jtsize := getinteger; (* NUMBER OF ENTRIES IN JUMP TABLE *)
pc := exproc;
sad(pc,jtsize * 10);
okval := gethex;
IF okval THEN heapstart := ltemp;
okval := gethex;
IF okval THEN stkstart := ltemp;
genstart := pc;
IF mainflg THEN sad(pc,24); (* LEAVE ROOM FOR INIT CODE *)
genloc := pc;
corebase := pc;
END; (* GETHEADER *)
PROCEDURE scan;
VAR xexternal: boolean;
(*RM*) i: integer; (* COUNTER FOR SET INIT *)
PROCEDURE getopcode; (*PROCESS INPUT LINE FOR A LEGAL OPCODE, LOOK
IT UP IN 'MN', SET CURROPCODE, CURROPTYPE *)
VAR i: integer;
j: mns;
BEGIN
WHILE (linebufÆchcntÅ = ' ') AND (chcnt < linelen) DO
chcnt := chcnt + 1;
i := 1;
WHILE (linebufÆchcntÅ <> ' ') AND (i<5) AND (chcnt < linelen) DO
BEGIN
opsymÆiÅ := linebufÆchcntÅ;
chcnt := chcnt + 1; i := i + 1;
END;
WHILE i < 5 DO BEGIN opsymÆiÅ := ' '; i := i + 1 END;
curropcode := xnone;
IF (opsymÆ1Å<>'Y') AND (opsymÆ1Å<>'Z') THEN
FOR j := fmnÆopsymÆ1ÅÅ TO pred(fmnÆsuccibm(opsymÆ1Å)Å) DO
IF mnÆjÅ = opsym THEN curropcode := j;
IF curropcode = xnone THEN BEGIN error('ILLEGAL OPCODE ');
curroptype := op0
END
ELSE curroptype := otÆcurropcodeÅ;
END; (*GETOPCODE*)
PROCEDURE gettype;
BEGIN
WHILE (linebufÆchcntÅ = ' ') AND (chcnt < linelen) DO
chcnt := chcnt + 1;
WITH curri^ DO BEGIN
dtype := notatyp;
IF (linebufÆchcntÅ>='A') AND (linebufÆchcntÅ<='V') THEN
CASE linebufÆchcntÅ OF
'D','E','F','G','K','L','M','N','O','T': ;
'A': dtype := atyp;
(*RM*) 'H': dtype := htyp;
'I': dtype := ityp;
'J': dtype := jtyp;
'R': dtype := rtyp;
'Q': dtype := qtyp;
(*RM*) 'U': dtype := utyp;
'V': dtype := vtyp;
'S': dtype := styp;
'B': dtype := btyp;
'C': dtype := ctyp;
'P': dtype := ptyp
END;
END;
chcnt := chcnt + 1;
END; (*GETTYPE*)
PROCEDURE getlabel;
BEGIN
WHILE (linebufÆchcntÅ = ' ') AND (chcnt < linelen) DO
chcnt := chcnt + 1;
IF linebufÆchcntÅ = 'L' THEN dollar := false
ELSE IF linebufÆchcntÅ = '$' THEN dollar := true
ELSE error('LABEL EXPECTED ');
chcnt := chcnt + 1;
IF dollar THEN currlabel := getinteger
ELSE BEGIN currlabel := getinteger - labeloffset ;
IF currlabel<0 THEN currlabel:= 0; (* NEEDED IF OLD PCODES *)
IF currlabel > highlabel THEN highlabel:= currlabel
END
END; (*GETLABEL*)
PROCEDURE definelabel( absol: boolean);
PROCEDURE fixup(absol: boolean);
VAR addr1: ^labelref; addr2: lint;
addr3: integer;
i: integer;
BEGIN
addr1 := labeltableÆcurrlabelÅ.refchain;
REPEAT
addr2 := addr1^.coreloc ;
ltemp := addr2;
lsb(ltemp,corebase);
sad(ltemp,1);
lasgn(i, ltemp);
IF i <= 0
THEN
BEGIN
gensave := genloc;
genloc := addr2;
locount := maxcore - 20;
coresave := corecount;
corecount := maxcore - 19;
END;
IF NOT absol
THEN BEGIN
ltemp := pc;
lsb(ltemp, addr2);
lasgn(i,ltemp);
IF locount <> 1
THEN addr3 := locount
ELSE
BEGIN
ltemp := addr2;
lsb(ltemp, corebase);
sad(ltemp, 1);
lasgn(addr3,ltemp)
END;
coreÆaddr3Å := i DIV 256;
coreÆaddr3+1Å := i MOD 256
END ELSE
BEGIN
IF locount <> 1
THEN addr3 := locount
ELSE
BEGIN
ltemp := addr2;
lsb(ltemp,corebase);
sad (ltemp,1);
lasgn(addr3,ltemp)
END;
lasgn(i, labeltableÆcurrlabelÅ.location);
coreÆaddr3Å := defvalue DIV 256;
coreÆaddr3+1Å := defvalue MOD 256;
IF (defvalue < 0) OR (i < 0)
THEN BEGIN
coreÆaddr3Å := abs(coreÆaddr3Å);
coreÆaddr3+1Å:=abs(coreÆaddr3+1Å);
coreÆaddr3Å := 255 - coreÆaddr3Å;
coreÆaddr3+1Å := 256 - coreÆaddr3+1Å;
IF coreÆaddr3+1Å = 256
THEN BEGIN
coreÆaddr3+1Å := 0;
coreÆaddr3Å := coreÆaddr3Å + 1;;
IF coreÆaddr3Å = 256
THEN coreÆaddr3Å := 0;
END;
END
END ;
IF locount <> 1
THEN
BEGIN
emitcode;
genloc := gensave;
locount := 1;
corecount := coresave;
END;
addr1 := addr1^.next;
UNTIL addr1 = NIL;
END; (*FIXUPLABEL*)
BEGIN (*DEFINELABEL*)
flush;
WITH labeltableÆcurrlabelÅ DO BEGIN
IF defined THEN error ('DOUBLY DEFINED LABEL')
ELSE IF refed THEN fixup(absol);
defined := true;
IF NOT absol THEN location := pc
ELSE sasgn(location, defvalue)
END
END; (*DEFINELABEL*)
PROCEDURE defineproc(absol: boolean);
PROCEDURE fixupproc;
VAR
addr1:^labelref; addr2: lint; i: integer;
BEGIN
gensave := genloc;
coresave := corecount;
addr1 := proctableÆcurrlabelÅ.refchain;
REPEAT
locount := maxcore - 20;
corecount := maxcore - 17; (* DATA IS IN -20 TO -17 *)
addr2 := addr1^.coreloc;
IF curropcode = xdef
THEN BEGIN
ltemp := exproc;
lsb(ltemp, addr2)
END
ELSE BEGIN
ltemp := pc;
lsb(ltemp, addr2)
END;
FOR i := 0 TO 3 DO
coreÆlocount + iÅ := ltempÆiÅ;
genloc := addr2;
emitcode;
addr1 := addr1^.next;
UNTIL addr1 = NIL;
genloc := gensave;
locount := 1;
corecount := coresave;
END; (*FIXUPPROC*)
BEGIN
flush;
WITH proctableÆcurrlabelÅ DO BEGIN
IF curropcode = xent THEN emitcode;
IF defined THEN error('DOUBLY DEFINED LABEL')
ELSE IF refed THEN fixupproc;
defined := true;
IF NOT absol THEN location := pc
ELSE sasgn(location, defvalue);
IF curropcode=xdef
THEN BEGIN
location := exproc;
sad(exproc,10);
END
END
END; (*DEFINEPROC*)
PROCEDURE quai(VAR newi: iptr);(*"QUAI" IS "QUEUE UP ANOTHER INSTRUCTION"*)
BEGIN IF lasti^.inuse THEN
IF lasti^.next = NIL THEN
BEGIN new(tempi);
tempi^.opstring := NIL;
tempi^.opset := NIL;
tempi^.next := NIL;
lasti^.next := tempi;
lasti := tempi
END
ELSE lasti := lasti^.next;
newi := lasti
END; (*QUAI*)
BEGIN (*SCAN*)
nextline;
IF linebufÆ1Å <> ' ' THEN BEGIN labeled := true; (*COLLECT LABEL*)
(*RM*) getlabel; lastlabel := currlabel
END
ELSE labeled := false;
getopcode;
IF curropcode = xdef
THEN IF NOT dollar
THEN
BEGIN
defvalue := getinteger;
absol := true
END
ELSE absol := false
ELSE absol := false;
IF labeled THEN IF dollar THEN defineproc(absol)
ELSE definelabel(absol);
quai(curri); (*GET A QUEUE SLOT FOR A NEW INSTRUCTION *)
WITH curri^ DO BEGIN
inuse := true; dtype := notatyp; d1type := notatyp;
opcode := curropcode; optype := curroptype;
opand1 := 0; opand2 := 0; opand3 := 0;
CASE optype OF
endop, op0: BEGIN
opand1 := currlabel;
IF curropcode = xdef THEN
IF NOT dollar THEN opand2 := defvalue
END;
opli: BEGIN opand1 := getinteger; opand2 := getinteger;
dtype := atyp END;
opt: BEGIN gettype;
IF dtype IN longtypes THEN opand1 := getinteger
END;
oplab: BEGIN getlabel; opand1 := currlabel END;
(*RM*) op2t: BEGIN gettype; d1type := dtype; gettype;
(*RM*) IF d1type IN Æstyp,utyp,vtypÅ THEN
(*RM*) opand1 := getinteger END;
opti: BEGIN gettype;
IF dtype = notatyp THEN chcnt := chcnt - 1;
opand1 := getinteger;
IF (opand1=0) AND (opcode = xarg)
THEN BEGIN
opcode := xnone;
inuse := false
END;
IF dtype IN longtypes THEN opand2 := getinteger
END;
opt2i: BEGIN
gettype;
IF dtype <> jtyp
THEN BEGIN opand1 := getinteger;
opand2 := getinteger
END
ELSE BEGIN
IF opset = NIL THEN new(opset);
WITH opset^ DO BEGIN
FOR i := 1 TO 8 DO BEGIN
opand1 := getinteger;
setvÆi*2-1Å :=
hexdataÆopand1 DIV 16 + 1Å;
setvÆi*2Å :=
hexdataÆopand1 MOD 16 + 1Å
END
END;
opand1 := 1;
END
END;
opi: opand1 := getinteger;
op3i: BEGIN opand1 := getinteger;
opand2 := getinteger;
opand3 := getinteger
END;
optli: BEGIN gettype; opand1 := getinteger;
opand2 := getinteger;
IF dtype IN longtypes THEN opand3 := getinteger
END;
optl2i: BEGIN gettype; opand1 := getinteger;
opand2 := getinteger;
opand3 := getinteger END;
optv: BEGIN gettype;
(*604*) IF dtype IN Æityp,htypÅ THEN opand1 := getinteger
(*604*) ELSE IF (dtype=atyp) AND (opcode<>xldc)
(*604*) THEN opand1 := getinteger
ELSE IF dtype IN Æ styp,ctypÅ THEN BEGIN
IF opstring = NIL THEN new(opstring);
getstring;
IF dtype = ctyp THEN alength := 1;
opstring^.stringl := alength;
opstring^.vstringa := vstring
END
ELSE IF dtype = btyp THEN BEGIN
opand1 := getinteger
END
(*604*) ELSE IF dtype = ptyp THEN BEGIN
(*RM*) IF opset = NIL THEN new(opset);
(*RM*) WITH opset^ DO BEGIN
(*RM*) FOR i := 1 TO 8 DO BEGIN
(*RM*) opand1 := getinteger;
(*RM*) setvÆi*2-1Å := hexdataÆopand1 DIV 16+1Å;
(*RM*) setvÆi*2Å := hexdataÆopand1 MOD 16 + 1Å;
(*RM*) END
(*RM*) END;
opand1 := 0
END ELSE IF dtype IN Æatyp,jtypÅ
THEN BEGIN
opand1 := getinteger;
opand2 := getinteger;
opand3 := getinteger;
opand4 := getinteger
(*RM*) END ELSE ; (* R NOT IMPLEMENTED *)
END;
opent: BEGIN opand1 := getinteger;
opand2 := getinteger; (*SEGSIZE LABEL*)
getstring; (*OPTIONS(IGNORED)*)
IF (vstringÆ1Å>='0') AND(vstringÆ1Å<='9')
THEN debug := ord(vstringÆ1Å)-ord('0');
IF (vstringÆ2Å>='0') AND (vstringÆ2Å<='9')
THEN debug := debug * 10 +
ord(vstringÆ2Å)-ord('0');
getstring; (*NAME*)
END;
opentb: (*NOT CURRENTLY IMPLEMENTED*)
END (*CASE*)
END (*WITH*)
END; (*SCAN*)
(*-------------------------------------------------------------------------
INITIALIZATION SECTION
-------------------------------------------------------------------------*)
PROCEDURE init;
VAR i: integer;
j: mns;
r: register;
BEGIN
errorwr := false;
writeln(listing,' ':10,'LLEN',' ':3,'120');
stkptr := -1;
flpc := false;
dalloc := 0; aalloc := 0;
dtop := dnone; atop := anone;
dbot := dnone; abot := anone;
sp := a7;
dalloccnt := 0; aalloccnt := 0;
dpushcnt := 0; apushcnt := 0;
dpopcnt := 0; apopcnt := 0;
longtypes := Æptyp,vtyp,styp,utypÅ;
sasgn(pc,12388);
debug := 9;
genloc := pc;
corecount := 0;
genstart := pc;
locount := 1;
corebase := pc;
clr(progstart);
mainflg := false;
linecount := -1;
sasgn(rtjump,490);
stkstartÆ0Å := 0; stkstartÆ1Å := 0; stkstartÆ2Å := 127;
stkstartÆ3Å := 254;
heapstartÆ0Å := 255; heapstartÆ1Å := 255; heapstartÆ2Å := 255;
heapstartÆ3Å := 255; (* INITIALIZE HEAPSTART TO HEX FFFFFFFF *)
jtsize := 10;
level := 0;
templevel := -1; (*-1 WHENEVER A4 NOT POINTING TO A VALID DISPLAY LEVEL*)
highlabel := 0; labeloffset := 0;
toplabel := 0;
absol := false;
FOR i:= 0 TO maxlabel DO BEGIN proctableÆiÅ.defined :=false;
proctableÆiÅ.refed :=false;
proctableÆiÅ.refchain := NIL;
labeltableÆiÅ.refchain := NIL;
labeltableÆiÅ.defined :=false;
labeltableÆiÅ.refed :=false
END;
new(firstesd); WITH firstesd^ DO BEGIN name := xnone;
next := NIL;
sasgn(reference, 0);
END;
sizeÆatypÅ := 4;
sizeÆitypÅ := 2;
sizeÆjtypÅ := 4;
sizeÆrtypÅ := 4;
sizeÆqtypÅ := 8;
sizeÆvtypÅ := 4;
sizeÆstypÅ := 4;
sizeÆbtypÅ := 1;
sizeÆptypÅ := 8;
sizeÆnotatypÅ := 0;
sizeÆctypÅ := 1;
(*RM*) sizeÆhtypÅ := 1;
(*RM*) sizeÆutypÅ := 4;
(*480*) new(fakei);
(*480*) WITH fakei^ DO
(*480*) BEGIN
(*480*) opcode := xnone; next := NIL; opand1 := 0; inuse := true;
(*480*) optype := op0; dtype := notatyp; d1type := notatyp;
(*480*) opand2 := 0; opand3 := 0; opstring := NIL; opset := NIL
(*480*) END;
new(firsti); lasti := firsti; firsti^.next := NIL; firsti^.inuse := false;
firsti^.opstring := NIL; firsti^.opset := NIL;
FOR i := 1 TO strlength DO blanksÆiÅ := ' ';
mnÆxab Å :='AB '; mnÆxad Å :='AD ';
mnÆxafi Å :='AFI '; mnÆxand Å :='AND ';
mnÆxarg Å :='ARG ';
mnÆxast Å :='AST '; mnÆxatn Å :='ATN ';
mnÆxchk Å :='CHK '; mnÆxchkfÅ :='CHKF';
mnÆxclo Å :='CLO ';
mnÆxcos Å :='COS '; mnÆxcsp Å :='CSP ';
mnÆxcspfÅ :='CSPF'; mnÆxcup Å :='CUP ';
mnÆxcupfÅ :='CUPF'; mnÆxcvb Å :='CVB ';
mnÆxcvt Å :='CVT '; mnÆxdas Å :='DAS ';
mnÆxdataÅ :='DATA'; mnÆxdatbÅ :='DATB';
mnÆxdec Å :='DEC '; mnÆxdef Å :='DEF ';
mnÆxdif Å :='DIF '; mnÆxdis Å :='DIS ';
mnÆxdv Å :='DV '; mnÆxeio Å :='EIO ';
mnÆxend Å :='END ';
mnÆxent Å :='ENT '; mnÆxentbÅ :='ENTB';
mnÆxeof Å :='EOF ';
mnÆxeol Å :='EOL '; mnÆxequ Å :='EQU ';
(*1015B*) mnÆxexi Å :='EXIT'; mnÆxexp Å :='EXP ';
mnÆxext Å :='EXT '; mnÆxfjp Å :='FJP ';
mnÆxgeq Å :='GEQ '; mnÆxget Å :='GET ';
mnÆxgrt Å :='GRT '; mnÆxifd Å :='IFD ';
mnÆxinc Å :='INC '; mnÆxind Å :='IND ';
mnÆxinn Å :='INN '; mnÆxins Å :='INS ';
mnÆxint Å :='INT '; mnÆxior Å :='IOR ';
mnÆxisc Å :='ISC '; mnÆxixa Å :='IXA ';
mnÆxlab Å :='LAB '; mnÆxlca Å :='LCA ';
mnÆxlda Å :='LDA '; mnÆxldc Å :='LDC ';
mnÆxleq Å :='LEQ '; mnÆxles Å :='LES ';
mnÆxlod Å :='LOD '; mnÆxlog Å :='LOG ';
mnÆxlsc Å :='LSC '; mnÆxlspaÅ :='LSPA';
mnÆxlta Å :='LTA '; mnÆxlupaÅ :='LUPA';
mnÆxmod Å :='MOD '; mnÆxmov Å :='MOV ';
mnÆxmovvÅ :='MOVV'; mnÆxmp Å :='MP ';
mnÆxmrk Å :='MRK '; mnÆxmst Å :='MST ';
mnÆxneq Å :='NEQ ';
mnÆxnew Å :='NEW '; mnÆxng Å :='NG ';
mnÆxnot Å :='NOT '; mnÆxodd Å :='ODD ';
mnÆxpag Å :='PAG '; mnÆxpee Å :='PEE ';
mnÆxpok Å :='POK '; mnÆxpos Å :='POS ';
mnÆxput Å :='PUT '; mnÆxrdb Å :='RDB ';
mnÆxrdc Å :='RDC '; mnÆxrde Å :='RDE ';
mnÆxrdi Å :='RDI '; mnÆxrdj Å :='RDJ ';
(*604*) mnÆxrdh Å := 'RDH '; mnÆxwrh Å := 'WRH ';
mnÆxrdq Å :='RDQ '; mnÆxrdr Å :='RDR ';
mnÆxrds Å :='RDS '; mnÆxrdv Å :='RDV ';
mnÆxret Å :='RET ';
mnÆxrln Å :='RLN '; mnÆxrls Å :='RLS ';
mnÆxrnd Å :='RND ';
mnÆxrst Å :='RST '; mnÆxrwt Å :='RWT ';
mnÆxsb Å :='SB '; mnÆxsconÅ :='SCON';
mnÆxscopÅ :='SCOP'; mnÆxsdelÅ :='SDEL';
mnÆxsee Å :='SEE '; mnÆxsgs Å :='SGS ';
mnÆxsin Å :='SIN '; mnÆxsinsÅ :='SINS';
mnÆxslenÅ :='SLEN'; mnÆxsposÅ :='SPOS';
mnÆxsqr Å :='SQR '; mnÆxsqt Å :='SQT ';
mnÆxstc Å :='STC ';
mnÆxsto Å :='STO '; mnÆxstp Å :='STP ';
mnÆxstr Å :='STR '; mnÆxtrc Å :='TRC ';
mnÆxujp Å :='UJP '; mnÆxuni Å :='UNI ';
(*RM*) mnÆxvjp Å :='VJP ';
mnÆxwln Å :='WLN '; mnÆxwrb Å :='WRB ';
mnÆxwrc Å :='WRC '; mnÆxwre Å :='WRE ';
mnÆxwri Å :='WRI '; mnÆxwrj Å :='WRJ ';
mnÆxwrq Å :='WRQ '; mnÆxwrr Å :='WRR ';
mnÆxwrs Å :='WRS '; mnÆxwrv Å :='WRV ';
mnÆxxjp Å :='XJP ';
mnÆxnoneÅ :=' ';
fmnÆ'A'Å :=xab ; fmnÆ'B'Å :=xchk;
fmnÆ'C'Å :=xchk; fmnÆ'D'Å :=xdas;
fmnÆ'E'Å :=xeio; fmnÆ'F'Å :=xfjp;
fmnÆ'G'Å :=xgeq; fmnÆ'H'Å :=xifd;
fmnÆ'I'Å :=xifd; fmnÆ'J'Å :=xlab;
fmnÆ'K'Å :=xlab; fmnÆ'L'Å :=xlab;
fmnÆ'M'Å :=xmod; fmnÆ'N'Å :=xneq;
fmnÆ'O'Å :=xodd; fmnÆ'P'Å :=xpag;
fmnÆ'Q'Å :=xrdb; fmnÆ'R'Å :=xrdb;
fmnÆ'S'Å :=xsb ; fmnÆ'T'Å :=xtrc;
(*RM*) fmnÆ'U'Å :=xujp; fmnÆ'V'Å :=xvjp;
fmnÆ'W'Å :=xwln; fmnÆ'X'Å :=xxjp;
fmnÆ'Y'Å :=xnone;fmnÆ'Z'Å :=xnone;
tmnÆtmove Å :='MOVE '; tmnÆtlink Å :='LINK '; tmnÆtunlk Å :='UNLK ';
tmnÆtrts Å :='RTS '; tmnÆttst Å :='TST '; tmnÆtbgt Å :='BGT.S';
tmnÆtneg Å :='NEG '; tmnÆtsubq Å :='SUB '; tmnÆtbtst Å :='BTST ';
tmnÆtsnz Å :='SNZ '; tmnÆtadd Å :='ADD '; tmnÆtsub Å :='SUB ';
tmnÆtand Å :='AND '; tmnÆtor Å :='OR '; tmnÆtmuls Å :='MULS ';
tmnÆtdivs Å :='DIVS '; tmnÆtcmp Å :='CMP '; tmnÆtclr Å :='CLR ';
tmnÆttrap Å :='TRAP '; tmnÆtdcnt Å :='DCNT '; tmnÆtbsr Å :='BSR.S';
tmnÆtaddq Å :='ADD '; tmnÆtcomp Å :='NOT '; tmnÆtlbsr Å :='BSR ';
tmnÆtmoveqÅ :='MOVE '; tmnÆtseq Å :='SEQ '; tmnÆtsne Å :='SNE ';
tmnÆtsge Å :='SGE '; tmnÆtslt Å :='SLT '; tmnÆtsgt Å :='SGT ';
tmnÆtsle Å :='SLE '; tmnÆtlea Å :='LEA '; tmnÆtldq Å :='MOVE ';
tmnÆtbraÅ :='BRA.S'; tmnÆtbne Å :='BNE.S'; tmnÆtequ Å :='EQU ';
tmnÆtbeqÅ :='BEQ.S';
tmnÆtlbgtÅ :='BGT '; tmnÆtlbra Å :='BRA ';
tmnÆtlbneÅ :='BNE '; tmnÆtlbeqÅ :='BEQ ';
tmnÆtlbltÅ :='BLT '; tmnÆtasl Å := 'ASL ';
tmnÆtblt Å :='BLT.S'; tmnÆtjmpÅ := 'JMP ';
tmnÆtpea Å :='PEA '; tmnÆtbsetÅ := 'BSET ';
tmnÆtbz Å :='BEQ '; tmnÆtjsr Å := 'JSR ';
(*RM*) tmnÆteor Å :='EOR ';
(*RM*) tmnÆtexte Å := 'EXT '; tmnÆtswapÅ :='SWAP ';
tmnÆtcmpm Å := 'CMPM ';
tmnÆtbnz Å := 'BNE.S'; tmnÆtbge Å := 'BGE.S';
tmnÆtble Å := 'BLE.S'; tmnÆtchk Å := 'CHK ';
tmnÆtdc Å := 'DC '; (*DUMMY INSTR*)
tmnÆtlbleÅ := 'BLE '; tmnÆtlbgeÅ := 'BGE ';
(*RM*) dnameÆatypÅ := 'A'; dnameÆitypÅ := 'I'; dnameÆjtypÅ := 'J';
(*RM*) dnameÆrtypÅ := 'R'; dnameÆqtypÅ := 'Q'; dnameÆvtypÅ := 'V';
(*RM*) dnameÆstypÅ := 'S'; dnameÆbtypÅ := 'B'; dnameÆptypÅ := 'P';
(*RM*) dnameÆnotatypÅ :=' '; dnameÆctypÅ := 'C'; dnameÆhtypÅ :='H';
(*RM*) dnameÆutypÅ := 'U';
FOR j := xab TO xxjp DO otÆjÅ := op0;
otÆxab Å := opt ; otÆxad Å := opt ;
(*604*) otÆxarg Å := opti ; (* CHANGE FOR 6809 CHIPS STUFF *)
otÆxast Å := opti ; otÆxatn Å := opt ;
(*604*) otÆxchk Å := opt2i ; otÆxchkfÅ := opt ;
otÆxcos Å := opt ; otÆxcsp Å := oplab ;
otÆxcup Å := oplab ;
otÆxcvb Å := op2t ;
otÆxcvt Å := op2t ; otÆxdas Å := opi ;
(*DATA,DATB*)
otÆxdec Å := opti ;
otÆxdis Å := opi ;
otÆxdv Å := opt ; otÆxend Å := endop ;
otÆxent Å := opent ; otÆxentbÅ := opentb;
otÆxequ Å := opt ;
otÆxexi Å := opi ;
otÆxexp Å := opt ;
otÆxext Å := optl2i; otÆxfjp Å := oplab ;
otÆxgeq Å := opt ;
otÆxgrt Å := opt ;
otÆxinc Å := opti ; otÆxind Å := opti ;
otÆxins Å := op3i ;
otÆxixa Å := opi ;
otÆxlca Å := optv ;
otÆxlda Å := opli ; otÆxldc Å := optv ;
otÆxleq Å := opt ; otÆxles Å := opt ;
otÆxlod Å := optli ; otÆxlog Å := opt ;
otÆxlsc Å := opi ; otÆxlspaÅ := opi ;
otÆxlupaÅ := opi ;
otÆxmod Å := opt ; otÆxmov Å := opi ;
otÆxmp Å := opt ;
otÆxneq Å := opt ;
otÆxnew Å := opi ; otÆxng Å := opt ;
otÆxodd Å := opt ;
otÆxret Å := opli ;
otÆxrnd Å := opt ;
otÆxsb Å := opt ;
otÆxsin Å := opt ;
otÆxsqr Å := opt ; otÆxsqt Å := opt ;
otÆxsto Å := opt ;
otÆxstr Å := optli ; otÆxtrc Å := opt ;
otÆxujp Å := oplab ;
(*RM*) otÆxvjp Å := oplab;
otÆxxjp Å := oplab ;
FOR j := xab TO xnone DO flÆjÅ := true;
flÆxab Å := false; flÆxad Å := false; flÆxand Å := false;
flÆxast Å := false; flÆxcvb Å := false; flÆxcvt Å := false;
flÆxdas Å := false;
flÆxdataÅ := false; flÆxdatbÅ := false; flÆxdec Å := false;
flÆxdif Å := false; flÆxdv Å := false; flÆxequ Å := false;
flÆxext Å := false;
flÆxgeq Å := false; flÆxgrt Å := false; flÆxinc Å := false;
flÆxind Å := false; flÆxinn Å := false; flÆxins Å := false;
flÆxint Å := false;
flÆxior Å := false;
flÆxixa Å := false; flÆxlca Å := false; flÆxlda Å := false;
flÆxldc Å := false; flÆxleq Å := false; flÆxles Å := false;
flÆxlod Å := false; flÆxlspaÅ := false; flÆxlta Å := false;
flÆxlupaÅ := false;
flÆxmod Å := false; flÆxmov Å := false; flÆxmp Å := false;
flÆxneq Å := false; flÆxng Å := false; flÆxnot Å := false;
flÆxodd Å := false; flÆxsb Å := false; flÆxsqr Å := false;
flÆxuni Å := false; flÆxnoneÅ := false;
FOR j := xab TO xxjp DO subtypeÆjÅ := 0;
subtypeÆxab Å := 1; subtypeÆxad Å := 1;
subtypeÆxng Å := 2; subtypeÆxsb Å := 2;
subtypeÆxdec Å := 3; subtypeÆxand Å := 3;
subtypeÆxinc Å := 4; subtypeÆxior Å := 4;
subtypeÆxnot Å := 5; subtypeÆxmp Å := 5;
subtypeÆxodd Å := 6; subtypeÆxdv Å := 6;
subtypeÆxsqr Å := 7; subtypeÆxmod Å := 7;
subtypeÆxlod Å := 1; subtypeÆxequ Å := 1;
subtypeÆxlda Å := 2; subtypeÆxneq Å := 2;
subtypeÆxstr Å := 3; subtypeÆxles Å := 3;
subtypeÆxleq Å := 4;
subtypeÆxgrt Å := 5;
subtypeÆxgeq Å := 6;
subtypeÆxujp Å := 1;
subtypeÆxfjp Å := 2;
buildaddr(eanone,none,anone,anone,0);
buildaddr(eaddir,ddirect,anone,anone,0);
buildaddr(eaadir,adirect,anone,anone,0);
buildaddr(eaimmed,immed,anone,anone,0);
buildaddr(eadefer,defer,anone,anone,0);
buildaddr(eaincr,incr,anone,anone,0);
buildaddr(eapop,incr,sp,anone,0);
buildaddr(eapush,decr,sp,anone,0);
buildaddr(ealimm,labimmed,anone,anone,0);
buildaddr(earel,relative,anone,anone,0);
buildaddr(ealab,labelled,anone,anone,0);
(*RM*) buildaddr(eapset,pimmed,anone,anone,0);
buildaddr(eabased,based,anone,anone,0);
buildaddr(ealong,limmed,anone,anone,0);
FOR r := dnone TO a7 DO regtypeÆrÅ := notatyp;
r := d0;
FOR i:= 0 TO ndregs DO BEGIN dregsÆiÅ := r;
r := succ(r)
END;
r := a0;
FOR i:= 0 TO naregs DO BEGIN aregsÆiÅ := r;
r := succ(r)
END;
machcode := ' ';
machindex := 1;
hexdata := '0123456789ABCDEF';
sasgn(exproc,12288); (* HEX 3000 *)
FOR c := chr(0) TO chr(127) DO asciiÆcÅ := 32; (*BLANK*)
asciiÆ'a'Å:=97; asciiÆ'b'Å:=98; asciiÆ'c'Å:=99; asciiÆ'd'Å:=100;
asciiÆ'e'Å:=101;asciiÆ'f'Å:=102;asciiÆ'g'Å:=103;asciiÆ'h'Å:=104;
asciiÆ'i'Å:=105;asciiÆ'j'Å:=106;asciiÆ'k'Å:=107;asciiÆ'l'Å:=108;
asciiÆ'm'Å:=109;asciiÆ'n'Å:=110;asciiÆ'o'Å:=111;asciiÆ'p'Å:=112;
asciiÆ'q'Å:=113;asciiÆ'r'Å:=114;asciiÆ's'Å:=115;asciiÆ't'Å:=116;
asciiÆ'u'Å:=117;asciiÆ'v'Å:=118;asciiÆ'w'Å:=119;asciiÆ'x'Å:=120;
asciiÆ'y'Å:=121;asciiÆ'z'Å:=122;
asciiÆ'A'Å:=65; asciiÆ'B'Å:=66; asciiÆ'C'Å:=67; asciiÆ'D'Å:=68;
asciiÆ'E'Å:=69; asciiÆ'F'Å:=70; asciiÆ'G'Å:=71; asciiÆ'H'Å:=72;
asciiÆ'I'Å:=73; asciiÆ'J'Å:=74; asciiÆ'K'Å:=75; asciiÆ'L'Å:=76;;
asciiÆ'M'Å:=77; asciiÆ'N'Å:=78; asciiÆ'O'Å:=79; asciiÆ'P'Å:=80;
asciiÆ'Q'Å:=81; asciiÆ'R'Å:=82; asciiÆ'S'Å:=83; asciiÆ'T'Å:=84;
asciiÆ'U'Å:=85; asciiÆ'V'Å:=86; asciiÆ'W'Å:=87; asciiÆ'X'Å:=88;
asciiÆ'Y'Å:=89; asciiÆ'Z'Å:=90;
asciiÆ'0'Å:=48; asciiÆ'1'Å:=49; asciiÆ'2'Å:=50; asciiÆ'3'Å:=51;
asciiÆ'4'Å:=52; asciiÆ'5'Å:=53; asciiÆ'6'Å:=54; asciiÆ'7'Å:=55;
asciiÆ'8'Å:=56; asciiÆ'9'Å:=57;
asciiÆ' 'Å:=32; asciiÆ'*'Å:=42; asciiÆ'>'Å:=62;
asciiÆ'!'Å:=33; asciiÆ'+'Å:=43; asciiÆ'?'Å:=63;
asciiÆ'"'Å:=34; asciiÆ','Å:=44; asciiÆ'^'Å:=64;
asciiÆ'#'Å:=35; asciiÆ'-'Å:=45;
asciiÆ'$'Å:=36; asciiÆ'.'Å:=46; asciiÆ'Ø'Å:=92;
asciiÆ'%'Å:=37; asciiÆ'/'Å:=47;
asciiÆ'&'Å:=38; asciiÆ':'Å:=58; asciiÆ'!'Å:=94;
asciiÆ''''Å:=39;asciiÆ';'Å:=59;
asciiÆ'('Å:=40; asciiÆ'<'Å:=60;
asciiÆ')'Å:=41; asciiÆ'='Å:=61;
asciiÆ'Æ'Å:=91; asciiÆ'Å'Å:=93;
asciiÆ'_'Å:=95; asciiÆ'æ'Å:=123; asciiÆ'å'Å:=125;
asciiÆ'`'Å:=96; asciiÆ'ø'Å:=124; asciiÆ'^'Å:=126;
rtÆxcvbÅ := 4228; rtÆxafiÅ := 4112; rtÆxcloÅ := 4116;
rtÆxdisÅ := 4104; rtÆxeofÅ := 4120; rtÆxeolÅ := 4124;
rtÆxequÅ := 4268; rtÆxexiÅ := 4096; rtÆxgeqÅ := 4288;
rtÆxendÅ := 4096;
rtÆxgetÅ := 4128; rtÆxgrtÅ := 4284; rtÆxifdÅ := 4132;
rtÆxindÅ := 4264; rtÆxleqÅ := 4280; rtÆxlesÅ := 4276;
rtÆxlodÅ := 4264; rtÆxneqÅ := 4272; rtÆxnewÅ := 4108;
rtÆxpagÅ := 4136; rtÆxpeeÅ := 4140; rtÆxpokÅ := 4144;
rtÆxposÅ := 4148; rtÆxputÅ := 4152; rtÆxrdbÅ := 4176;
rtÆxrdcÅ := 4180; rtÆxrdiÅ := 4184; rtÆxrdsÅ := 4188;
rtÆxrdvÅ := 4212; rtÆxrlnÅ := 4156; rtÆxrstÅ := 4160;
rtÆxrwtÅ := 4164; rtÆxsconÅ:= 4232; rtÆxscopÅ:= 4236;
rtÆxsdelÅ:= 4240; rtÆxseeÅ := 4168; rtÆxsinsÅ := 4244;
rtÆxslenÅ:= 4248; rtÆxsposÅ:= 4252; rtÆxstoÅ := 4260;
rtÆxstpÅ := 4100; rtÆxstrÅ := 4256; rtÆxwlnÅ := 4172;
rtÆxwrbÅ := 4192; rtÆxwrcÅ := 4196; rtÆxwriÅ := 4200;
rtÆxwrsÅ := 4204; rtÆxwrvÅ := 4208; rtÆxcvtÅ := 4220;
rtÆxcvtsuÅ := 4216; rtÆxcvtusÅ := 4224; rtÆxldcÅ := 4292;
rtÆxstrvÅ := 4296; rtÆxstovÅ := 4300; rtÆxindvÅ := 4304;
rtÆxlodvÅ := 4304; rtÆxequvÅ := 4308; rtÆxneqvÅ := 4312;
rtÆxlesvÅ := 4316; rtÆxleqvÅ := 4320; rtÆxgrtvÅ := 4324;
rtÆxgeqvÅ := 4328; rtÆxldcvÅ := 4332; rtÆxstcÅ := 4336;
rtÆxmpÅ := 4340; rtÆxdvÅ := 4344; rtÆxmodÅ := 4348;
rtÆxrlsÅ := 4148; rtÆxmrkÅ := 4144; rtÆxrdhÅ := 4528;
rtÆxrdjÅ := 4532; rtÆxwrhÅ := 4520; rtÆxwrjÅ := 4524;
END; (*INIT*)
(*-------------------------------------------------------------------------
SUMMARY PROCEDURE
-------------------------------------------------------------------------*)
PROCEDURE summarize;
BEGIN writeln(listing,'*D REGISTERS: ',dalloccnt,' ALLOCATIONS, REQUIRING ',
dpushcnt,' PUSHES');
writeln(listing,'* AND ', dpopcnt,' POPS');
writeln(listing,'*A REGISTERS: ',aalloccnt,' ALLOCATIONS, REQUIRING ',
apushcnt,' PUSHES');
writeln(listing,'* AND ', apopcnt,' POPS');
writeln(listing,'*');
write(listing,'*TOTAL OF ');
ltemp := pc;
lsb(ltemp,genstart);
plint(listing,ltemp);
writeln(listing,' BYTES GENERATED.');
write(output,' CODE GENERATOR PRODUCED ');
plint(output,ltemp);
writeln(output,' BYTES OF CODE.');
writeln(output,' LABELS USED:',toplabel:4);
IF errorwr THEN writeln(output,' ***** ERROR(S) DETECTED *****')
ELSE writeln(output,' NO ERRORS DETECTED.');
writeln(output,'STACKPTR = ',stkptr:5);
page(listing)
END;
(*-------------------------------------------------------------------------
MAIN PROGRAM
-------------------------------------------------------------------------*)
BEGIN
rewrite(listing);
writeln(listing,'* M68000 PASCAL COMPILER PHASE TWO VERSION 1.10 08/07/80 ');
reset(pcode);
rewrite(object);
writeln(output,' M68000 PASCAL COMPILER PHASE TWO VERSION 1.10');
writeln(output,' COPYRIGHTED 1980 BY MOTOROLA, INC.');
writeln(listing,' ');
init;
getheader;
IF linebufÆ3Å = '2' THEN
REPEAT
scan;
(*WITH CURRI^ DO
WRITELN(LISTING,'* ',MNÆOPCODEÅ,ORD(OPTYPE),OPAND1,OPAND2,OPAND3);*)
IF flÆcurri^.opcodeÅ THEN flush;
UNTIL curri^.optype = endop;
summarize;
END.
▶EOF◀