|
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: 192000 (0x2ee00) Types: TextFile Names: »mpasc1«
└─⟦00964e8f7⟧ Bits:30007478 RC8000 Dump tape fra HCØ. └─⟦b2ec5d50f⟧ └─⟦this⟧ »mpasc1«
(*$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 *) 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; (*EXTERNAL SYMBOL DEFINITION LIST*) REFERENCE: ADDRESS; NEXT: @ESD END; EAMODE = (NONE,DDIRECT,ADIRECT,DEFER,INCR,DECR, (*RM*) BASED,INDEX, PCINDEX, STSHORT, RELATIVE,EXTERNAL,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: FILE OF CHAR; PCODE: FILE OF CHAR; OBJECT: FILE OF CHAR; 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; (*RM*) BEGIN (*RM*) WITH INSTR@ DO BEGIN (*RM*) FOR I := 1 TO 8 DO BEGIN (*RM*) WRITE(LISTING,OPSET@.SETV(. K + I .):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*) EXTERNAL: 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; (* EXTERNAL *) 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; EXTERNAL: 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; EXTERNAL: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 = EXTERNAL 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 EXTERNAL: 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◀