DataMuseum.dk

Presents historical artifacts from the history of:

RC4000/8000/9000

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about RC4000/8000/9000

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download

⟦fa68ba6bd⟧ TextFile

    Length: 192000 (0x2ee00)
    Types: TextFile
    Names: »mpasc1«

Derivation

└─⟦00964e8f7⟧ Bits:30007478 RC8000 Dump tape fra HCØ.
    └─⟦b2ec5d50f⟧ 
        └─⟦this⟧ »mpasc1« 

TextFile

(*$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◀