head     56.3;
access   paws bayes jws quist brad dew jwh;
symbols  ;
locks    ; strict;
comment  @# @;


56.3
date     93.01.27.13.35.21;  author jwh;  state Exp;
branches ;
next     56.2;

56.2
date     93.01.27.12.11.30;  author jwh;  state Exp;
branches ;
next     56.1;

56.1
date     91.11.05.09.25.27;  author jwh;  state Exp;
branches ;
next     55.1;

55.1
date     91.08.25.10.02.45;  author jwh;  state Exp;
branches ;
next     54.1;

54.1
date     91.03.18.15.12.51;  author jwh;  state Exp;
branches ;
next     53.1;

53.1
date     91.03.11.19.13.49;  author jwh;  state Exp;
branches ;
next     52.1;

52.1
date     91.02.19.08.58.58;  author jwh;  state Exp;
branches ;
next     51.1;

51.1
date     91.01.30.15.57.54;  author jwh;  state Exp;
branches ;
next     50.1;

50.1
date     90.10.29.16.10.46;  author jwh;  state Exp;
branches ;
next     49.1;

49.1
date     90.08.14.14.00.00;  author jwh;  state Exp;
branches ;
next     48.1;

48.1
date     90.07.26.11.05.26;  author jwh;  state Exp;
branches ;
next     47.1;

47.1
date     90.05.14.10.39.35;  author dew;  state Exp;
branches ;
next     46.1;

46.1
date     90.05.07.08.29.19;  author jwh;  state Exp;
branches ;
next     45.1;

45.1
date     90.04.19.15.36.21;  author jwh;  state Exp;
branches ;
next     44.1;

44.1
date     90.04.01.21.54.01;  author jwh;  state Exp;
branches ;
next     43.1;

43.1
date     90.03.20.13.43.55;  author jwh;  state Exp;
branches ;
next     42.1;

42.1
date     90.01.23.17.29.16;  author jwh;  state Exp;
branches ;
next     41.4;

41.4
date     90.01.05.14.52.53;  author jwh;  state Exp;
branches ;
next     41.3;

41.3
date     90.01.05.10.03.45;  author jwh;  state Exp;
branches ;
next     41.2;

41.2
date     89.12.26.11.44.11;  author jwh;  state Exp;
branches ;
next     41.1;

41.1
date     89.12.22.11.11.51;  author jwh;  state Exp;
branches ;
next     40.3;

40.3
date     89.12.21.15.27.04;  author jwh;  state Exp;
branches ;
next     40.2;

40.2
date     89.11.21.10.53.41;  author jwh;  state Exp;
branches ;
next     40.1;

40.1
date     89.09.29.11.35.00;  author jwh;  state Exp;
branches ;
next     39.1;

39.1
date     89.09.26.16.20.25;  author dew;  state Exp;
branches ;
next     38.1;

38.1
date     89.08.29.11.10.25;  author jwh;  state Exp;
branches ;
next     37.1;

37.1
date     89.05.12.11.23.18;  author dew;  state Exp;
branches ;
next     36.1;

36.1
date     89.02.06.10.02.24;  author dew;  state Exp;
branches ;
next     35.1;

35.1
date     89.02.02.13.11.58;  author dew;  state Exp;
branches ;
next     34.1;

34.1
date     89.01.23.15.48.03;  author jwh;  state Exp;
branches ;
next     33.1;

33.1
date     89.01.16.11.24.30;  author dew;  state Exp;
branches ;
next     32.1;

32.1
date     89.01.10.11.29.09;  author bayes;  state Exp;
branches ;
next     31.1;

31.1
date     88.12.14.17.50.04;  author bayes;  state Exp;
branches ;
next     30.1;

30.1
date     88.12.09.13.28.31;  author dew;  state Exp;
branches ;
next     29.1;

29.1
date     88.10.31.15.12.47;  author bayes;  state Exp;
branches ;
next     28.1;

28.1
date     88.10.06.10.43.28;  author dew;  state Exp;
branches ;
next     27.1;

27.1
date     88.09.29.11.05.02;  author bayes;  state Exp;
branches ;
next     26.1;

26.1
date     88.09.28.12.17.21;  author bayes;  state Exp;
branches ;
next     25.1;

25.1
date     88.03.02.08.58.37;  author bayes;  state Exp;
branches ;
next     24.1;

24.1
date     87.08.31.08.57.25;  author jws;  state Exp;
branches ;
next     23.1;

23.1
date     87.08.26.09.34.25;  author bayes;  state Exp;
branches ;
next     22.1;

22.1
date     87.08.17.10.11.03;  author bayes;  state Exp;
branches ;
next     21.1;

21.1
date     87.08.12.13.00.35;  author bayes;  state Exp;
branches ;
next     20.1;

20.1
date     87.07.30.10.10.56;  author bayes;  state Exp;
branches ;
next     19.1;

19.1
date     87.06.01.07.32.10;  author jws;  state Exp;
branches ;
next     18.1;

18.1
date     87.05.20.14.24.04;  author bayes;  state Exp;
branches ;
next     17.1;

17.1
date     87.04.30.09.40.28;  author jws;  state Exp;
branches ;
next     16.1;

16.1
date     87.04.26.14.57.37;  author jws;  state Exp;
branches ;
next     15.1;

15.1
date     87.04.13.08.20.10;  author jws;  state Exp;
branches ;
next     14.1;

14.1
date     87.04.01.14.04.35;  author jws;  state Exp;
branches ;
next     13.1;

13.1
date     87.02.28.17.49.48;  author jws;  state Exp;
branches ;
next     12.1;

12.1
date     87.02.02.12.34.27;  author jws;  state Exp;
branches ;
next     11.1;

11.1
date     87.01.19.09.00.50;  author jws;  state Exp;
branches ;
next     10.1;

10.1
date     86.12.24.10.04.09;  author jws;  state Exp;
branches ;
next     9.1;

9.1
date     86.12.12.13.21.21;  author bayes;  state Exp;
branches ;
next     8.1;

8.1
date     86.11.27.11.02.26;  author jws;  state Exp;
branches ;
next     7.2;

7.2
date     86.11.25.14.47.27;  author jws;  state Exp;
branches ;
next     7.1;

7.1
date     86.11.20.12.47.42;  author hal;  state Exp;
branches ;
next     6.1;

6.1
date     86.11.04.16.42.53;  author paws;  state Exp;
branches ;
next     5.1;

5.1
date     86.10.28.14.03.00;  author hal;  state Exp;
branches ;
next     4.1;

4.1
date     86.09.30.18.27.48;  author hal;  state Exp;
branches ;
next     3.1;

3.1
date     86.09.01.11.14.56;  author hal;  state Exp;
branches ;
next     2.2;

2.2
date     86.08.26.11.19.27;  author geli;  state Exp;
branches ;
next     2.1;

2.1
date     86.07.30.14.04.08;  author hal;  state Exp;
branches ;
next     1.1;

1.1
date     86.06.30.12.57.03;  author danm;  state tmp;
branches ;
next     ;


desc
@Base file for PWS 3.2 release.

@


56.3
log
@
pws2rcs automatic delta on Wed Jan 27 13:14:25 MST 1993
@
text
@CONST BADOPS=101; OPSOK=100;

PROCEDURE PASS2; { THIS PROCEDURE DOES ALL THE PASS 2 PROCESSING. }
VAR SP:STREF;  { SCRATCH VAR FOR SYMTABLE ACCESS }

PROCEDURE PASS2STUFF; { THIS DOES PASS 2 INSTRUCTION PROCESSING }
VAR TOP: OPERAND;  { SCRATCH VAR FOR OPERANDS }

PROCEDURE NEWTEXTREC; { DOES NECESSARY STUFF WHEN GET NEW ORG }
VAR I,  SAVEBLOCK: SHORTINT;

BEGIN
REFCOPY;
SAVEBLOCK:=OBJCTR;
if object then begin
  I:=BLOCKREAD(OBJFILE,PUNCHBLK,1,1);
  IF I<>1  THEN ERROR(errcread);
end;
PUNCHLC:=TEXTINFO;
IF PUNCHLC+22>511 THEN ERROR(ERRDIROVF);
PUNCHDWORD(TEXTSTART);
PUNCHDWORD(TEXTSIZE);
PUNCHDWORD(REFSTART);
PUNCHDWORD(REFSIZE);
IF PCMODE=REL THEN GV.PRIMARYTYPE:=RELOCATABLE ELSE
  GV.PRIMARYTYPE:=ABSOLUTE;
GV.DATASIZE:=SINT;
GV.PATCHABLE:=FALSE;
GV.VALUEEXTEND:=TRUE;
GV.LONGOFFSET:=FALSE;
GV.SHORT:=6;
PUNCHGVR(GV);
PUNCHDWORD(ORIGIN);
if object then begin
  I:=BLOCKWRITE(OBJFILE, PUNCHBLK,1,1);
  IF I<>1  THEN ERROR(errwrite);
end;
TEXTINFO:=PUNCHLC;
OBJCTR:=SAVEBLOCK;
TEXTSTART:=OBJCTR-1;
PUNCHLC:=0;
{****************** Not needed!!!  (BAR)
if object then begin
  I:=BLOCKREAD(OBJFILE,PUNCHBLK,1,OBJCTR);
  IF I<>1  THEN ERROR(errcread);
end;
***************************************}
TEXTRECORDS:=TEXTRECORDS+1;
END;


PROCEDURE NEWCODESEG;
BEGIN
  TEXTSIZE:=ENDOFCODE-ORIGIN;
  NEWTEXTREC;
  ORIGIN:=LOCCTR.LONGINT;
  if odd(origin) then error(erroddorg);
  CONTIGUOUS:=TRUE;
END;


PROCEDURE REFOFFSET;  {CALCULATES OFFSETS FOR REF RECORDS}
BEGIN
  IF FIRSTREF THEN BEGIN
    LASTREFLOC:=REFLOC;
    REFOFF:=REFLOC-ORIGIN;
    FIRSTREF:=FALSE;
  END
  ELSE BEGIN
    REFOFF:=REFLOC-LASTREFLOC;
    LASTREFLOC:=REFLOC;
  END;
  IF REFOFF<256 THEN BEGIN
    REFFILE^.INFO.LONGOFFSET:=FALSE;
    REFFILE^.INFO.SHORT:=REFOFF;
  END
  ELSE BEGIN
    REFFILE^.INFO.LONGOFFSET:=TRUE;
    REFFILE^.INFO.LONG:=REFOFF;
  END;
END;


PROCEDURE DOLINKXTREF(OPER:OPERAND;BDISP:SHORTINT; LINKPATCH:BOOLEAN;
			  VAR EXWORDADDR: WORD32);
VAR
  OD_DISP: INTEGER;

  PROCEDURE NEWREFFILE;
  BEGIN
  TRY
    NEW(REFFILE)
  RECOVER
    BEGIN
    if escapecode=-2 then
      begin
      WRITELN(LP,'MEMORY OVERFLOW!');
      LPCHECK;           { 3/2/84 }
      IF LISTNAME<>'CONSOLE:' THEN WRITELN('MEMORY OVERFLOW!');
      ESCAPE(-1);
      end
    else escape(escapecode);
    END;
  END;

  PROCEDURE PUTREFFILE;
  BEGIN
  REFLOC:=LOCCTR.LONGINT+BDISP;
  REFOFFSET;
  IF REFHEAD=NIL
    THEN REFHEAD:=REFFILE
    ELSE REFTAIL^.REFNEXT:=REFFILE;
  REFTAIL:=REFFILE;
  REFFILE^.REFNEXT:=NIL;
  REFCTR:=REFCTR+1;
  END;

BEGIN
IF ((OPER.MODE=6) OR ((OPER.MODE=7) AND (OPER.REG=3))) AND
   OPER.FULL_FORMAT THEN
  BDISP:=BDISP+2-1; (* SPACE FOR EXTENSION WORD *)
IF OPER.VALUE.EXPREFS <> NIL THEN
  (******************** THERE IS AN EXTERNAL REFERENCE *)
  BEGIN
  NEWREFFILE;
  REFFILE^.EXTSTUFF2.LAST:=FALSE;
  REFFILE^.EXTSTUFF.ADR:=OPER.VALUE.EXPREFS^.SYMPT^.SVALUE.LOHALF;
  REFFILE^.INFO.VALUEEXTEND:=FALSE;

  if ((oper.mode=6) AND (NOT OPER.FULL_FORMAT)) or
     ((oper.mode=7) and (oper.reg=4) and (size=1)) or
     ((oper.mode=7) and (oper.reg=3) AND (NOT OPER.FULL_FORMAT)) then
    begin
    if not(fitsin8(oper.value.offset)) then
      begin
      reffile^.info.valueextend:=true;
      exwordaddr:=zero32;
      code.byt[bdisp+1]:=0;
      end
    end
$if fpimmed$
	      (* ??? may need larger immed. opd handling *)
$end$
   else if not((oper.mode=7) and (oper.reg=4) and (size=4)) then
     if not(fitsin16(oper.value.offset)) AND (OPER.SIZE=2) then
       begin
       reffile^.info.valueextend:=true;
       exwordaddr:=zero32;
       code.int[bdisp div 2 + 1]:=0;
       end
     ELSE IF ((OPER.MODE=6) OR ((OPER.MODE=7) AND (OPER.REG=3))) AND
	     OPER.FULL_FORMAT AND
	     (OPER.BD_SIZE=S_WORD) AND
	     NOT(FITSIN16(OPER.VALUE.OFFSET)) THEN
       BEGIN
       REFFILE^.INFO.VALUEEXTEND:=TRUE;
       EXWORDADDR:=ZERO32;
       CODE.INT[BDISP DIV 2 + 1]:=0;
       END;



  CASE OPER.MODE OF
  0,1,2,3,4: BEGIN  END;
  5: BEGIN
    REFFILE^.INFO.PRIMARYTYPE:=GENERAL;
    REFFILE^.INFO.DATASIZE:=SWORD;
    REFFILE^.INFO.PATCHABLE:=FALSE;
    IF OPER.VALUE.EXPREFS^.MINUS
      THEN REFFILE^.EXTSTUFF.OP:=SUBIT
      ELSE REFFILE^.EXTSTUFF.OP:=ADDIT;
    END;

  6: BEGIN (* SAME AS MODE=7, REG=3 *)
    REFFILE^.INFO.PRIMARYTYPE:=GENERAL;
    REFFILE^.INFO.PATCHABLE:=FALSE;
    IF OPER.FULL_FORMAT THEN
      BEGIN
      IF OPER.BD_SIZE=S_WORD (* CAN'T HAVE S_NULL OR S_RES WITH AN EXT. REF. *)
	THEN REFFILE^.INFO.DATASIZE:=SWORD
	ELSE REFFILE^.INFO.DATASIZE:=SINT
      END
    ELSE
      REFFILE^.INFO.DATASIZE:=SBYTE;
    IF OPER.VALUE.EXPREFS^.MINUS
      THEN REFFILE^.EXTSTUFF.OP:=SUBIT
      ELSE REFFILE^.EXTSTUFF.OP:=ADDIT;
    IF OPER.VALUE.EXPREFS^.SYMPT^.SKIND=RELATIVE THEN
      BEGIN
      REFFILE^.EXTSTUFF2.OP:=SUBIT;
      REFFILE^.EXTSTUFF2.ADR:=0;
      REFFILE^.EXTSTUFF2.LAST:=TRUE;
      END;
    END;

  7:
    CASE OPER.REG OF
      0,1: BEGIN
	REFFILE^.INFO.PRIMARYTYPE:=GENERAL;
	REFFILE^.INFO.PATCHABLE:=FALSE;
	IF OPER.REG=0
	  THEN REFFILE^.INFO.DATASIZE:=SWORD
	  ELSE REFFILE^.INFO.DATASIZE:=SINT;
	IF ((OPER.VALUE.BASE=RELATIVE) AND
	    (OPER.VALUE.EXPREFS^.SYMPT^.SKIND=ABSOLUT)) OR
	   ((OPER.VALUE.BASE=ABSOLUT) AND
	    (OPER.VALUE.EXPREFS^.SYMPT^.SKIND=RELATIVE)) THEN
	  BEGIN
	  IF    (OPER.VALUE.BASE=ABSOLUT) AND
	     NOT(OPER.VALUE.EXPREFS^.MINUS)
	    THEN REFFILE^.EXTSTUFF2.OP:=SUBIT
	    ELSE REFFILE^.EXTSTUFF2.OP:=ADDIT;
	  REFFILE^.EXTSTUFF2.ADR:=0;
	  REFFILE^.EXTSTUFF2.LAST:=TRUE;
	  END;
	IF OPER.VALUE.EXPREFS^.MINUS
	  THEN REFFILE^.EXTSTUFF.OP:=SUBIT
	  ELSE REFFILE^.EXTSTUFF.OP:=ADDIT;
	END;

      2: BEGIN                  {PC + 16 BIT}
	REFFILE^.INFO.PRIMARYTYPE:=GENERAL;
	REFFILE^.INFO.PATCHABLE:=LINKPATCH;
	IF OPER.SIZE=2
	  THEN REFFILE^.INFO.DATASIZE:=SWORD
	  ELSE REFFILE^.INFO.DATASIZE:=SINT; (* MUST BE SIZE=4 *)
	IF OPER.VALUE.EXPREFS^.MINUS
	  THEN REFFILE^.EXTSTUFF.OP:=SUBIT
	  ELSE REFFILE^.EXTSTUFF.OP:=ADDIT;
	IF (OPER.VALUE.BASE=RELATIVE) THEN
	  IF (OPER.VALUE.EXPREFS^.SYMPT^.SKIND=RELATIVE) AND
	     (PCMODE=REL) THEN
	    BEGIN
	    REFFILE^.EXTSTUFF2.OP:=SUBIT;
	    REFFILE^.EXTSTUFF2.ADR:=0;
	    REFFILE^.EXTSTUFF2.LAST:=TRUE;
	    END
	  ELSE
	ELSE IF PCMODE=REL THEN
	  BEGIN
	 { ABSOLUTE TARGET -- KLUGE FOR BRANCH }
	  REFFILE^.EXTSTUFF2.OP:=SUBIT;
	  REFFILE^.EXTSTUFF2.ADR:=0;
	  REFFILE^.EXTSTUFF2.LAST:=TRUE;
	  END;
	END;

      3: BEGIN (* SAME AS MODE=6 *) {PC + 8 BIT}
	REFFILE^.INFO.PRIMARYTYPE:=GENERAL;
	REFFILE^.INFO.PATCHABLE:=false;
	IF OPER.FULL_FORMAT THEN
	  BEGIN
	  IF OPER.BD_SIZE=S_WORD (* CAN'T HAVE S_NULL OR S_RES WITH AN EXT. REF. *)
	    THEN REFFILE^.INFO.DATASIZE:=SWORD
	    ELSE REFFILE^.INFO.DATASIZE:=SINT
	  END
	ELSE
	  REFFILE^.INFO.DATASIZE:=SBYTE;
	IF OPER.VALUE.EXPREFS^.MINUS
	  THEN REFFILE^.EXTSTUFF.OP:=SUBIT
	  ELSE REFFILE^.EXTSTUFF.OP:=ADDIT;
	IF OPER.VALUE.EXPREFS^.SYMPT^.SKIND=RELATIVE THEN
	  BEGIN
	  REFFILE^.EXTSTUFF2.OP:=SUBIT;
	  REFFILE^.EXTSTUFF2.ADR:=0;
	  REFFILE^.EXTSTUFF2.LAST:=TRUE;
	  END;
	END;

      4: BEGIN
$if mc68881$
	     (* need to handle larger immed. opds ??? *)
$end$
	REFFILE^.INFO.PRIMARYTYPE:=GENERAL;
	REFFILE^.INFO.PATCHABLE:=FALSE;
	CASE SIZE OF
	  1: REFFILE^.INFO.DATASIZE:=SBYTE;
	  2: REFFILE^.INFO.DATASIZE:=SWORD;
	  4: REFFILE^.INFO.DATASIZE:=SINT;
	  END;
	IF ((OPER.VALUE.BASE=RELATIVE) AND
	    (OPER.VALUE.EXPREFS^.SYMPT^.SKIND=ABSOLUT)) OR
	   ((OPER.VALUE.BASE=ABSOLUT) AND
	    (OPER.VALUE.EXPREFS^.SYMPT^.SKIND=RELATIVE)) THEN
	  BEGIN
	  IF    (OPER.VALUE.BASE=ABSOLUT) AND
	     NOT(OPER.VALUE.EXPREFS^.MINUS)
	    THEN REFFILE^.EXTSTUFF2.OP:=SUBIT
	    ELSE REFFILE^.EXTSTUFF2.OP:=ADDIT;
	  REFFILE^.EXTSTUFF2.ADR:=0;
	  REFFILE^.EXTSTUFF2.LAST:=TRUE;
	  END;
	IF OPER.VALUE.EXPREFS^.MINUS
	  THEN REFFILE^.EXTSTUFF.OP:=SUBIT
	  ELSE REFFILE^.EXTSTUFF.OP:=ADDIT;
	END;

      5,6,7: BEGIN END;

      END; {CASE}
    END; {CASE}

  REFFILE^.EXTSTUFF.LAST:=NOT REFFILE^.EXTSTUFF2.LAST;
  IF REFFILE^.INFO.VALUEEXTEND
    THEN REFFILE^.VALUE:=OPER.VALUE.OFFSET
    ELSE REFFILE^.VALUE:=ZERO32;
  PUTREFFILE;
  END (* OPER.VALUE.EXPREFS <> NIL *)
ELSE
$if mc68881$
		    (* need to handle larger immed. opds ??? *)
$end$
IF (OPER.VALUE.BASE=RELATIVE) AND
   (OPER.MODE=7) AND
   ((OPER.REG=4) or (oper.reg=0) or (oper.reg=1)) THEN
  (******************** THERE IS A RELATIVE IN ABSOLUTE OR IMMEDIATE *)
  BEGIN
  NEWREFFILE;
  REFFILE^.INFO.PATCHABLE:=FALSE;
  REFFILE^.INFO.PRIMARYTYPE:=RELOCATABLE;
  REFFILE^.INFO.VALUEEXTEND:=FALSE;
  if (oper.reg=4) then
    CASE SIZE OF
      1: REFFILE^.INFO.DATASIZE:=SBYTE;
      2: REFFILE^.INFO.DATASIZE:=SWORD;
      4: REFFILE^.INFO.DATASIZE:=SINT;
$if fpimmed AND FALSE$
      8:
	begin
	reffile^.info.datasize:= sint;  (* this is wrong ??? *)
	reffile^.info.valueextend := true;
	reffile^.value := oper.value.offset;
	end;
$end$
      END (* CASE *) (* if (oper.reg=4) *)
  else if oper.reg=0 then
    reffile^.info.datasize:=sword
  else
    reffile^.info.datasize:=sint;
  PUTREFFILE;
  END
ELSE IF (CURROP.CLASS=7)
$if mc68881$
     or (currop.class=(fpbase+fpbrbase+32))  (* FBcc *)
$end$
     THEN
  BEGIN
  (******************** THIS IS A BRANCH AND NOT EXTERNAL *)
  NEWREFFILE;
  REFFILE^.INFO.PATCHABLE:=LINKPATCH;
  REFFILE^.INFO.PRIMARYTYPE:=GENERAL;
  if not fitsin16(oper.value.offset) AND (SIZE=2) then
    begin
    reffile^.info.valueextend:=true;
    reffile^.value:=oper.value.offset;
    code.int[2]:=0;
    end
  else reffile^.info.valueextend:=false;
  IF SIZE=2
    THEN REFFILE^.INFO.DATASIZE:=SWORD
    ELSE REFFILE^.INFO.DATASIZE:=SINT;
  REFFILE^.EXTSTUFF.ADR:=0;
  if oper.value.base=absolut
    then reffile^.extstuff.op:=subit
    else REFFILE^.EXTSTUFF.OP:=addit;
  REFFILE^.EXTSTUFF.LAST:=TRUE;
  PUTREFFILE;
  END
else if (pcmode=abs) and
	(((oper.mode=7) and ((oper.reg=2) or (oper.reg=3))) OR
	 ( OPER.MODE=6)) and
	(oper.value.base=relative) then
  begin
  (******************** THERE IS A RELATIVE BUT NO EXTERNAL IN INDIRECT *)
  NEWREFFILE;
  reffile^.info.patchable:=linkpatch and (OPER.MODE=7) AND (oper.reg=2);
  reffile^.info.primarytype:=relocatable;
  if (OPER.MODE=7) AND (oper.reg=2) then
    reffile^.info.datasize:=sword
  else
    IF OPER.FULL_FORMAT THEN
      BEGIN
      IF OPER.BD_SIZE=S_WORD (* CAN'T HAVE S_NULL OR S_RES WITH A REF. *)
	THEN REFFILE^.INFO.DATASIZE:=SWORD
	ELSE REFFILE^.INFO.DATASIZE:=SINT
      END
    ELSE
      REFFILE^.INFO.DATASIZE:=SBYTE;
  if (not(fitsin16(oper.value.offset)) and (REFFILE^.INFO.DATASIZE=SWORD)) or
     (not(fitsin8 (oper.value.offset)) and (REFFILE^.INFO.DATASIZE=SBYTE)) then
    begin
    reffile^.info.valueextend:=true;
    if REFFILE^.INFO.DATASIZE=SBYTE then
      code.byt[bdisp+1]:=0
    else
      code.int[bdisp div 2 + 1]:=0;
    reffile^.value:=oper.value.offset;
    exwordaddr:=zero32;
    end
  else
    begin
    reffile^.info.valueextend:=false;
    reffile^.value:=zero32;
    end;
  PUTREFFILE;
  end;
(*************************************************************************)
(* THE PRECEDING CHUNKS ARE ALL EXCLUSIVE; IF ONE IS INVOKED, NONE OF
(* THE OTHERS ARE.  THE FOLLOWING CHUNK IS INDEPENDENT OF THE PRECEDING.
(**)
IF ((OPER.MODE=6) OR ((OPER.MODE=7) AND (OPER.REG=3))) AND
   (OPER.FULL_FORMAT) AND
   (OPER.OD_SIZE>=S_WORD) THEN
  BEGIN
  IF      OPER.BD_SIZE=S_LONG THEN
    BDISP:=BDISP+4
  ELSE IF OPER.BD_SIZE=S_WORD THEN
    BDISP:=BDISP+2;

  IF OPER.OD_VALUE.EXPREFS <> NIL THEN
    (******************** THERE IS AN EXTERNAL REFERENCE *)
    BEGIN
    NEWREFFILE;
    REFFILE^.EXTSTUFF2.LAST:=FALSE;
    REFFILE^.EXTSTUFF.ADR:=OPER.OD_VALUE.EXPREFS^.SYMPT^.SVALUE.LOHALF;
    REFFILE^.INFO.VALUEEXTEND:=FALSE;

    IF (OPER.OD_SIZE=S_WORD) AND
       NOT(FITSIN16(OPER.OD_VALUE.OFFSET)) THEN
      BEGIN
      REFFILE^.INFO.VALUEEXTEND:=TRUE;
      EXWORDADDR:=ZERO32;
      CODE.INT[BDISP DIV 2 + 1]:=0;
      END;

    REFFILE^.INFO.PRIMARYTYPE:=GENERAL;
    REFFILE^.INFO.PATCHABLE:=FALSE;
    IF OPER.OD_SIZE=S_WORD (* CAN'T HAVE S_NULL OR S_RES WITH AN EXT. REF. *)
      THEN REFFILE^.INFO.DATASIZE:=SWORD
      ELSE REFFILE^.INFO.DATASIZE:=SINT;
    IF OPER.OD_VALUE.EXPREFS^.MINUS
      THEN REFFILE^.EXTSTUFF.OP:=SUBIT
      ELSE REFFILE^.EXTSTUFF.OP:=ADDIT;
    IF OPER.OD_VALUE.EXPREFS^.SYMPT^.SKIND=RELATIVE THEN
      BEGIN
      REFFILE^.EXTSTUFF2.OP:=SUBIT;
      REFFILE^.EXTSTUFF2.ADR:=0;
      REFFILE^.EXTSTUFF2.LAST:=TRUE;
      END;

    REFFILE^.EXTSTUFF.LAST:=NOT REFFILE^.EXTSTUFF2.LAST;
    IF REFFILE^.INFO.VALUEEXTEND
      THEN REFFILE^.VALUE:=OPER.OD_VALUE.OFFSET
      ELSE REFFILE^.VALUE:=ZERO32;
    PUTREFFILE;
    END (* OPER.OD_VALUE.EXPREFS <> NIL *)
$IF FALSE$
  ELSE if (pcmode=abs) and
	  (oper.OD_value.base=relative (* THIS CAN'T HAPPEN ANYMORE *)) then
    begin
    (******************** THERE IS A RELATIVE BUT NO EXTERNAL IN INDIRECT *)
    NEWREFFILE;
    reffile^.info.patchable:=FALSE;
    reffile^.info.primarytype:=relocatable;
    IF OPER.OD_SIZE=S_WORD (* CAN'T HAVE S_NULL OR S_RES WITH A REF. *)
      THEN REFFILE^.INFO.DATASIZE:=SWORD
      ELSE REFFILE^.INFO.DATASIZE:=SINT;
    if (not(fitsin16(oper.OD_value.offset)) and (REFFILE^.INFO.DATASIZE=SWORD)) then
      begin
      reffile^.info.valueextend:=true;
      code.int[bdisp div 2 + 1]:=0;
      reffile^.value:=oper.OD_value.offset;
      exwordaddr:=zero32;
      end
    else
      begin
      reffile^.info.valueextend:=false;
      reffile^.value:=zero32;
      end;
    PUTREFFILE;
    end;
$END$
  END;
END; {PROCEDURE DOLINKXTREF}


PROCEDURE PASS2PSEUDOS; { THIS DOES PSEUDO-OPS FOR PASS 2 }

VAR COUNT: SHORTINT;
    SYM, SP: STREF;
    I,COL, LEN, STARTCOL: SHORTINT;
    tlab: lstring;

PROCEDURE CHARSTRING2;
VAR DONE: BOOLEAN;
    BYTECOUNT: SHORTINT;

PROCEDURE OUTPUTCHAR;
BEGIN
  CODELENGTH:=1;
  IF (BYTECOUNT=0) AND (COUNT=0) THEN BEGIN
    LISTINST(1);
    PRINTLINE:='';
  END
  ELSE IF NOT SHORTMODE THEN LISTINST(1);
  if not contiguous then newcodeseg;
  PUNCHBYTE(ORD(LINECOPY[CURCOL]));
  LOCCTR.LONGINT := LOCCTR.LONGINT + 1;
  BYTECOUNT:=BYTECOUNT+1;
END;

BEGIN
  DONE:=FALSE;
  BYTECOUNT:=0;
  REPEAT
    CURCOL:=CURCOL+1;
    IF CURCOL<>LENGTH(LINECOPY) THEN
      IF LINECOPY[CURCOL]=CHR(39) THEN
	IF LINECOPY[CURCOL+1]=CHR(39) THEN BEGIN
	  CURCOL:=CURCOL+1;
	  CODE.BYT[1]:=39;
	  OUTPUTCHAR;
	END
	ELSE DONE:=TRUE
      ELSE BEGIN
	CODE.BYT[1]:=ORD(LINECOPY[CURCOL]);
	OUTPUTCHAR;
      END
    ELSE BEGIN
      ERROR(ERRBADSYNTAX);
      DONE:=TRUE;
    END;
  UNTIL DONE;
  IF (SIZE=2) AND  ODD(LOCCTR.LOHALF)  THEN BEGIN
    LOCCTR.LONGINT := LOCCTR.LONGINT + 1;
    BYTECOUNT:=BYTECOUNT+1;
    if not contiguous then newcodeseg;
    PUNCHBYTE(0);
  END
  ELSE IF SIZE=4 THEN WHILE BYTECOUNT MOD 4 <> 0 DO
	 BEGIN
	   LOCCTR.LONGINT := LOCCTR.LONGINT + 1;
	   if not contiguous then newcodeseg;
	   PUNCHBYTE(0);
	   BYTECOUNT:=BYTECOUNT+1;
	 END;
$if mc68881$
	(* may need larger size handling here ??? *)
$end$
  IF CURCOL<>LENGTH(LINECOPY) THEN CURCOL:=CURCOL+1;
  COUNT := COUNT + BYTECOUNT DIV SIZE;
END;


BEGIN
CASE CURROP.CODE OF

  0: { COMMENT }
    LISTINST(4);


  1: { DC }
     BEGIN
       COUNT:=0; CURCOL:=CURCOL-1;
       OPERAND1.MODE:=7; OPERAND1.REG:=4;
       LINECOPY:=PRINTLINE;
       LINECOPY[0]:=SUCC(LINECOPY[0]);
       LINECOPY[LENGTH(LINECOPY)]:=BLANK;
       REPEAT
	 CURCOL:=CURCOL+1;
	 IF LINE[CURCOL]=CHR(39) THEN CHARSTRING2
	 ELSE BEGIN
	   COUNT:=COUNT+1;
$if fpimmed$
	   if sizesuffix = 'D' then
	     begin
	       if not fpimmedexp( true, evalok, evalue, curcol ) then
		 error( errfpconstneeded );
	     end
	   else
$end$
	   EXPRESS(TRUE, EVALOK, EVALUE, CURCOL);
	   OPERAND1.VALUE:=EVALUE;
	   CODELENGTH:=SIZE;
	   CASE SIZE OF
	     1: BEGIN
		  IF NOT(FITSIN8(EVALUE.OFFSET)) AND ((EVALUE.OFFSET.HIHALF<>0)
		    OR (EVALUE.OFFSET.LOHALF<0) OR (EVALUE.OFFSET.LOHALF>255))
		  and (evalue.exprefs=nil) THEN ERROR(ERRFIELDOFLO);
		  IF NOT CONTIGUOUS THEN NEWCODESEG;
		  CODE.BYT[1]:=EVALUE.OFFSET.BYTE4;
		  DOLINKXTREF(OPERAND1, 0, FALSE, LOCCTB);
		  punchbyte(code.byt[1]);
		END;

	     2: BEGIN
		  IF NOT(FITSIN16(EVALUE.OFFSET)) AND (EVALUE.OFFSET.HIHALF<>0)
		  and (evalue.exprefs=nil) THEN ERROR(ERRFIELDOFLO);
		  CODE.INT[1]:=EVALUE.OFFSET.LOHALF;
		  IF NOT CONTIGUOUS THEN NEWCODESEG;
		  DOLINKXTREF(OPERAND1, 0, FALSE, LOCCTB);
		  PUNCHCODE;
		END;

	     4: BEGIN
		  CODE.INT[1]:=EVALUE.OFFSET.HIHALF;
		  CODE.INT[2]:=EVALUE.OFFSET.LOHALF;
		  IF NOT CONTIGUOUS THEN NEWCODESEG;
		  DOLINKXTREF(OPERAND1, 0, FALSE, LOCCTB);
		  PUNCHCODE;
		END;
$if fpimmed$
	     8: begin
		  with evalue.offset do
		    begin
		      code.int[ 1 ] := fltptwd1;
		      code.int[ 2 ] := fltptwd2;
		      code.int[ 3 ] := fltptwd3;
		      code.int[ 4 ] := fltptwd4;
		      if not contiguous then newcodeseg;
		      dolinkxtref( operand1, 0, false, locctb);
		      punchcode;
		    end;
		end;
	     12: begin
			(* ???   error( errfpinternalerr );  *)
		 end;
$end$
	   END;
	   IF (LENGTH(PRINTLINE)>0) OR NOT(SHORTMODE) THEN LISTINST(1);
	   IF COUNT>0 THEN PRINTLINE:='';
	   LOCCTR.LONGINT := LOCCTR.LONGINT + SIZE;
	 END
       UNTIL LINE[CURCOL]<>',';
       IF LINE[CURCOL]<>' ' THEN ERROR(ERREOLEXP);
     END; {OF DC PROCESSING}

  2: { DS }
     BEGIN
       EXPRESS(TRUE, EVALOK, EVALUE, CURCOL);
       IF LINE[CURCOL]<>BLANK THEN ERROR(ERREOLEXP);
       CODELENGTH:=2;
       CODE.INT[1]:=EVALUE.OFFSET.LOHALF;
       LISTINST(1);  { NORMAL LINE LIST }
       IF (EVALOK=OK1) AND (EVALUE.EXPREFS=NIL) THEN
	 if evalue.base=absolut then begin
	   IF CONTIGUOUS THEN ENDOFCODE:=LOCCTR.LONGINT;
	   LOCCTR.LONGINT:=SIZE*EVALUE.OFFSET.LONGINT
		+LOCCTR.LONGINT;
	   CONTIGUOUS:=FALSE;
	 end
	 else error(errbadbase)
       ELSE
	 begin
	 if (evalue.exprefs <> NIL) then
	   error(errextrefs);
	 if evalok = ok2 then
	   ERROR(ERRBADEXPR);
	 end;
     END;

  3: {END} LISTINST(4);

  4: {MNAME}
     LISTINST(4);

  5: {EQU}
     BEGIN
     tlab:=lab;
     LOOKUPSYMBOL(SYM);
     IF CHECKREGS THEN BEGIN
       CODE.INT[1]:=0;
       CODE.INT[2]:=CHECKREGNO;
     END
     ELSE IF CHECKSPREGS THEN BEGIN
       CODE.INT[1]:=0;
       CODE.INT[2]:=CHECKREGNO;
     END
     ELSE BEGIN
       EXPRESS(TRUE, EVALOK, EVALUE, CURCOL);
       CODE.INT[1]:=EVALUE.OFFSET.HIHALF;
       CODE.INT[2]:=EVALUE.OFFSET.LOHALF;
     END;
     if (tlab<>'') and (sym<>nil) then
       IF (CODE.INT[1]<>SYM^.SVALUE.HIHALF) OR
	  (CODE.INT[2]<>SYM^.SVALUE.LOHALF) THEN ERROR(ERRPHASE);
     CODELENGTH:=4;
     IF LINE[CURCOL]<>' ' THEN ERROR(ERREOLEXP);
     LISTINST(2);
     END;


  6: { SRC }
     LISTINST(4);

  8: {LIST}
     BEGIN
     LISTINST(4);
     LISTING:=TRUE;
     END;

  9: { LLEN }
      BEGIN
	EXPRESS(true, EVALOK, EVALUE, CURCOL);
	IF (EVALUE.EXPREFS<>NIL) OR (EVALOK<>OK1) OR
	   NOT((EVALUE.OFFSET.HIHALF=0) AND
	       (EVALUE.OFFSET.LOHALF>=32) AND
	       (EVALUE.OFFSET.LOHALF<=132)) THEN ERROR(ERRBADEXPR)
	else LLEN:=EVALUE.OFFSET.LOHALF;
	listinst(4);
      END;


  10: { NOLIST, NOL }
     BEGIN
     LISTINST(4);
     LISTING:=FALSE;
     END;

  11: { NOOBJ}
      LISTINST(4);

  12: { NOPAGE }
     BEGIN
      LISTINST(4);
      LINESPERPAGE:=32767;
     END;

  13,15: { ORG, RORG }
      BEGIN
	EXPRESS(true, EVALOK, EVALUE, CURCOL);
	IF (EVALOK=OK1) AND (EVALUE.EXPREFS=NIL)  THEN BEGIN
	  IF CONTIGUOUS THEN BEGIN
	    IF LOCCTR.LONGINT>ORIGIN THEN BEGIN
	      TEXTSIZE:=LOCCTR.LONGINT-ORIGIN;
	      NEWTEXTREC;
	    END
	  END
	  ELSE
	    IF ENDOFCODE > ORIGIN THEN BEGIN
	      TEXTSIZE:=ENDOFCODE-ORIGIN;
	      NEWTEXTREC;
	    END;
	  if pcmode=rel then
	    if locctr.longint > highaddr.longint then highaddr:=locctr;
	  LOCCTR:=EVALUE.OFFSET;
	  ORIGIN:=EVALUE.OFFSET.LONGINT;
	  if odd(origin) then
	     error(erroddorg);
	  CONTIGUOUS:=TRUE;
	  IF SIZE=4 THEN ORGMODE:=LONGFWDS ELSE ORGMODE:=SHORTFWDS;
	  IF CURROP.CODE=13 THEN PCMODE:=ABS ELSE BEGIN
	    PCMODE:=REL;
	    IF LOCCTR.LONGINT < LOWRORG.LONGINT THEN LOWRORG:=LOCCTR;
	  END;
	  IF LINE[CURCOL]<>' ' THEN ERROR(ERREOLEXP);
	END
	else error(errbadexpr);
	LISTINST(3);
      END;

  14: { PAGE }
	if superlist and listing then CURRENTLINE:=LINESPERPAGE+10;

  17: { SPC }
      BEGIN
	EXPRESS(TRUE,EVALOK,EVALUE,CURCOL);
	IF (EVALOK<>NOK) and (evalue.exprefs=nil)
	   and (evalue.base=absolut) THEN
	  BEGIN
	    if line[curcol]<>' ' then begin
	      error(erreolexp);
	      listinst(4);
	    end
	    else begin
	      PRINTLINE:=' ';
	      FOR COUNT:=1 TO EVALUE.OFFSET.LOHALF DO
		  LISTINST(4);
	    end;
	  END
	ELSE BEGIN
	  error(errbadexpr);
	  listinst(4);
	end;
      END;

  18: { TTL }
      BEGIN
	CODELENGTH:=LENGTH(LINE)-CURCOL;
	IF CODELENGTH>60 THEN CODELENGTH:=60;
	TITLE[0]:=CHR(CODELENGTH);
	FOR I:=1 TO CODELENGTH DO TITLE[I]:=LINE[CURCOL+I-1];
      END;

  19: { COM }
      LISTINST(4);

  20: { DEF }
      BEGIN
      TRY
	REPEAT
	  IF NOT(LINE[CURCOL] IN ['A'..'Z','_','@@'])  THEN {leading '_','@@'}
	    ESCAPE(BADOPS);                                {jch 08/26/86}
	  STARTCOL:=CURCOL;
	  REPEAT
	    CURCOL:=CURCOL+1;
	  UNTIL CHTYPE[LINE[CURCOL]]=SPECIAL;
	  LAB:=COPY(LINE, STARTCOL, CURCOL-STARTCOL);
	  LOOKUPSYMBOL(SP);
	  IF SP=NIL THEN BEGIN
	    ERROR(ERRUNDEFSYM);
	    ESCAPE(OPSOK);
	  END;
	  IF SP^.DEFINED<=0 THEN BEGIN ERROR(ERRUNDEFSYM);
	    ESCAPE(OPSOK) END;
	  IF (SP^.EXT) OR (SP^.SEXTPTR<>NIL)  THEN BEGIN
	    ERROR(ERREXTREFS);
	    ESCAPE(OPSOK);
	  END;
	  TRY
	    NEWBYTES(DEFFILE,SIZEOF(DEFREC)-80+LENGTH(LAB))
	  RECOVER BEGIN
	    if escapecode=-2 then begin
	      WRITELN(LP,'MEMORY OVERFLOW!');
	      LPCHECK;           { 3/2/84 }
	      IF LISTNAME<>'CONSOLE:' THEN WRITELN('MEMORY OVERFLOW!');
	      ESCAPE(-1);
	    end else escape(escapecode);
	  END;
	  DEFFILE^.LOCATION:=SP^.SVALUE;
	  IF SP^.EXT AND (SP^.SVALUE.LOHALF=0) AND (SP^.SVALUE.HIHALF=0)
	    THEN DEFFILE^.DEFTYPE:=GLOBAL
	    ELSE IF SP^.SKIND=ABSOLUT THEN DEFFILE^.DEFTYPE:=ABSOLUTE
	    ELSE IF SP^.SKIND=RELATIVE THEN DEFFILE^.DEFTYPE:=RELOCATABLE
	      ELSE ESCAPE(BADOPS);
	  DEFFILE^.IDNAME:=SP^.SNAME;
	  IF DEFHEAD=NIL THEN DEFHEAD:=DEFFILE
	    ELSE DEFTAIL^.DEFNEXT:=DEFFILE;
	  DEFTAIL:=DEFFILE;
	  DEFFILE^.DEFNEXT:=NIL;
	  DEFCTR:=DEFCTR+1;
	  IF LINE[CURCOL]=BLANK THEN ESCAPE(OPSOK);
	  IF LINE[CURCOL]<>COMMA THEN ESCAPE(BADOPS);
	  CURCOL:=CURCOL+1;
	UNTIL FALSE;
      RECOVER
	IF ESCAPECODE=BADOPS THEN ERROR(ERRBADSYNTAX)
	ELSE IF ESCAPECODE<>OPSOK THEN ESCAPE(ESCAPECODE);
	LISTINST(4);
    END;


  21,22: { REFA, REFR } LISTINST(4); { NO PASS 2 ACTION }

  25,26,27,28: { LMODE, SMODE, RMODE, MLOAD }
      LISTINST(4);

  29: { NOSYMS }
      BEGIN
	LISTSYMS:=FALSE;
	LISTINST(4);
      END;

  30: { INCLUDE }
      BEGIN
	LISTINST(4);
	INCLUDEINSTR;
      END;

  31: { SPRINT }
      BEGIN
	SHORTMODE:=TRUE;
	LISTINST(4);
      END;

  32: { LPRINT }
      BEGIN
	SHORTMODE:=FALSE;
	LISTINST(4);
      END;

  33: { START }
      BEGIN
	EXPRESS(TRUE, EVALOK, EVALUE, CURCOL);
	IF (EVALUE.EXPREFS<>NIL) OR (EVALOK<>OK1) THEN BEGIN
	  CODE.INT[1]:=0;
	  CODE.INT[2]:=0;
	END
	ELSE BEGIN
	  CODE.INT[1]:=EVALUE.OFFSET.HIHALF;
	  CODE.INT[2]:=EVALUE.OFFSET.LOHALF;
	  IF LINE[CURCOL]<>' ' THEN ERROR(ERREOLEXP);
	END;
	CODELENGTH:=4;
	LISTINST(2);
      END;

  34: { DECIMAL }
      listinst(4);


END; { OF CASE }
END; { OF PROCEDURE }

PROCEDURE CODEGEN;
VAR I         :SHORTINT;
    LINKPATCH :BOOLEAN;
    EXWORDADDR:WORD32;
    DUMMY: SHORTINT; { KLUDGE FOR COMPILER BUG}
    SAVEREGY, SAVEMODE: 0..7;



PROCEDURE BUILDEA(OPER:OPERAND;CDISP:SHORTINT;VAR EAWORD1:IDXWORD);
VAR
  EADISP: SHORTINT;
BEGIN  {BUILDEA}
CODE.TYPE4.MODE:=OPER.MODE;
CODE.TYPE2.REGY:=OPER.REG;
CASE CODE.TYPE4.MODE OF
  0,1,2,3,4: BEGIN {NO ACTION} END; {DN, AN, (AN), (AN)+, -(AN)}
  5:BEGIN                          {D(AN)}
    CODE.INT[CDISP]:=OPER.VALUE.OFFSET.LOHALF;
    CODELENGTH:=CODELENGTH+2;
    DOLINKXTREF(OPER,CDISP*2-2,LINKPATCH, EXWORDADDR);
    END;
  6:BEGIN                          {D(AN,RI)}
    CODELENGTH:=CODELENGTH+2;

    EAWORD1.DA   :=OPER.INDEXMODE=ADDRS;
    EAWORD1.REGI :=OPER.INDEX;
    EAWORD1.WL   :=OPER.INDEXSIZE=LONG;
    EAWORD1.SCALE:=OPER.INDEXSCALE;
    EAWORD1.FULL :=OPER.FULL_FORMAT;
    IF EAWORD1.FULL THEN
      BEGIN
      EAWORD1.BASE_SUPPRESS :=OPER.BASE_SUPPRESS ;
      EAWORD1.INDEX_SUPPRESS:=OPER.INDEX_SUPPRESS;
      EAWORD1.BD_SIZE       :=OPER.BD_SIZE       ;
      EAWORD1.FILL          :=OPER.FILL          ;
      EAWORD1.POST_INDEXED  :=OPER.POST_INDEXED  ;
      EAWORD1.OD_SIZE       :=OPER.OD_SIZE       ;
      EADISP:=CDISP;
      IF      OPER.BD_SIZE=S_LONG THEN
	BEGIN
	EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.   VALUE.OFFSET.HIHALF;
	EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.   VALUE.OFFSET.LOHALF;
	END
      ELSE IF OPER.BD_SIZE=S_WORD THEN
	BEGIN
	EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.   VALUE.OFFSET.LOHALF;
	END;
      IF      OPER.OD_SIZE=S_LONG THEN
	BEGIN
	EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.OD_VALUE.OFFSET.HIHALF;
	EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.OD_VALUE.OFFSET.LOHALF;
	END
      ELSE IF OPER.OD_SIZE=S_WORD THEN
	BEGIN
	EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.OD_VALUE.OFFSET.LOHALF;
	END;
      CODELENGTH:=CODELENGTH+(EADISP-CDISP)*2;
      END
    ELSE
      EAWORD1.DISP:=OPER.VALUE.OFFSET.BYTE4;

    DOLINKXTREF(OPER,CDISP*2-1,LINKPATCH, EXWORDADDR);
    END;
  7:BEGIN
    CODELENGTH:=CODELENGTH+2;
    CASE CODE.TYPE2.REGY OF
      0:BEGIN
	CODE.INT[CDISP]:=OPER.VALUE.OFFSET.LOHALF; {ABS 16 BIT ADDR.}
	DOLINKXTREF(OPER,CDISP*2-2,LINKPATCH, EXWORDADDR);
	END;
      1:BEGIN                                      {ABS 32 BIT ADDR.}
	CODE.INT[CDISP]:=OPER.VALUE.OFFSET.HIHALF;
	CODE.INT[CDISP+1]:=OPER.VALUE.OFFSET.LOHALF;
	CODELENGTH:=CODELENGTH+2;
	DOLINKXTREF(OPER,CDISP*2-2,LINKPATCH, EXWORDADDR);
	END;
      2:BEGIN                                       {PC + 16 BIT DISP}
	EXWORDADDR.LONGINT := OPER.VALUE.OFFSET.LONGINT +
			      2 - LOCCTR.LONGINT - CDISP*2;
	OPER.VALUE.OFFSET:=EXWORDADDR;
	CODE.INT[CDISP]:=EXWORDADDR.LOHALF;
	DOLINKXTREF(OPER,CDISP*2-2,LINKPATCH, EXWORDADDR);
	IF NOT FITSIN16(EXWORDADDR) THEN ERROR(ERRFIELDOFLO);
	END;
      3:BEGIN                            {PC + INDEX REG + 8 BIT DISP}
	IF OPER.FULL_FORMAT AND OPER.BASE_SUPPRESS THEN
	  EXWORDADDR.LONGINT := OPER.VALUE.OFFSET.LONGINT
	ELSE
	  BEGIN
	  EXWORDADDR.LONGINT := OPER.VALUE.OFFSET.LONGINT +
				2 - LOCCTR.LONGINT - CDISP*2;
	  END;
	OPER.VALUE.OFFSET:=EXWORDADDR;

	EAWORD1.DA   :=OPER.INDEXMODE=ADDRS;
	EAWORD1.REGI :=OPER.INDEX;
	EAWORD1.WL   :=OPER.INDEXSIZE=LONG;
	EAWORD1.SCALE:=OPER.INDEXSCALE;
	EAWORD1.FULL :=OPER.FULL_FORMAT;
	IF EAWORD1.FULL THEN
	  BEGIN
	  EAWORD1.BASE_SUPPRESS :=OPER.BASE_SUPPRESS ;
	  EAWORD1.INDEX_SUPPRESS:=OPER.INDEX_SUPPRESS;
	  EAWORD1.BD_SIZE       :=OPER.BD_SIZE       ;
	  EAWORD1.FILL          :=OPER.FILL          ;
	  EAWORD1.POST_INDEXED  :=OPER.POST_INDEXED  ;
	  EAWORD1.OD_SIZE       :=OPER.OD_SIZE       ;
	  EADISP:=CDISP;
	  IF      OPER.BD_SIZE=S_LONG THEN
	    BEGIN
	    EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.   VALUE.OFFSET.HIHALF;
	    EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.   VALUE.OFFSET.LOHALF;
	    END
	  ELSE IF OPER.BD_SIZE=S_WORD THEN
	    BEGIN
	    EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.   VALUE.OFFSET.LOHALF;
	    END;
	  IF      OPER.OD_SIZE=S_LONG THEN
	    BEGIN
	    EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.OD_VALUE.OFFSET.HIHALF;
	    EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.OD_VALUE.OFFSET.LOHALF;
	    END
	  ELSE IF OPER.OD_SIZE=S_WORD THEN
	    BEGIN
	    EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.OD_VALUE.OFFSET.LOHALF;
	    END;
	  CODELENGTH:=CODELENGTH+(EADISP-CDISP)*2;
	  END
	ELSE
	  EAWORD1.DISP:=OPER.VALUE.OFFSET.BYTE4;

	DOLINKXTREF(OPER,CDISP*2-1,LINKPATCH, EXWORDADDR);
	IF (NOT OPER.FULL_FORMAT AND NOT FITSIN8(EXWORDADDR)) OR
	   (    OPER.FULL_FORMAT AND NOT FITSIN16(EXWORDADDR) AND
	       (OPER.BD_SIZE=S_WORD)) THEN
	  ERROR(ERRFIELDOFLO);
	END;
      4:{IMMEDIATE DATA}
	BEGIN
$if mc68881$
		      (* need to handle larger immed. opds ??? *)
$end$
	IF      SIZE = 1 THEN
	  CODE.INT[CDISP]:=OPER.VALUE.OFFSET.BYTE4
	ELSE IF SIZE = 2 THEN
	    CODE.INT[CDISP]:=OPER.VALUE.OFFSET.LOHALF
$if fpimmed$
	ELSE if size = 4 then
$end$
	  BEGIN
	  CODE.INT[CDISP]:=OPER.VALUE.OFFSET.HIHALF;
	  CODE.INT[CDISP+1]:=OPER.VALUE.OFFSET.LOHALF;
	  CODELENGTH:=CODELENGTH+2;
$if fpimmed$
	  end
	else if size = 8 then
	  with oper.value.offset do
	    begin
	    code.int[cdisp] := fltptwd1;
	    code.int[cdisp+1] := fltptwd2;
	    code.int[cdisp+2] := fltptwd3;
	    code.int[cdisp+3] := fltptwd4;
	    codelength := codelength + 6;
	    end
	else
	  begin
	    (*  ???  error( errfpinternalerr );  *)
$end$
	  END;
	DOLINKXTREF(OPER,CDISP*2-2+ORD(SIZE=1), LINKPATCH, EXWORDADDR)
	END;
      5,6,7: {CCR, SR, USP}
	BEGIN CODE.TYPE2.REGY:=4; CODELENGTH:=CODELENGTH-2; END;
      END; (* CASE CODE.TYPE2.REGY *)
    END; (* CASE = 7 *)
$if mc68881$
  8:                     (* flt. pt. register FPn operand *)
    begin
    error( errfpregnotallowed );
    end;
  9:                     (* flt. pt. system register operand *)
    begin
    error( errfpsysregnotallowed );
    end;
$end$
  END; (* CASE *)
END; {BUILDEA}


$include 'M68KFPCDG'$

BEGIN {CODEGEN}
  IF NOT CONTIGUOUS THEN NEWCODESEG;
  CODELENGTH:=2;
  LINKPATCH:=FALSE;
  CODE.INT[1]:=CURROP.CODE;

$if mc68881$
if (currop.class >= fpbase) and (currop.class <= fptop) then
  fpcodegen
else
$end$
CASE CURROP.CLASS OF
1: {ABCD,SBCD}          {DY,DX}
   BEGIN                {-(AY),-(AX)}
     CODE.TYPE2.REGX:=OPERAND2.REG;
     CODE.TYPE2.REGY:=OPERAND1.REG;
     CODE.TYPE2.B3:= OPERAND1.MODE = 4;;
   END;

2,5: {ADD,ADDA,SUB,SUBA}{AND,OR}
  BEGIN
    IF MEMALT(OPERAND2) THEN {DN,<EA>}
      BEGIN
	CODE.TYPE2.OPM1:=(SIZE DIV 2)+4;
	CODE.TYPE2.REGX:=OPERAND1.REG;
	BUILDEA(OPERAND2,2,CODE.IDX[2]);
      END
      ELSE
      BEGIN
	IF OPERAND2.MODE = 1 THEN
	    CODE.TYPE2.OPM1:=(SIZE * 2)-1 {<EA>,AN}
	  ELSE
	    CODE.TYPE2.OPM1:=SIZE DIV 2;   {<EA>,DN}
	CODE.TYPE2.REGX:=OPERAND2.REG;
	BUILDEA(OPERAND1,2,CODE.IDX[2]);
      END;
  END;

3: {ADDQ,SUBQ}
  BEGIN                      {#<DATA>,<EA>}
    CODE.TYPE3.SIZE:=SIZE DIV 2;
    BUILDEA(OPERAND2,2,CODE.IDX[2]);
    CODE.TYPE2.REGX:=OPERAND1.VALUE.OFFSET.BYTE4 MOD 8;
  END;

4: {ADDX,SUBX}
  BEGIN                      {DY,DX}
    CODE.TYPE2.REGX:=OPERAND2.REG; {-(AY),-(AX)}
    CODE.TYPE2.REGY:=OPERAND1.REG;
    CODE.TYPE3.SIZE:=SIZE DIV 2;
    CODE.TYPE2.B3:=OPERAND1.MODE = 4;
  END;

6: {ASL,ASR,LSL,LSR,ROL,ROR,ROXL,ROXR}{ASSUME MEM FORMAT IS SUPPLIED}
  BEGIN
    IF OPERAND1.MODE = 0 THEN
      BEGIN                {DX,DY}
	CODE.TYPE2.REGX:=OPERAND1.REG;
	CODE.TYPE3.SIZE:=SIZE DIV 2;
	CODE.TYPE2.REGY:=OPERAND2.REG;
	CODE.TYPE2.B5:=TRUE;
      END
      ELSE
      IF NOT MEMALT(OPERAND1) THEN
	BEGIN              {#<DATA>,DY}
	  CODE.TYPE2.REGX:=OPERAND1.VALUE.OFFSET.BYTE4 MOD 8;
	  CODE.TYPE3.SIZE:=SIZE DIV 2;
	  CODE.TYPE2.REGY:=OPERAND2.REG;
	  CODE.TYPE2.B5:=FALSE;
	END
	ELSE
	BEGIN              {<EA>}
	  BUILDEA(OPERAND1,2,CODE.IDX[2]);
	END;
  END;

7: {Bcc (BRANCH ON CONDITION) ,BRA,BSR}  {<LABEL>}
  IF OPERAND1.SIZE = 1 THEN                       {.BYTE}
    CODE.BYT[2]:=OPERAND1.VALUE.OFFSET.BYTE4
  ELSE
    BEGIN          { .WORD or .LONG }
    IF OPERAND1.SIZE = 2 THEN
      BEGIN
      CODE.BYT[2]:=0;
      CODE.INT[2]:=OPERAND1.VALUE.OFFSET.LOHALF;
      CODELENGTH:=CODELENGTH+2;
      END
    ELSE (* MUST BE OPERAND1.SIZE=4 *)
      BEGIN
      CODE.BYT[2]:=255;
      CODE.INT[2]:=OPERAND1.VALUE.OFFSET.HIHALF;
      CODE.INT[3]:=OPERAND1.VALUE.OFFSET.LOHALF;
      CODELENGTH:=CODELENGTH+4;
      END;
    IF ( OPERAND1.VALUE.EXPREFS <> NIL) OR
       ((OPERAND1.VALUE.BASE=ABSOLUT ) AND (PCMODE=REL)) or
       ((operand1.value.base=relative) and (pcmode=abs)) THEN
      BEGIN
      OPERAND1.MODE:=7; OPERAND1.REG:=2;
      IF OPERAND1.SIZE=2 THEN LINKPATCH:=TRUE;
      DOLINKXTREF(OPERAND1,2,LINKPATCH, EXWORDADDR);
      END;
    END;

8: {BCHG, BCLR, BSET, BTST}
  IF OPERAND1.MODE = 0 THEN  {DN,<EA>}
    BEGIN
      CODE.TYPE2.REGX:=OPERAND1.REG;
      BUILDEA(OPERAND2,2,CODE.IDX[2]);
    END
    ELSE                     {#<DATA>,<EA>}
    BEGIN
      CODE.TYPE2.REGX:=4;
      CODE.TYPE3.B8:=FALSE;
      BUILDEA(OPERAND2,3,CODE.IDX[3]);
      size:=1;
      code.int[2]:=operand1.value.offset.byte4;
      dolinkxtref(operand1,3,false, exwordaddr);
      codelength:=codelength+2;
    END;

 9,19: {CHK, DIVS, DIVU, MULS, MULU} {LEA  <EA>,AN}
   BEGIN
     CODE.TYPE2.REGX:=OPERAND2.REG;  {<EA>,DN}
     BUILDEA(OPERAND1,2,CODE.IDX[2]);
   END;

 10: {CLR, NEG, NEGX, NOT, TST}
   BEGIN                      {<EA>}
     CODE.TYPE3.SIZE:=SIZE DIV 2;
     BUILDEA(OPERAND1,2,CODE.IDX[2]);
   END;
 11: {CMP,CMPA}
   BEGIN
     IF OPERAND2.MODE = 1 THEN
	 CODE.TYPE2.OPM1:=(SIZE * 2)-1 {<EA>,AN}
       ELSE
	 CODE.TYPE2.OPM1:=SIZE DIV 2;   {<EA>,DN}
     CODE.TYPE2.REGX:=OPERAND2.REG;
     BUILDEA(OPERAND1,2,CODE.IDX[2]);
   END;

 12: { STOP #XXXX }
   BEGIN
     CODE.INT[2]:=OPERAND1.VALUE.OFFSET.LOHALF;
     DOLINKXTREF(OPERAND1, 2, FALSE, EXWORDADDR);
     CODELENGTH:=CODELENGTH+2;
   END;

 13: {DBCC,DBRA} {TEST CONDITION DECREMENT & BRANCH}
   BEGIN                       {DN,<LABEL>}
     CODE.TYPE2.REGY:=OPERAND1.REG;
     CODE.INT[2]:=OPERAND2.VALUE.OFFSET.LOHALF;
     CODELENGTH:=CODELENGTH+2;
     OPERAND2.SIZE:=2;  (* KLUDGES FOR BRANCHES *)
     OPERAND2.MODE:=7;  (* KLUDGES FOR BRANCHES *)
     OPERAND2.REG :=2;  (* KLUDGES FOR BRANCHES *)
     DOLINKXTREF(OPERAND2,2,TRUE,EXWORDADDR);
   END;

 14: {EOR} {DN,<EA>}
   BEGIN
     CODE.TYPE2.OPM1:=(SIZE DIV 2)+4;
     CODE.TYPE2.REGX:=OPERAND1.REG;
     BUILDEA(OPERAND2,2,CODE.IDX[2]);
   END;

 15: {EXG} {RX,RY}
   BEGIN
     CODE.TYPE2.REGX:=OPERAND1.REG;
     CODE.TYPE2.REGY:=OPERAND2.REG;
     CODE.TYPE4.MODE:=OPERAND2.MODE;
     IF OPERAND1.MODE = OPERAND2.MODE
       THEN CODE.TYPE3.SIZE:=1
       ELSE CODE.TYPE3.SIZE:=2;
   END;

 16: {EXT}  {DN}
   BEGIN
     CODE.TYPE2.REGY:=OPERAND1.REG;
   END;

 17,25: {JMP, JSR, PEA}{NBCD, SCC (SET BY CONDITION), TAS}  {<EA>}
   BEGIN
     IF (CURROP.CLASS=17) AND (CURROP.NAME<>'PEA      ') THEN LINKPATCH:=TRUE;
     BUILDEA(OPERAND1,2,CODE.IDX[2]);
   END;

 18: {ADDI,CMPI,SUBI}
   BEGIN           {#<DATA>,<EA>}
     CODE.TYPE3.SIZE:=SIZE DIV 2;
     BUILDEA(OPERAND1,2,CODE.IDX[2]);
     IF SIZE = 4 THEN BUILDEA(OPERAND2,4,CODE.IDX[4])
		 ELSE BUILDEA(OPERAND2,3,CODE.IDX[3]);
   END;

  20: {LINK}  {AN,#<DISP>}
   BEGIN
     CODE.TYPE2.REGY:=OPERAND1.REG;
     IF SIZE=2 THEN
       BEGIN
       code.int[2]:=operand2.value.offset.lohalf;
       dolinkxtref(operand2, 2, false, exwordaddr);
       END
     ELSE
       BEGIN
       code.int[2]:=operand2.value.offset.hihalf;
       code.int[3]:=operand2.value.offset.lohalf;
       dolinkxtref(operand2, 2, false, exwordaddr);
       END;
     codelength:=codelength+SIZE;
   END;

 21: {MOVE, MOVEA}  {<EA>,<EA>}
   IF (OPERAND2.MODE = 7) AND (OPERAND2.REG > 4) THEN
     BEGIN                  {<EA>,SPECIAL REGISTER}
       CODE.TYPE3.OPCODE:=4;
       CASE OPERAND2.REG OF
       5: BEGIN             {CCR}
	    CODE.TYPE2.REGX:=2;
	    CODE.TYPE2.OPM1:=3;
	    BUILDEA(OPERAND1,2,CODE.IDX[2]);
	  END;
       6: BEGIN             {SR}
	    CODE.TYPE2.REGX:=3;
	    CODE.TYPE2.OPM1:=3;
	    BUILDEA(OPERAND1,2,CODE.IDX[2]);
	  END;
       7: BEGIN             {USP}
	    CODE.TYPE2.REGX:=7;
	    CODE.TYPE2.OPM1:=1;
	    BUILDEA(OPERAND1,2,CODE.IDX[2]);
	    CODE.TYPE4.MODE:=4; (* FIX UP MODE FIELD *)
	  END;
       END;

     END {OP2 = 7 AND REG > 4}
     ELSE
     IF (OPERAND1.MODE = 7) AND (OPERAND1.REG > 4) THEN
       BEGIN                 {SPECIAL REGISTER,<EA>}
	 CODE.TYPE3.OPCODE:=4;
	 CASE OPERAND1.REG OF
	 5: BEGIN            {CCR -- allowed on 68010/12 }
	      code.type2.regx:=1;
	      code.type2.opm1:=3;
	    END;
	 6: BEGIN            {SR}
	      CODE.TYPE2.REGX:=0;
	      CODE.TYPE2.OPM1:=3;
	    END;
	 7: BEGIN            {USP}
	      CODE.TYPE2.REGX:=7;
	      CODE.TYPE2.OPM1:=1;
	    END;
	 END;
	 BUILDEA(OPERAND2,2,CODE.IDX[2]);
	 IF OPERAND1.REG = 7 THEN CODE.TYPE4.MODE:=5;
       END {OP1 = 7 AND REG > 4}
       ELSE
       BEGIN                {<EA>,<EA>}
	 IF SIZE = 1 THEN CODE.TYPE2.MSIZE:=1
	   ELSE
	     IF SIZE =2 THEN CODE.TYPE2.MSIZE:=3
			ELSE CODE.TYPE2.MSIZE:=2;
	 BUILDEA(OPERAND1,2,CODE.IDX[2]);
	 SAVEREGY:=CODE.TYPE2.REGY;
	 SAVEMODE:=CODE.TYPE4.MODE;
	 DUMMY:=2+(OPERAND1.SIZE DIV 2);
	 BUILDEA(OPERAND2,DUMMY,CODE.IDX[DUMMY]);
	 CODE.TYPE2.REGX:=CODE.TYPE2.REGY;
	 CODE.TYPE2.OPM1:=CODE.TYPE4.MODE;
	 CODE.TYPE2.REGY:=SAVEREGY;
	 CODE.TYPE4.MODE:=SAVEMODE;
       END;

 22: {MOVEM} {<LIST>,<EA> OR <EA>,<LIST>  LIST WILL BE IMMED DATA}
   BEGIN
     CODELENGTH:=4;
     CODE.TYPE5.B6:= SIZE = 4;
     CODE.TYPE4.B10:= (OPERAND2.MODE = 7) AND (OPERAND2.REG = 4);
     IF CODE.TYPE4.B10 = FALSE THEN
       BEGIN                       {<LIST>,<EA>}
	 CODE.INT[2]:=OPERAND1.VALUE.OFFSET.LOHALF;
	 BUILDEA(OPERAND2,3,CODE.IDX[3]);
       END
       ELSE
       BEGIN                       {<EA>,<LIST>}
	 CODE.INT[2]:=OPERAND2.VALUE.OFFSET.LOHALF;
	 BUILDEA(OPERAND1,3,CODE.IDX[3]);
       END;
    END;

 23: {MOVEP} {DX,D(AY)  OR D(AY),DX}
    BEGIN
      IF OPERAND1.MODE = 0 THEN
	BEGIN {DX,D(AY)}
	  CODE.TYPE2.REGX:=OPERAND1.REG;
	  BUILDEA(OPERAND2,2,CODE.IDX[2]);
	  CODE.TYPE2.OPM1:=6;
	END
	ELSE
	BEGIN
	  CODE.TYPE2.REGX:=OPERAND2.REG;
	  BUILDEA(OPERAND1,2,CODE.IDX[2]);
	  CODE.TYPE2.OPM1:=4;
	END;
      CODE.TYPE4.MODE:=1;
      IF SIZE = 4 THEN CODE.TYPE2.OPM1:=CODE.TYPE2.OPM1+1;
   END;


 24: {MOVEQ} {#<DATA>,DN}
   BEGIN
     CODE.TYPE2.REGX:=OPERAND2.REG;
     CODE.BYT[2]:=OPERAND1.VALUE.OFFSET.BYTE4;
   END;

 26: {NOP,RESET,RTE,RTR,RTS,STOP,TRAPV}
   BEGIN  END;

 27: {ANDI,EORI,ORI} {#<DATA>,<EA>}
   BEGIN
     CODE.TYPE3.SIZE:= SIZE DIV 2;
     BUILDEA(OPERAND1,2,CODE.IDX[2]);
     IF SIZE = 4 THEN BUILDEA(OPERAND2,4,CODE.IDX[4])
		 ELSE BUILDEA(OPERAND2,3,CODE.IDX[3]);
     IF OPERAND2.MODE = 7 THEN
       BEGIN
	 IF OPERAND2.REG = 5 THEN CODE.TYPE3.SIZE:=0; {CCR}
	 IF OPERAND2.REG = 6 THEN CODE.TYPE3.SIZE:=1; {SR}
       END;
   END;

 28,30: {SWAP}{UNLK}  {REG}
   CODE.TYPE2.REGY:=OPERAND1.REG;

 29: {TRAP}
   BEGIN
   CODE.TYPE5.VECTOR:=OPERAND1.VALUE.OFFSET.BYTE4 MOD 16;
   IF SIZE=2 THEN
     BEGIN
     CODE.INT[2]:=OPERAND2.VALUE.OFFSET.LOHALF;
     CODELENGTH:=CODELENGTH+2;
     END;
   END;

 31: {CMPM} {(AY)+,(AX)+}
   BEGIN
     CODE.TYPE3.SIZE:=SIZE DIV 2;
     CODE.TYPE2.REGX:=OPERAND2.REG;
     CODE.TYPE2.REGY:=OPERAND1.REG;
   END;

 32: { MOVEC }
   BEGIN
     CODELENGTH:=4;
     CODE.INT[2]:=0;
     IF (OPERAND1.MODE<=1) THEN CODE.INT[1]:=CODE.INT[1]+1;
     IF ODD(CODE.INT[1]) THEN BEGIN { GENERAL TO CONTROL REG }
       CODE.IDX[2].DA:=OPERAND1.MODE=1;
       CODE.IDX[2].REGI:=OPERAND1.REG;
       CASE OPERAND2.REG OF
	 7:  { USP  } I:=HEX('800');
	 8:  { DFC  } I:=HEX('001');
	 9:  { SFC  } I:=HEX('000');
	 10: { VBR  } I:=HEX('801');
	 11: { MSP  } I:=HEX('803');
	 12: { ISP  } I:=HEX('804');
	 13: { CACR } I:=HEX('002');
	 14: { CAAR } I:=HEX('802');
       { Added 12/26/89 for the new '040 registers : }
	 15: { TC }   I:= HEX('003');
	 16: { ITT0 } I:= hex('004');
	 17: { ITT1 } I:= hex('005');
	 18: { DTT0 } I:= hex('006');
	 19: { DTT1 } I:= hex('007');
	 20: { MMUSR } I:= hex('805');
	 21: { URP } I:= hex('806');
	 22: { SRP } I:= hex('807');
       END;
     END
     ELSE BEGIN
       CODE.IDX[2].DA:=OPERAND2.MODE=1;
       CODE.IDX[2].REGI:=OPERAND2.REG;
       CASE OPERAND1.REG OF
	 7:  { USP  } I:=HEX('800');
	 8:  { DFC  } I:=HEX('001');
	 9:  { SFC  } I:=HEX('000');
	 10: { VBR  } I:=HEX('801');
	 11: { MSP  } I:=HEX('803');
	 12: { ISP  } I:=HEX('804');
	 13: { CACR } I:=HEX('002');
	 14: { CAAR } I:=HEX('802');
       { Added 12/26/89 for the new '040 registers : }
	 15: { TC }   I:= HEX('003');
	 16: { ITT0 } I:= hex('004');
	 17: { ITT1 } I:= hex('005');
	 18: { DTT0 } I:= hex('006');
	 19: { DTT1 } I:= hex('007');
	 20: { MMUSR } I:= hex('805');
	 21: { URP } I:= hex('806');
	 22: { SRP } I:= hex('807');
       END
     END;
     CODE.INT[2]:=CODE.INT[2]+I;
   END;

 33: { MOVES }
   BEGIN
     CODE.INT[2]:=0;
     CODELENGTH:=4;
     CODE.TYPE2.OPM1:=SIZE DIV 2;
     IF (OPERAND1.MODE<=1) THEN BEGIN { REG, <EA>}
       CODE.IDX[2].DA:=OPERAND1.MODE=1;
       CODE.IDX[2].REGI:=OPERAND1.REG;
       CODE.IDX[2].WL:=TRUE;
       BUILDEA(OPERAND2, 3, CODE.IDX[3]);
     END
     ELSE BEGIN          { <EA>, REG }
       CODE.IDX[2].DA:=OPERAND2.MODE=1;
       CODE.IDX[2].REGI:=OPERAND2.REG;
       BUILDEA(OPERAND1, 3, CODE.IDX[3]);
     END;
   END;

 34: { RTM }
   BEGIN
   CODE.BITS.B3:=OPERAND1.MODE=1;
   CODE.OITS.O0:=OPERAND1.REG;
   END;

 35: { BKPT }
   CODE.OITS.O0:=OPERAND1.VALUE.OFFSET.BYTE4;

 36: { TRAPcc }
   BEGIN
   IF      SIZESUFFIX='W' THEN
     BEGIN
     CODE.OITS.O0:=2; CODELENGTH:=4;
     CODE.INT[2]:=OPERAND1.VALUE.OFFSET.LOHALF;
     END
   ELSE IF SIZESUFFIX='L' THEN
     BEGIN
     CODE.OITS.O0:=3; CODELENGTH:=6;
     CODE.INT[2]:=OPERAND1.VALUE.OFFSET.HIHALF;
     CODE.INT[3]:=OPERAND1.VALUE.OFFSET.LOHALF;
     END
   ELSE   {SIZESUFFIX=' '}
     BEGIN
     CODE.OITS.O0:=4; CODELENGTH:=2;
     END;
   IF SIZESUFFIX<>' ' THEN
     DOLINKXTREF(OPERAND1,2,FALSE,EXWORDADDR);
   END;

 37: { CALLM }
   BEGIN
   CODELENGTH:=4;
   CODE.INT[2]:=0;
   CODE.BYT[4]:=OPERAND1.VALUE.OFFSET.BYTE4;
   SIZE:=1; DOLINKXTREF(OPERAND1,3,FALSE,EXWORDADDR);
   BUILDEA(OPERAND2,3,CODE.IDX[3]);
   END;

 38: { CAS }
   BEGIN
   CODELENGTH:=4;
   CODE.INT[2]:=0;
   CODE.OITS2.O0:=OPERAND1.REG;
   CODE.OITS2.O2:=OPERAND2.REG;
   BUILDEA(OPERAND3,3,CODE.IDX[3]);
   END;

 39: { CAS2 }
   BEGIN
   CODELENGTH:=6;
   CODE.INT[2]:=0;
   CODE.OITS2.O0 :=OPERAND1.REG;
   CODE.OITS2.O2 :=OPERAND3.REG;
   CODE.OITS2.O4 :=OPERAND5.REG;
   CODE.OITS2.B15:=OPERAND5.MODE=2;
   CODE.INT[3]:=0;
   CODE.OITS3.O0 :=OPERAND2.REG;
   CODE.OITS3.O2 :=OPERAND4.REG;
   CODE.OITS3.O4 :=OPERAND6.REG;
   CODE.OITS3.B15:=OPERAND6.MODE=2;
   END;

 40: { CHK2, CMP2 }
   BEGIN
   CODELENGTH:=4;
   CODE.INT[2]:=0;
   CODE.OITS2.O4 := OPERAND2.REG;
   CODE.BITS2.B15:=(OPERAND2.MODE=1);
   CODE.BITS2.B11:=(CURROP.NAME='CHK2     ');
   BUILDEA(OPERAND1,3,CODE.IDX[3]);
   END;

 41: { PACK, UNPK }
   BEGIN
   CODELENGTH:=4;
   CODE.BITS.B3:=(OPERAND1.MODE=4);
   CODE.OITS.O0:=OPERAND1.REG;
   CODE.OITS.O3:=OPERAND2.REG;
   CODE.INT[2] :=OPERAND3.VALUE.OFFSET.LOHALF;
   DOLINKXTREF(OPERAND3,2,FALSE,EXWORDADDR);
   END;

 42: { BFCHG, BFCLR, BFSET, BFTST }
   BEGIN
   CODELENGTH:=4;
   CODE.INT[2]:=0;
   CODE.BF.DOFF  :=BITFIELD.DOFF;
   CODE.BF.OFFSET:=BITFIELD.OFFSET;
   CODE.BF.DWID  :=BITFIELD.DWID;
   CODE.BF.WIDTH :=BITFIELD.WIDTH;
   BUILDEA(OPERAND1,3,CODE.IDX[3]);
   END;

 43: { BFEXTS, BFEXTU, BFFFO }
   BEGIN
   CODELENGTH:=4;
   CODE.INT[2]:=0;
   CODE.BF.REG   :=OPERAND2.REG;
   CODE.BF.DOFF  :=BITFIELD.DOFF;
   CODE.BF.OFFSET:=BITFIELD.OFFSET;
   CODE.BF.DWID  :=BITFIELD.DWID;
   CODE.BF.WIDTH :=BITFIELD.WIDTH;
   BUILDEA(OPERAND1,3,CODE.IDX[3]);
   END;

 44: { BFINS }
   BEGIN
   CODELENGTH:=4;
   CODE.INT[2]:=0;
   CODE.BF.REG   :=OPERAND1.REG;
   CODE.BF.DOFF  :=BITFIELD.DOFF;
   CODE.BF.OFFSET:=BITFIELD.OFFSET;
   CODE.BF.DWID  :=BITFIELD.DWID;
   CODE.BF.WIDTH :=BITFIELD.WIDTH;
   BUILDEA(OPERAND2,3,CODE.IDX[3]);
   END;

 45: { DIV?.L, DIV?L.L, MUL?.L }
   BEGIN
   CODELENGTH:=4;
   CODE.INT[2]:=0;
   CODE.BITS2.B11:=(CURROP.NAME[4]='S');
   CODE.BITS2.B10:=(OPERAND2.MODE=0); (***** special flag for 64bit mode *****)
				      (* someone unkind may call it a kludge *)
   CODE.OITS2.O0 :=OPERAND2.REG;
   CODE.OITS2.O4 :=OPERAND3.REG;
   BUILDEA(OPERAND1,3,CODE.IDX[3]);
   END;

 46: { MOVE16 }  { JWH 11/21/89 }
   BEGIN
    if operand1.mode <> 0 then { everything's cool }
     begin
     if ((operand1.MODE = 3) and (operand2.MODE = 3)) then  { POST INCR MODE }
      begin
       CODELENGTH := 4;
       CODE.BYT[2] := 32 + OPERAND1.REG;
       CODE.BYT[3] := 128 + 16*OPERAND2.REG;
       CODE.BYT[4] := 0;
      end
     else { ABSOLUTE MODE }
      begin
       CODELENGTH := 6;
       if OPERAND1.MODE = 7 then {it's absolute}
	begin
	 CODE.INT[2] := OPERAND1.VALUE.OFFSET.HIHALF;
	 CODE.INT[3] := OPERAND1.VALUE.OFFSET.LOHALF;
	 dolinkxtref(operand1, 2, false, exwordaddr);
	 if OPERAND2.MODE = 3 then
	   CODE.BYT[2] := 8 + OPERAND2.REG
	 else { operand2.MODE = 2 }
	   CODE.BYT[2] := 24 + OPERAND2.REG;
	end
       else { OPERAND2.MODE = 7 }
	begin
	 CODE.INT[2] := OPERAND2.VALUE.OFFSET.HIHALF;
	 CODE.INT[3] := OPERAND2.VALUE.OFFSET.LOHALF;
	 dolinkxtref(operand2, 2, false, exwordaddr);
	 if OPERAND1.MODE = 3 then
	   CODE.BYT[2] :=  OPERAND1.REG
	 else { operand2.MODE = 2 }
	   CODE.BYT[2] := 16 + OPERAND1.REG;
	end; { OPERAND2.MODE = 7 }
      end; { ABSOLUTE MODE }
     end { operand1.mode <> 0 }
     else { operand1.mode = 0, have BADOPS if we are here }
	  { just put in some generic values }
      begin
       if operand1.size = 0 then
	begin
	 CODELENGTH := 4;
	 CODE.BYT[2] := 32;
	 CODE.BYT[3] := 128;
	 CODE.BYT[4] := 0;
	end
       else { operand1.size = 2 }
	begin
	 CODELENGTH := 6;
	 CODE.BYT[2] := 0;
	 CODE.INT[3] := 0;
	 CODE.INT[4] := 0;
	end;
      end; { code for badops }
   END;  { Case 46 }
   47,48,49,50,51,52 : { CINVL,CINVP,CINVA,CPUSHL,CPUSHP,CPUSHA }
   BEGIN
     { If operand1.mode = 0 we had an operand error }
     CODELENGTH := 2;
     case OPERAND1.MODE of
       0: CODE.BYT[2] := 0;    { cache : 00 no operation }
       1: CODE.BYT[2] := 64;   { cache : 01 data        }
       2: CODE.BYT[2] := 128;  { cache : 10 instruction }
       3: CODE.BYT[2] := 192;  { cache : 11 both        }
     end; { CASE }
     if ((currop.CLASS <> 49) and (currop.CLASS <> 52)) then
       CODE.BYT[2] := CODE.BYT[2] + OPERAND2.REG;
     if ((CURROP.CLASS = 47) or (CURROP.CLASS = 50)) then
	CODE.BYT[2] := CODE.BYT[2] + 8   { scope : 01 - LINE }
     else IF ((currop.class = 48) or (currop.class = 51)) then
       CODE.BYT[2] := CODE.BYT[2] + 16   { scope : 10 - PAGE }
     else { currop.class = 49 or currop.class = 52 }
       CODE.BYT[2] := CODE.BYT[2] + 24; { scope : 11 - ALL }
     if currop.class > 49 then { it is a CPUSHx }
       CODE.BYT[2] := CODE.BYT[2] + 32; { SET BIT 5 to 1 }
   END; { case 47,48,49 }


END;  { OF CASE }
 PUNCHCODE;   (* OUTPUT THE GENERATED CODE *)
END;


@


56.2
log
@
pws2rcs automatic delta on Wed Jan 27 11:57:27 MST 1993
@
text
@d1 1734
@


56.1
log
@Automatic bump of revision number for PWS version 3.25
@
text
@a0 1734
CONST BADOPS=101; OPSOK=100;

PROCEDURE PASS2; { THIS PROCEDURE DOES ALL THE PASS 2 PROCESSING. }
VAR SP:STREF;  { SCRATCH VAR FOR SYMTABLE ACCESS }

PROCEDURE PASS2STUFF; { THIS DOES PASS 2 INSTRUCTION PROCESSING }
VAR TOP: OPERAND;  { SCRATCH VAR FOR OPERANDS }

PROCEDURE NEWTEXTREC; { DOES NECESSARY STUFF WHEN GET NEW ORG }
VAR I,  SAVEBLOCK: SHORTINT;

BEGIN
REFCOPY;
SAVEBLOCK:=OBJCTR;
if object then begin
  I:=BLOCKREAD(OBJFILE,PUNCHBLK,1,1);
  IF I<>1  THEN ERROR(errcread);
end;
PUNCHLC:=TEXTINFO;
IF PUNCHLC+22>511 THEN ERROR(ERRDIROVF);
PUNCHDWORD(TEXTSTART);
PUNCHDWORD(TEXTSIZE);
PUNCHDWORD(REFSTART);
PUNCHDWORD(REFSIZE);
IF PCMODE=REL THEN GV.PRIMARYTYPE:=RELOCATABLE ELSE
  GV.PRIMARYTYPE:=ABSOLUTE;
GV.DATASIZE:=SINT;
GV.PATCHABLE:=FALSE;
GV.VALUEEXTEND:=TRUE;
GV.LONGOFFSET:=FALSE;
GV.SHORT:=6;
PUNCHGVR(GV);
PUNCHDWORD(ORIGIN);
if object then begin
  I:=BLOCKWRITE(OBJFILE, PUNCHBLK,1,1);
  IF I<>1  THEN ERROR(errwrite);
end;
TEXTINFO:=PUNCHLC;
OBJCTR:=SAVEBLOCK;
TEXTSTART:=OBJCTR-1;
PUNCHLC:=0;
{****************** Not needed!!!  (BAR)
if object then begin
  I:=BLOCKREAD(OBJFILE,PUNCHBLK,1,OBJCTR);
  IF I<>1  THEN ERROR(errcread);
end;
***************************************}
TEXTRECORDS:=TEXTRECORDS+1;
END;


PROCEDURE NEWCODESEG;
BEGIN
  TEXTSIZE:=ENDOFCODE-ORIGIN;
  NEWTEXTREC;
  ORIGIN:=LOCCTR.LONGINT;
  if odd(origin) then error(erroddorg);
  CONTIGUOUS:=TRUE;
END;


PROCEDURE REFOFFSET;  {CALCULATES OFFSETS FOR REF RECORDS}
BEGIN
  IF FIRSTREF THEN BEGIN
    LASTREFLOC:=REFLOC;
    REFOFF:=REFLOC-ORIGIN;
    FIRSTREF:=FALSE;
  END
  ELSE BEGIN
    REFOFF:=REFLOC-LASTREFLOC;
    LASTREFLOC:=REFLOC;
  END;
  IF REFOFF<256 THEN BEGIN
    REFFILE^.INFO.LONGOFFSET:=FALSE;
    REFFILE^.INFO.SHORT:=REFOFF;
  END
  ELSE BEGIN
    REFFILE^.INFO.LONGOFFSET:=TRUE;
    REFFILE^.INFO.LONG:=REFOFF;
  END;
END;


PROCEDURE DOLINKXTREF(OPER:OPERAND;BDISP:SHORTINT; LINKPATCH:BOOLEAN;
			  VAR EXWORDADDR: WORD32);
VAR
  OD_DISP: INTEGER;

  PROCEDURE NEWREFFILE;
  BEGIN
  TRY
    NEW(REFFILE)
  RECOVER
    BEGIN
    if escapecode=-2 then
      begin
      WRITELN(LP,'MEMORY OVERFLOW!');
      LPCHECK;           { 3/2/84 }
      IF LISTNAME<>'CONSOLE:' THEN WRITELN('MEMORY OVERFLOW!');
      ESCAPE(-1);
      end
    else escape(escapecode);
    END;
  END;

  PROCEDURE PUTREFFILE;
  BEGIN
  REFLOC:=LOCCTR.LONGINT+BDISP;
  REFOFFSET;
  IF REFHEAD=NIL
    THEN REFHEAD:=REFFILE
    ELSE REFTAIL^.REFNEXT:=REFFILE;
  REFTAIL:=REFFILE;
  REFFILE^.REFNEXT:=NIL;
  REFCTR:=REFCTR+1;
  END;

BEGIN
IF ((OPER.MODE=6) OR ((OPER.MODE=7) AND (OPER.REG=3))) AND
   OPER.FULL_FORMAT THEN
  BDISP:=BDISP+2-1; (* SPACE FOR EXTENSION WORD *)
IF OPER.VALUE.EXPREFS <> NIL THEN
  (******************** THERE IS AN EXTERNAL REFERENCE *)
  BEGIN
  NEWREFFILE;
  REFFILE^.EXTSTUFF2.LAST:=FALSE;
  REFFILE^.EXTSTUFF.ADR:=OPER.VALUE.EXPREFS^.SYMPT^.SVALUE.LOHALF;
  REFFILE^.INFO.VALUEEXTEND:=FALSE;

  if ((oper.mode=6) AND (NOT OPER.FULL_FORMAT)) or
     ((oper.mode=7) and (oper.reg=4) and (size=1)) or
     ((oper.mode=7) and (oper.reg=3) AND (NOT OPER.FULL_FORMAT)) then
    begin
    if not(fitsin8(oper.value.offset)) then
      begin
      reffile^.info.valueextend:=true;
      exwordaddr:=zero32;
      code.byt[bdisp+1]:=0;
      end
    end
$if fpimmed$
	      (* ??? may need larger immed. opd handling *)
$end$
   else if not((oper.mode=7) and (oper.reg=4) and (size=4)) then
     if not(fitsin16(oper.value.offset)) AND (OPER.SIZE=2) then
       begin
       reffile^.info.valueextend:=true;
       exwordaddr:=zero32;
       code.int[bdisp div 2 + 1]:=0;
       end
     ELSE IF ((OPER.MODE=6) OR ((OPER.MODE=7) AND (OPER.REG=3))) AND
	     OPER.FULL_FORMAT AND
	     (OPER.BD_SIZE=S_WORD) AND
	     NOT(FITSIN16(OPER.VALUE.OFFSET)) THEN
       BEGIN
       REFFILE^.INFO.VALUEEXTEND:=TRUE;
       EXWORDADDR:=ZERO32;
       CODE.INT[BDISP DIV 2 + 1]:=0;
       END;



  CASE OPER.MODE OF
  0,1,2,3,4: BEGIN  END;
  5: BEGIN
    REFFILE^.INFO.PRIMARYTYPE:=GENERAL;
    REFFILE^.INFO.DATASIZE:=SWORD;
    REFFILE^.INFO.PATCHABLE:=FALSE;
    IF OPER.VALUE.EXPREFS^.MINUS
      THEN REFFILE^.EXTSTUFF.OP:=SUBIT
      ELSE REFFILE^.EXTSTUFF.OP:=ADDIT;
    END;

  6: BEGIN (* SAME AS MODE=7, REG=3 *)
    REFFILE^.INFO.PRIMARYTYPE:=GENERAL;
    REFFILE^.INFO.PATCHABLE:=FALSE;
    IF OPER.FULL_FORMAT THEN
      BEGIN
      IF OPER.BD_SIZE=S_WORD (* CAN'T HAVE S_NULL OR S_RES WITH AN EXT. REF. *)
	THEN REFFILE^.INFO.DATASIZE:=SWORD
	ELSE REFFILE^.INFO.DATASIZE:=SINT
      END
    ELSE
      REFFILE^.INFO.DATASIZE:=SBYTE;
    IF OPER.VALUE.EXPREFS^.MINUS
      THEN REFFILE^.EXTSTUFF.OP:=SUBIT
      ELSE REFFILE^.EXTSTUFF.OP:=ADDIT;
    IF OPER.VALUE.EXPREFS^.SYMPT^.SKIND=RELATIVE THEN
      BEGIN
      REFFILE^.EXTSTUFF2.OP:=SUBIT;
      REFFILE^.EXTSTUFF2.ADR:=0;
      REFFILE^.EXTSTUFF2.LAST:=TRUE;
      END;
    END;

  7:
    CASE OPER.REG OF
      0,1: BEGIN
	REFFILE^.INFO.PRIMARYTYPE:=GENERAL;
	REFFILE^.INFO.PATCHABLE:=FALSE;
	IF OPER.REG=0
	  THEN REFFILE^.INFO.DATASIZE:=SWORD
	  ELSE REFFILE^.INFO.DATASIZE:=SINT;
	IF ((OPER.VALUE.BASE=RELATIVE) AND
	    (OPER.VALUE.EXPREFS^.SYMPT^.SKIND=ABSOLUT)) OR
	   ((OPER.VALUE.BASE=ABSOLUT) AND
	    (OPER.VALUE.EXPREFS^.SYMPT^.SKIND=RELATIVE)) THEN
	  BEGIN
	  IF    (OPER.VALUE.BASE=ABSOLUT) AND
	     NOT(OPER.VALUE.EXPREFS^.MINUS)
	    THEN REFFILE^.EXTSTUFF2.OP:=SUBIT
	    ELSE REFFILE^.EXTSTUFF2.OP:=ADDIT;
	  REFFILE^.EXTSTUFF2.ADR:=0;
	  REFFILE^.EXTSTUFF2.LAST:=TRUE;
	  END;
	IF OPER.VALUE.EXPREFS^.MINUS
	  THEN REFFILE^.EXTSTUFF.OP:=SUBIT
	  ELSE REFFILE^.EXTSTUFF.OP:=ADDIT;
	END;

      2: BEGIN                  {PC + 16 BIT}
	REFFILE^.INFO.PRIMARYTYPE:=GENERAL;
	REFFILE^.INFO.PATCHABLE:=LINKPATCH;
	IF OPER.SIZE=2
	  THEN REFFILE^.INFO.DATASIZE:=SWORD
	  ELSE REFFILE^.INFO.DATASIZE:=SINT; (* MUST BE SIZE=4 *)
	IF OPER.VALUE.EXPREFS^.MINUS
	  THEN REFFILE^.EXTSTUFF.OP:=SUBIT
	  ELSE REFFILE^.EXTSTUFF.OP:=ADDIT;
	IF (OPER.VALUE.BASE=RELATIVE) THEN
	  IF (OPER.VALUE.EXPREFS^.SYMPT^.SKIND=RELATIVE) AND
	     (PCMODE=REL) THEN
	    BEGIN
	    REFFILE^.EXTSTUFF2.OP:=SUBIT;
	    REFFILE^.EXTSTUFF2.ADR:=0;
	    REFFILE^.EXTSTUFF2.LAST:=TRUE;
	    END
	  ELSE
	ELSE IF PCMODE=REL THEN
	  BEGIN
	 { ABSOLUTE TARGET -- KLUGE FOR BRANCH }
	  REFFILE^.EXTSTUFF2.OP:=SUBIT;
	  REFFILE^.EXTSTUFF2.ADR:=0;
	  REFFILE^.EXTSTUFF2.LAST:=TRUE;
	  END;
	END;

      3: BEGIN (* SAME AS MODE=6 *) {PC + 8 BIT}
	REFFILE^.INFO.PRIMARYTYPE:=GENERAL;
	REFFILE^.INFO.PATCHABLE:=false;
	IF OPER.FULL_FORMAT THEN
	  BEGIN
	  IF OPER.BD_SIZE=S_WORD (* CAN'T HAVE S_NULL OR S_RES WITH AN EXT. REF. *)
	    THEN REFFILE^.INFO.DATASIZE:=SWORD
	    ELSE REFFILE^.INFO.DATASIZE:=SINT
	  END
	ELSE
	  REFFILE^.INFO.DATASIZE:=SBYTE;
	IF OPER.VALUE.EXPREFS^.MINUS
	  THEN REFFILE^.EXTSTUFF.OP:=SUBIT
	  ELSE REFFILE^.EXTSTUFF.OP:=ADDIT;
	IF OPER.VALUE.EXPREFS^.SYMPT^.SKIND=RELATIVE THEN
	  BEGIN
	  REFFILE^.EXTSTUFF2.OP:=SUBIT;
	  REFFILE^.EXTSTUFF2.ADR:=0;
	  REFFILE^.EXTSTUFF2.LAST:=TRUE;
	  END;
	END;

      4: BEGIN
$if mc68881$
	     (* need to handle larger immed. opds ??? *)
$end$
	REFFILE^.INFO.PRIMARYTYPE:=GENERAL;
	REFFILE^.INFO.PATCHABLE:=FALSE;
	CASE SIZE OF
	  1: REFFILE^.INFO.DATASIZE:=SBYTE;
	  2: REFFILE^.INFO.DATASIZE:=SWORD;
	  4: REFFILE^.INFO.DATASIZE:=SINT;
	  END;
	IF ((OPER.VALUE.BASE=RELATIVE) AND
	    (OPER.VALUE.EXPREFS^.SYMPT^.SKIND=ABSOLUT)) OR
	   ((OPER.VALUE.BASE=ABSOLUT) AND
	    (OPER.VALUE.EXPREFS^.SYMPT^.SKIND=RELATIVE)) THEN
	  BEGIN
	  IF    (OPER.VALUE.BASE=ABSOLUT) AND
	     NOT(OPER.VALUE.EXPREFS^.MINUS)
	    THEN REFFILE^.EXTSTUFF2.OP:=SUBIT
	    ELSE REFFILE^.EXTSTUFF2.OP:=ADDIT;
	  REFFILE^.EXTSTUFF2.ADR:=0;
	  REFFILE^.EXTSTUFF2.LAST:=TRUE;
	  END;
	IF OPER.VALUE.EXPREFS^.MINUS
	  THEN REFFILE^.EXTSTUFF.OP:=SUBIT
	  ELSE REFFILE^.EXTSTUFF.OP:=ADDIT;
	END;

      5,6,7: BEGIN END;

      END; {CASE}
    END; {CASE}

  REFFILE^.EXTSTUFF.LAST:=NOT REFFILE^.EXTSTUFF2.LAST;
  IF REFFILE^.INFO.VALUEEXTEND
    THEN REFFILE^.VALUE:=OPER.VALUE.OFFSET
    ELSE REFFILE^.VALUE:=ZERO32;
  PUTREFFILE;
  END (* OPER.VALUE.EXPREFS <> NIL *)
ELSE
$if mc68881$
		    (* need to handle larger immed. opds ??? *)
$end$
IF (OPER.VALUE.BASE=RELATIVE) AND
   (OPER.MODE=7) AND
   ((OPER.REG=4) or (oper.reg=0) or (oper.reg=1)) THEN
  (******************** THERE IS A RELATIVE IN ABSOLUTE OR IMMEDIATE *)
  BEGIN
  NEWREFFILE;
  REFFILE^.INFO.PATCHABLE:=FALSE;
  REFFILE^.INFO.PRIMARYTYPE:=RELOCATABLE;
  REFFILE^.INFO.VALUEEXTEND:=FALSE;
  if (oper.reg=4) then
    CASE SIZE OF
      1: REFFILE^.INFO.DATASIZE:=SBYTE;
      2: REFFILE^.INFO.DATASIZE:=SWORD;
      4: REFFILE^.INFO.DATASIZE:=SINT;
$if fpimmed AND FALSE$
      8:
	begin
	reffile^.info.datasize:= sint;  (* this is wrong ??? *)
	reffile^.info.valueextend := true;
	reffile^.value := oper.value.offset;
	end;
$end$
      END (* CASE *) (* if (oper.reg=4) *)
  else if oper.reg=0 then
    reffile^.info.datasize:=sword
  else
    reffile^.info.datasize:=sint;
  PUTREFFILE;
  END
ELSE IF (CURROP.CLASS=7)
$if mc68881$
     or (currop.class=(fpbase+fpbrbase+32))  (* FBcc *)
$end$
     THEN
  BEGIN
  (******************** THIS IS A BRANCH AND NOT EXTERNAL *)
  NEWREFFILE;
  REFFILE^.INFO.PATCHABLE:=LINKPATCH;
  REFFILE^.INFO.PRIMARYTYPE:=GENERAL;
  if not fitsin16(oper.value.offset) AND (SIZE=2) then
    begin
    reffile^.info.valueextend:=true;
    reffile^.value:=oper.value.offset;
    code.int[2]:=0;
    end
  else reffile^.info.valueextend:=false;
  IF SIZE=2
    THEN REFFILE^.INFO.DATASIZE:=SWORD
    ELSE REFFILE^.INFO.DATASIZE:=SINT;
  REFFILE^.EXTSTUFF.ADR:=0;
  if oper.value.base=absolut
    then reffile^.extstuff.op:=subit
    else REFFILE^.EXTSTUFF.OP:=addit;
  REFFILE^.EXTSTUFF.LAST:=TRUE;
  PUTREFFILE;
  END
else if (pcmode=abs) and
	(((oper.mode=7) and ((oper.reg=2) or (oper.reg=3))) OR
	 ( OPER.MODE=6)) and
	(oper.value.base=relative) then
  begin
  (******************** THERE IS A RELATIVE BUT NO EXTERNAL IN INDIRECT *)
  NEWREFFILE;
  reffile^.info.patchable:=linkpatch and (OPER.MODE=7) AND (oper.reg=2);
  reffile^.info.primarytype:=relocatable;
  if (OPER.MODE=7) AND (oper.reg=2) then
    reffile^.info.datasize:=sword
  else
    IF OPER.FULL_FORMAT THEN
      BEGIN
      IF OPER.BD_SIZE=S_WORD (* CAN'T HAVE S_NULL OR S_RES WITH A REF. *)
	THEN REFFILE^.INFO.DATASIZE:=SWORD
	ELSE REFFILE^.INFO.DATASIZE:=SINT
      END
    ELSE
      REFFILE^.INFO.DATASIZE:=SBYTE;
  if (not(fitsin16(oper.value.offset)) and (REFFILE^.INFO.DATASIZE=SWORD)) or
     (not(fitsin8 (oper.value.offset)) and (REFFILE^.INFO.DATASIZE=SBYTE)) then
    begin
    reffile^.info.valueextend:=true;
    if REFFILE^.INFO.DATASIZE=SBYTE then
      code.byt[bdisp+1]:=0
    else
      code.int[bdisp div 2 + 1]:=0;
    reffile^.value:=oper.value.offset;
    exwordaddr:=zero32;
    end
  else
    begin
    reffile^.info.valueextend:=false;
    reffile^.value:=zero32;
    end;
  PUTREFFILE;
  end;
(*************************************************************************)
(* THE PRECEDING CHUNKS ARE ALL EXCLUSIVE; IF ONE IS INVOKED, NONE OF
(* THE OTHERS ARE.  THE FOLLOWING CHUNK IS INDEPENDENT OF THE PRECEDING.
(**)
IF ((OPER.MODE=6) OR ((OPER.MODE=7) AND (OPER.REG=3))) AND
   (OPER.FULL_FORMAT) AND
   (OPER.OD_SIZE>=S_WORD) THEN
  BEGIN
  IF      OPER.BD_SIZE=S_LONG THEN
    BDISP:=BDISP+4
  ELSE IF OPER.BD_SIZE=S_WORD THEN
    BDISP:=BDISP+2;

  IF OPER.OD_VALUE.EXPREFS <> NIL THEN
    (******************** THERE IS AN EXTERNAL REFERENCE *)
    BEGIN
    NEWREFFILE;
    REFFILE^.EXTSTUFF2.LAST:=FALSE;
    REFFILE^.EXTSTUFF.ADR:=OPER.OD_VALUE.EXPREFS^.SYMPT^.SVALUE.LOHALF;
    REFFILE^.INFO.VALUEEXTEND:=FALSE;

    IF (OPER.OD_SIZE=S_WORD) AND
       NOT(FITSIN16(OPER.OD_VALUE.OFFSET)) THEN
      BEGIN
      REFFILE^.INFO.VALUEEXTEND:=TRUE;
      EXWORDADDR:=ZERO32;
      CODE.INT[BDISP DIV 2 + 1]:=0;
      END;

    REFFILE^.INFO.PRIMARYTYPE:=GENERAL;
    REFFILE^.INFO.PATCHABLE:=FALSE;
    IF OPER.OD_SIZE=S_WORD (* CAN'T HAVE S_NULL OR S_RES WITH AN EXT. REF. *)
      THEN REFFILE^.INFO.DATASIZE:=SWORD
      ELSE REFFILE^.INFO.DATASIZE:=SINT;
    IF OPER.OD_VALUE.EXPREFS^.MINUS
      THEN REFFILE^.EXTSTUFF.OP:=SUBIT
      ELSE REFFILE^.EXTSTUFF.OP:=ADDIT;
    IF OPER.OD_VALUE.EXPREFS^.SYMPT^.SKIND=RELATIVE THEN
      BEGIN
      REFFILE^.EXTSTUFF2.OP:=SUBIT;
      REFFILE^.EXTSTUFF2.ADR:=0;
      REFFILE^.EXTSTUFF2.LAST:=TRUE;
      END;

    REFFILE^.EXTSTUFF.LAST:=NOT REFFILE^.EXTSTUFF2.LAST;
    IF REFFILE^.INFO.VALUEEXTEND
      THEN REFFILE^.VALUE:=OPER.OD_VALUE.OFFSET
      ELSE REFFILE^.VALUE:=ZERO32;
    PUTREFFILE;
    END (* OPER.OD_VALUE.EXPREFS <> NIL *)
$IF FALSE$
  ELSE if (pcmode=abs) and
	  (oper.OD_value.base=relative (* THIS CAN'T HAPPEN ANYMORE *)) then
    begin
    (******************** THERE IS A RELATIVE BUT NO EXTERNAL IN INDIRECT *)
    NEWREFFILE;
    reffile^.info.patchable:=FALSE;
    reffile^.info.primarytype:=relocatable;
    IF OPER.OD_SIZE=S_WORD (* CAN'T HAVE S_NULL OR S_RES WITH A REF. *)
      THEN REFFILE^.INFO.DATASIZE:=SWORD
      ELSE REFFILE^.INFO.DATASIZE:=SINT;
    if (not(fitsin16(oper.OD_value.offset)) and (REFFILE^.INFO.DATASIZE=SWORD)) then
      begin
      reffile^.info.valueextend:=true;
      code.int[bdisp div 2 + 1]:=0;
      reffile^.value:=oper.OD_value.offset;
      exwordaddr:=zero32;
      end
    else
      begin
      reffile^.info.valueextend:=false;
      reffile^.value:=zero32;
      end;
    PUTREFFILE;
    end;
$END$
  END;
END; {PROCEDURE DOLINKXTREF}


PROCEDURE PASS2PSEUDOS; { THIS DOES PSEUDO-OPS FOR PASS 2 }

VAR COUNT: SHORTINT;
    SYM, SP: STREF;
    I,COL, LEN, STARTCOL: SHORTINT;
    tlab: lstring;

PROCEDURE CHARSTRING2;
VAR DONE: BOOLEAN;
    BYTECOUNT: SHORTINT;

PROCEDURE OUTPUTCHAR;
BEGIN
  CODELENGTH:=1;
  IF (BYTECOUNT=0) AND (COUNT=0) THEN BEGIN
    LISTINST(1);
    PRINTLINE:='';
  END
  ELSE IF NOT SHORTMODE THEN LISTINST(1);
  if not contiguous then newcodeseg;
  PUNCHBYTE(ORD(LINECOPY[CURCOL]));
  LOCCTR.LONGINT := LOCCTR.LONGINT + 1;
  BYTECOUNT:=BYTECOUNT+1;
END;

BEGIN
  DONE:=FALSE;
  BYTECOUNT:=0;
  REPEAT
    CURCOL:=CURCOL+1;
    IF CURCOL<>LENGTH(LINECOPY) THEN
      IF LINECOPY[CURCOL]=CHR(39) THEN
	IF LINECOPY[CURCOL+1]=CHR(39) THEN BEGIN
	  CURCOL:=CURCOL+1;
	  CODE.BYT[1]:=39;
	  OUTPUTCHAR;
	END
	ELSE DONE:=TRUE
      ELSE BEGIN
	CODE.BYT[1]:=ORD(LINECOPY[CURCOL]);
	OUTPUTCHAR;
      END
    ELSE BEGIN
      ERROR(ERRBADSYNTAX);
      DONE:=TRUE;
    END;
  UNTIL DONE;
  IF (SIZE=2) AND  ODD(LOCCTR.LOHALF)  THEN BEGIN
    LOCCTR.LONGINT := LOCCTR.LONGINT + 1;
    BYTECOUNT:=BYTECOUNT+1;
    if not contiguous then newcodeseg;
    PUNCHBYTE(0);
  END
  ELSE IF SIZE=4 THEN WHILE BYTECOUNT MOD 4 <> 0 DO
	 BEGIN
	   LOCCTR.LONGINT := LOCCTR.LONGINT + 1;
	   if not contiguous then newcodeseg;
	   PUNCHBYTE(0);
	   BYTECOUNT:=BYTECOUNT+1;
	 END;
$if mc68881$
	(* may need larger size handling here ??? *)
$end$
  IF CURCOL<>LENGTH(LINECOPY) THEN CURCOL:=CURCOL+1;
  COUNT := COUNT + BYTECOUNT DIV SIZE;
END;


BEGIN
CASE CURROP.CODE OF

  0: { COMMENT }
    LISTINST(4);


  1: { DC }
     BEGIN
       COUNT:=0; CURCOL:=CURCOL-1;
       OPERAND1.MODE:=7; OPERAND1.REG:=4;
       LINECOPY:=PRINTLINE;
       LINECOPY[0]:=SUCC(LINECOPY[0]);
       LINECOPY[LENGTH(LINECOPY)]:=BLANK;
       REPEAT
	 CURCOL:=CURCOL+1;
	 IF LINE[CURCOL]=CHR(39) THEN CHARSTRING2
	 ELSE BEGIN
	   COUNT:=COUNT+1;
$if fpimmed$
	   if sizesuffix = 'D' then
	     begin
	       if not fpimmedexp( true, evalok, evalue, curcol ) then
		 error( errfpconstneeded );
	     end
	   else
$end$
	   EXPRESS(TRUE, EVALOK, EVALUE, CURCOL);
	   OPERAND1.VALUE:=EVALUE;
	   CODELENGTH:=SIZE;
	   CASE SIZE OF
	     1: BEGIN
		  IF NOT(FITSIN8(EVALUE.OFFSET)) AND ((EVALUE.OFFSET.HIHALF<>0)
		    OR (EVALUE.OFFSET.LOHALF<0) OR (EVALUE.OFFSET.LOHALF>255))
		  and (evalue.exprefs=nil) THEN ERROR(ERRFIELDOFLO);
		  IF NOT CONTIGUOUS THEN NEWCODESEG;
		  CODE.BYT[1]:=EVALUE.OFFSET.BYTE4;
		  DOLINKXTREF(OPERAND1, 0, FALSE, LOCCTB);
		  punchbyte(code.byt[1]);
		END;

	     2: BEGIN
		  IF NOT(FITSIN16(EVALUE.OFFSET)) AND (EVALUE.OFFSET.HIHALF<>0)
		  and (evalue.exprefs=nil) THEN ERROR(ERRFIELDOFLO);
		  CODE.INT[1]:=EVALUE.OFFSET.LOHALF;
		  IF NOT CONTIGUOUS THEN NEWCODESEG;
		  DOLINKXTREF(OPERAND1, 0, FALSE, LOCCTB);
		  PUNCHCODE;
		END;

	     4: BEGIN
		  CODE.INT[1]:=EVALUE.OFFSET.HIHALF;
		  CODE.INT[2]:=EVALUE.OFFSET.LOHALF;
		  IF NOT CONTIGUOUS THEN NEWCODESEG;
		  DOLINKXTREF(OPERAND1, 0, FALSE, LOCCTB);
		  PUNCHCODE;
		END;
$if fpimmed$
	     8: begin
		  with evalue.offset do
		    begin
		      code.int[ 1 ] := fltptwd1;
		      code.int[ 2 ] := fltptwd2;
		      code.int[ 3 ] := fltptwd3;
		      code.int[ 4 ] := fltptwd4;
		      if not contiguous then newcodeseg;
		      dolinkxtref( operand1, 0, false, locctb);
		      punchcode;
		    end;
		end;
	     12: begin
			(* ???   error( errfpinternalerr );  *)
		 end;
$end$
	   END;
	   IF (LENGTH(PRINTLINE)>0) OR NOT(SHORTMODE) THEN LISTINST(1);
	   IF COUNT>0 THEN PRINTLINE:='';
	   LOCCTR.LONGINT := LOCCTR.LONGINT + SIZE;
	 END
       UNTIL LINE[CURCOL]<>',';
       IF LINE[CURCOL]<>' ' THEN ERROR(ERREOLEXP);
     END; {OF DC PROCESSING}

  2: { DS }
     BEGIN
       EXPRESS(TRUE, EVALOK, EVALUE, CURCOL);
       IF LINE[CURCOL]<>BLANK THEN ERROR(ERREOLEXP);
       CODELENGTH:=2;
       CODE.INT[1]:=EVALUE.OFFSET.LOHALF;
       LISTINST(1);  { NORMAL LINE LIST }
       IF (EVALOK=OK1) AND (EVALUE.EXPREFS=NIL) THEN
	 if evalue.base=absolut then begin
	   IF CONTIGUOUS THEN ENDOFCODE:=LOCCTR.LONGINT;
	   LOCCTR.LONGINT:=SIZE*EVALUE.OFFSET.LONGINT
		+LOCCTR.LONGINT;
	   CONTIGUOUS:=FALSE;
	 end
	 else error(errbadbase)
       ELSE
	 begin
	 if (evalue.exprefs <> NIL) then
	   error(errextrefs);
	 if evalok = ok2 then
	   ERROR(ERRBADEXPR);
	 end;
     END;

  3: {END} LISTINST(4);

  4: {MNAME}
     LISTINST(4);

  5: {EQU}
     BEGIN
     tlab:=lab;
     LOOKUPSYMBOL(SYM);
     IF CHECKREGS THEN BEGIN
       CODE.INT[1]:=0;
       CODE.INT[2]:=CHECKREGNO;
     END
     ELSE IF CHECKSPREGS THEN BEGIN
       CODE.INT[1]:=0;
       CODE.INT[2]:=CHECKREGNO;
     END
     ELSE BEGIN
       EXPRESS(TRUE, EVALOK, EVALUE, CURCOL);
       CODE.INT[1]:=EVALUE.OFFSET.HIHALF;
       CODE.INT[2]:=EVALUE.OFFSET.LOHALF;
     END;
     if (tlab<>'') and (sym<>nil) then
       IF (CODE.INT[1]<>SYM^.SVALUE.HIHALF) OR
	  (CODE.INT[2]<>SYM^.SVALUE.LOHALF) THEN ERROR(ERRPHASE);
     CODELENGTH:=4;
     IF LINE[CURCOL]<>' ' THEN ERROR(ERREOLEXP);
     LISTINST(2);
     END;


  6: { SRC }
     LISTINST(4);

  8: {LIST}
     BEGIN
     LISTINST(4);
     LISTING:=TRUE;
     END;

  9: { LLEN }
      BEGIN
	EXPRESS(true, EVALOK, EVALUE, CURCOL);
	IF (EVALUE.EXPREFS<>NIL) OR (EVALOK<>OK1) OR
	   NOT((EVALUE.OFFSET.HIHALF=0) AND
	       (EVALUE.OFFSET.LOHALF>=32) AND
	       (EVALUE.OFFSET.LOHALF<=132)) THEN ERROR(ERRBADEXPR)
	else LLEN:=EVALUE.OFFSET.LOHALF;
	listinst(4);
      END;


  10: { NOLIST, NOL }
     BEGIN
     LISTINST(4);
     LISTING:=FALSE;
     END;

  11: { NOOBJ}
      LISTINST(4);

  12: { NOPAGE }
     BEGIN
      LISTINST(4);
      LINESPERPAGE:=32767;
     END;

  13,15: { ORG, RORG }
      BEGIN
	EXPRESS(true, EVALOK, EVALUE, CURCOL);
	IF (EVALOK=OK1) AND (EVALUE.EXPREFS=NIL)  THEN BEGIN
	  IF CONTIGUOUS THEN BEGIN
	    IF LOCCTR.LONGINT>ORIGIN THEN BEGIN
	      TEXTSIZE:=LOCCTR.LONGINT-ORIGIN;
	      NEWTEXTREC;
	    END
	  END
	  ELSE
	    IF ENDOFCODE > ORIGIN THEN BEGIN
	      TEXTSIZE:=ENDOFCODE-ORIGIN;
	      NEWTEXTREC;
	    END;
	  if pcmode=rel then
	    if locctr.longint > highaddr.longint then highaddr:=locctr;
	  LOCCTR:=EVALUE.OFFSET;
	  ORIGIN:=EVALUE.OFFSET.LONGINT;
	  if odd(origin) then
	     error(erroddorg);
	  CONTIGUOUS:=TRUE;
	  IF SIZE=4 THEN ORGMODE:=LONGFWDS ELSE ORGMODE:=SHORTFWDS;
	  IF CURROP.CODE=13 THEN PCMODE:=ABS ELSE BEGIN
	    PCMODE:=REL;
	    IF LOCCTR.LONGINT < LOWRORG.LONGINT THEN LOWRORG:=LOCCTR;
	  END;
	  IF LINE[CURCOL]<>' ' THEN ERROR(ERREOLEXP);
	END
	else error(errbadexpr);
	LISTINST(3);
      END;

  14: { PAGE }
	if superlist and listing then CURRENTLINE:=LINESPERPAGE+10;

  17: { SPC }
      BEGIN
	EXPRESS(TRUE,EVALOK,EVALUE,CURCOL);
	IF (EVALOK<>NOK) and (evalue.exprefs=nil)
	   and (evalue.base=absolut) THEN
	  BEGIN
	    if line[curcol]<>' ' then begin
	      error(erreolexp);
	      listinst(4);
	    end
	    else begin
	      PRINTLINE:=' ';
	      FOR COUNT:=1 TO EVALUE.OFFSET.LOHALF DO
		  LISTINST(4);
	    end;
	  END
	ELSE BEGIN
	  error(errbadexpr);
	  listinst(4);
	end;
      END;

  18: { TTL }
      BEGIN
	CODELENGTH:=LENGTH(LINE)-CURCOL;
	IF CODELENGTH>60 THEN CODELENGTH:=60;
	TITLE[0]:=CHR(CODELENGTH);
	FOR I:=1 TO CODELENGTH DO TITLE[I]:=LINE[CURCOL+I-1];
      END;

  19: { COM }
      LISTINST(4);

  20: { DEF }
      BEGIN
      TRY
	REPEAT
	  IF NOT(LINE[CURCOL] IN ['A'..'Z','_','@@'])  THEN {leading '_','@@'}
	    ESCAPE(BADOPS);                                {jch 08/26/86}
	  STARTCOL:=CURCOL;
	  REPEAT
	    CURCOL:=CURCOL+1;
	  UNTIL CHTYPE[LINE[CURCOL]]=SPECIAL;
	  LAB:=COPY(LINE, STARTCOL, CURCOL-STARTCOL);
	  LOOKUPSYMBOL(SP);
	  IF SP=NIL THEN BEGIN
	    ERROR(ERRUNDEFSYM);
	    ESCAPE(OPSOK);
	  END;
	  IF SP^.DEFINED<=0 THEN BEGIN ERROR(ERRUNDEFSYM);
	    ESCAPE(OPSOK) END;
	  IF (SP^.EXT) OR (SP^.SEXTPTR<>NIL)  THEN BEGIN
	    ERROR(ERREXTREFS);
	    ESCAPE(OPSOK);
	  END;
	  TRY
	    NEWBYTES(DEFFILE,SIZEOF(DEFREC)-80+LENGTH(LAB))
	  RECOVER BEGIN
	    if escapecode=-2 then begin
	      WRITELN(LP,'MEMORY OVERFLOW!');
	      LPCHECK;           { 3/2/84 }
	      IF LISTNAME<>'CONSOLE:' THEN WRITELN('MEMORY OVERFLOW!');
	      ESCAPE(-1);
	    end else escape(escapecode);
	  END;
	  DEFFILE^.LOCATION:=SP^.SVALUE;
	  IF SP^.EXT AND (SP^.SVALUE.LOHALF=0) AND (SP^.SVALUE.HIHALF=0)
	    THEN DEFFILE^.DEFTYPE:=GLOBAL
	    ELSE IF SP^.SKIND=ABSOLUT THEN DEFFILE^.DEFTYPE:=ABSOLUTE
	    ELSE IF SP^.SKIND=RELATIVE THEN DEFFILE^.DEFTYPE:=RELOCATABLE
	      ELSE ESCAPE(BADOPS);
	  DEFFILE^.IDNAME:=SP^.SNAME;
	  IF DEFHEAD=NIL THEN DEFHEAD:=DEFFILE
	    ELSE DEFTAIL^.DEFNEXT:=DEFFILE;
	  DEFTAIL:=DEFFILE;
	  DEFFILE^.DEFNEXT:=NIL;
	  DEFCTR:=DEFCTR+1;
	  IF LINE[CURCOL]=BLANK THEN ESCAPE(OPSOK);
	  IF LINE[CURCOL]<>COMMA THEN ESCAPE(BADOPS);
	  CURCOL:=CURCOL+1;
	UNTIL FALSE;
      RECOVER
	IF ESCAPECODE=BADOPS THEN ERROR(ERRBADSYNTAX)
	ELSE IF ESCAPECODE<>OPSOK THEN ESCAPE(ESCAPECODE);
	LISTINST(4);
    END;


  21,22: { REFA, REFR } LISTINST(4); { NO PASS 2 ACTION }

  25,26,27,28: { LMODE, SMODE, RMODE, MLOAD }
      LISTINST(4);

  29: { NOSYMS }
      BEGIN
	LISTSYMS:=FALSE;
	LISTINST(4);
      END;

  30: { INCLUDE }
      BEGIN
	LISTINST(4);
	INCLUDEINSTR;
      END;

  31: { SPRINT }
      BEGIN
	SHORTMODE:=TRUE;
	LISTINST(4);
      END;

  32: { LPRINT }
      BEGIN
	SHORTMODE:=FALSE;
	LISTINST(4);
      END;

  33: { START }
      BEGIN
	EXPRESS(TRUE, EVALOK, EVALUE, CURCOL);
	IF (EVALUE.EXPREFS<>NIL) OR (EVALOK<>OK1) THEN BEGIN
	  CODE.INT[1]:=0;
	  CODE.INT[2]:=0;
	END
	ELSE BEGIN
	  CODE.INT[1]:=EVALUE.OFFSET.HIHALF;
	  CODE.INT[2]:=EVALUE.OFFSET.LOHALF;
	  IF LINE[CURCOL]<>' ' THEN ERROR(ERREOLEXP);
	END;
	CODELENGTH:=4;
	LISTINST(2);
      END;

  34: { DECIMAL }
      listinst(4);


END; { OF CASE }
END; { OF PROCEDURE }

PROCEDURE CODEGEN;
VAR I         :SHORTINT;
    LINKPATCH :BOOLEAN;
    EXWORDADDR:WORD32;
    DUMMY: SHORTINT; { KLUDGE FOR COMPILER BUG}
    SAVEREGY, SAVEMODE: 0..7;



PROCEDURE BUILDEA(OPER:OPERAND;CDISP:SHORTINT;VAR EAWORD1:IDXWORD);
VAR
  EADISP: SHORTINT;
BEGIN  {BUILDEA}
CODE.TYPE4.MODE:=OPER.MODE;
CODE.TYPE2.REGY:=OPER.REG;
CASE CODE.TYPE4.MODE OF
  0,1,2,3,4: BEGIN {NO ACTION} END; {DN, AN, (AN), (AN)+, -(AN)}
  5:BEGIN                          {D(AN)}
    CODE.INT[CDISP]:=OPER.VALUE.OFFSET.LOHALF;
    CODELENGTH:=CODELENGTH+2;
    DOLINKXTREF(OPER,CDISP*2-2,LINKPATCH, EXWORDADDR);
    END;
  6:BEGIN                          {D(AN,RI)}
    CODELENGTH:=CODELENGTH+2;

    EAWORD1.DA   :=OPER.INDEXMODE=ADDRS;
    EAWORD1.REGI :=OPER.INDEX;
    EAWORD1.WL   :=OPER.INDEXSIZE=LONG;
    EAWORD1.SCALE:=OPER.INDEXSCALE;
    EAWORD1.FULL :=OPER.FULL_FORMAT;
    IF EAWORD1.FULL THEN
      BEGIN
      EAWORD1.BASE_SUPPRESS :=OPER.BASE_SUPPRESS ;
      EAWORD1.INDEX_SUPPRESS:=OPER.INDEX_SUPPRESS;
      EAWORD1.BD_SIZE       :=OPER.BD_SIZE       ;
      EAWORD1.FILL          :=OPER.FILL          ;
      EAWORD1.POST_INDEXED  :=OPER.POST_INDEXED  ;
      EAWORD1.OD_SIZE       :=OPER.OD_SIZE       ;
      EADISP:=CDISP;
      IF      OPER.BD_SIZE=S_LONG THEN
	BEGIN
	EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.   VALUE.OFFSET.HIHALF;
	EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.   VALUE.OFFSET.LOHALF;
	END
      ELSE IF OPER.BD_SIZE=S_WORD THEN
	BEGIN
	EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.   VALUE.OFFSET.LOHALF;
	END;
      IF      OPER.OD_SIZE=S_LONG THEN
	BEGIN
	EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.OD_VALUE.OFFSET.HIHALF;
	EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.OD_VALUE.OFFSET.LOHALF;
	END
      ELSE IF OPER.OD_SIZE=S_WORD THEN
	BEGIN
	EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.OD_VALUE.OFFSET.LOHALF;
	END;
      CODELENGTH:=CODELENGTH+(EADISP-CDISP)*2;
      END
    ELSE
      EAWORD1.DISP:=OPER.VALUE.OFFSET.BYTE4;

    DOLINKXTREF(OPER,CDISP*2-1,LINKPATCH, EXWORDADDR);
    END;
  7:BEGIN
    CODELENGTH:=CODELENGTH+2;
    CASE CODE.TYPE2.REGY OF
      0:BEGIN
	CODE.INT[CDISP]:=OPER.VALUE.OFFSET.LOHALF; {ABS 16 BIT ADDR.}
	DOLINKXTREF(OPER,CDISP*2-2,LINKPATCH, EXWORDADDR);
	END;
      1:BEGIN                                      {ABS 32 BIT ADDR.}
	CODE.INT[CDISP]:=OPER.VALUE.OFFSET.HIHALF;
	CODE.INT[CDISP+1]:=OPER.VALUE.OFFSET.LOHALF;
	CODELENGTH:=CODELENGTH+2;
	DOLINKXTREF(OPER,CDISP*2-2,LINKPATCH, EXWORDADDR);
	END;
      2:BEGIN                                       {PC + 16 BIT DISP}
	EXWORDADDR.LONGINT := OPER.VALUE.OFFSET.LONGINT +
			      2 - LOCCTR.LONGINT - CDISP*2;
	OPER.VALUE.OFFSET:=EXWORDADDR;
	CODE.INT[CDISP]:=EXWORDADDR.LOHALF;
	DOLINKXTREF(OPER,CDISP*2-2,LINKPATCH, EXWORDADDR);
	IF NOT FITSIN16(EXWORDADDR) THEN ERROR(ERRFIELDOFLO);
	END;
      3:BEGIN                            {PC + INDEX REG + 8 BIT DISP}
	IF OPER.FULL_FORMAT AND OPER.BASE_SUPPRESS THEN
	  EXWORDADDR.LONGINT := OPER.VALUE.OFFSET.LONGINT
	ELSE
	  BEGIN
	  EXWORDADDR.LONGINT := OPER.VALUE.OFFSET.LONGINT +
				2 - LOCCTR.LONGINT - CDISP*2;
	  END;
	OPER.VALUE.OFFSET:=EXWORDADDR;

	EAWORD1.DA   :=OPER.INDEXMODE=ADDRS;
	EAWORD1.REGI :=OPER.INDEX;
	EAWORD1.WL   :=OPER.INDEXSIZE=LONG;
	EAWORD1.SCALE:=OPER.INDEXSCALE;
	EAWORD1.FULL :=OPER.FULL_FORMAT;
	IF EAWORD1.FULL THEN
	  BEGIN
	  EAWORD1.BASE_SUPPRESS :=OPER.BASE_SUPPRESS ;
	  EAWORD1.INDEX_SUPPRESS:=OPER.INDEX_SUPPRESS;
	  EAWORD1.BD_SIZE       :=OPER.BD_SIZE       ;
	  EAWORD1.FILL          :=OPER.FILL          ;
	  EAWORD1.POST_INDEXED  :=OPER.POST_INDEXED  ;
	  EAWORD1.OD_SIZE       :=OPER.OD_SIZE       ;
	  EADISP:=CDISP;
	  IF      OPER.BD_SIZE=S_LONG THEN
	    BEGIN
	    EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.   VALUE.OFFSET.HIHALF;
	    EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.   VALUE.OFFSET.LOHALF;
	    END
	  ELSE IF OPER.BD_SIZE=S_WORD THEN
	    BEGIN
	    EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.   VALUE.OFFSET.LOHALF;
	    END;
	  IF      OPER.OD_SIZE=S_LONG THEN
	    BEGIN
	    EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.OD_VALUE.OFFSET.HIHALF;
	    EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.OD_VALUE.OFFSET.LOHALF;
	    END
	  ELSE IF OPER.OD_SIZE=S_WORD THEN
	    BEGIN
	    EADISP:=EADISP+1; CODE.INT[EADISP]:=OPER.OD_VALUE.OFFSET.LOHALF;
	    END;
	  CODELENGTH:=CODELENGTH+(EADISP-CDISP)*2;
	  END
	ELSE
	  EAWORD1.DISP:=OPER.VALUE.OFFSET.BYTE4;

	DOLINKXTREF(OPER,CDISP*2-1,LINKPATCH, EXWORDADDR);
	IF (NOT OPER.FULL_FORMAT AND NOT FITSIN8(EXWORDADDR)) OR
	   (    OPER.FULL_FORMAT AND NOT FITSIN16(EXWORDADDR) AND
	       (OPER.BD_SIZE=S_WORD)) THEN
	  ERROR(ERRFIELDOFLO);
	END;
      4:{IMMEDIATE DATA}
	BEGIN
$if mc68881$
		      (* need to handle larger immed. opds ??? *)
$end$
	IF      SIZE = 1 THEN
	  CODE.INT[CDISP]:=OPER.VALUE.OFFSET.BYTE4
	ELSE IF SIZE = 2 THEN
	    CODE.INT[CDISP]:=OPER.VALUE.OFFSET.LOHALF
$if fpimmed$
	ELSE if size = 4 then
$end$
	  BEGIN
	  CODE.INT[CDISP]:=OPER.VALUE.OFFSET.HIHALF;
	  CODE.INT[CDISP+1]:=OPER.VALUE.OFFSET.LOHALF;
	  CODELENGTH:=CODELENGTH+2;
$if fpimmed$
	  end
	else if size = 8 then
	  with oper.value.offset do
	    begin
	    code.int[cdisp] := fltptwd1;
	    code.int[cdisp+1] := fltptwd2;
	    code.int[cdisp+2] := fltptwd3;
	    code.int[cdisp+3] := fltptwd4;
	    codelength := codelength + 6;
	    end
	else
	  begin
	    (*  ???  error( errfpinternalerr );  *)
$end$
	  END;
	DOLINKXTREF(OPER,CDISP*2-2+ORD(SIZE=1), LINKPATCH, EXWORDADDR)
	END;
      5,6,7: {CCR, SR, USP}
	BEGIN CODE.TYPE2.REGY:=4; CODELENGTH:=CODELENGTH-2; END;
      END; (* CASE CODE.TYPE2.REGY *)
    END; (* CASE = 7 *)
$if mc68881$
  8:                     (* flt. pt. register FPn operand *)
    begin
    error( errfpregnotallowed );
    end;
  9:                     (* flt. pt. system register operand *)
    begin
    error( errfpsysregnotallowed );
    end;
$end$
  END; (* CASE *)
END; {BUILDEA}


$include 'M68KFPCDG'$

BEGIN {CODEGEN}
  IF NOT CONTIGUOUS THEN NEWCODESEG;
  CODELENGTH:=2;
  LINKPATCH:=FALSE;
  CODE.INT[1]:=CURROP.CODE;

$if mc68881$
if (currop.class >= fpbase) and (currop.class <= fptop) then
  fpcodegen
else
$end$
CASE CURROP.CLASS OF
1: {ABCD,SBCD}          {DY,DX}
   BEGIN                {-(AY),-(AX)}
     CODE.TYPE2.REGX:=OPERAND2.REG;
     CODE.TYPE2.REGY:=OPERAND1.REG;
     CODE.TYPE2.B3:= OPERAND1.MODE = 4;;
   END;

2,5: {ADD,ADDA,SUB,SUBA}{AND,OR}
  BEGIN
    IF MEMALT(OPERAND2) THEN {DN,<EA>}
      BEGIN
	CODE.TYPE2.OPM1:=(SIZE DIV 2)+4;
	CODE.TYPE2.REGX:=OPERAND1.REG;
	BUILDEA(OPERAND2,2,CODE.IDX[2]);
      END
      ELSE
      BEGIN
	IF OPERAND2.MODE = 1 THEN
	    CODE.TYPE2.OPM1:=(SIZE * 2)-1 {<EA>,AN}
	  ELSE
	    CODE.TYPE2.OPM1:=SIZE DIV 2;   {<EA>,DN}
	CODE.TYPE2.REGX:=OPERAND2.REG;
	BUILDEA(OPERAND1,2,CODE.IDX[2]);
      END;
  END;

3: {ADDQ,SUBQ}
  BEGIN                      {#<DATA>,<EA>}
    CODE.TYPE3.SIZE:=SIZE DIV 2;
    BUILDEA(OPERAND2,2,CODE.IDX[2]);
    CODE.TYPE2.REGX:=OPERAND1.VALUE.OFFSET.BYTE4 MOD 8;
  END;

4: {ADDX,SUBX}
  BEGIN                      {DY,DX}
    CODE.TYPE2.REGX:=OPERAND2.REG; {-(AY),-(AX)}
    CODE.TYPE2.REGY:=OPERAND1.REG;
    CODE.TYPE3.SIZE:=SIZE DIV 2;
    CODE.TYPE2.B3:=OPERAND1.MODE = 4;
  END;

6: {ASL,ASR,LSL,LSR,ROL,ROR,ROXL,ROXR}{ASSUME MEM FORMAT IS SUPPLIED}
  BEGIN
    IF OPERAND1.MODE = 0 THEN
      BEGIN                {DX,DY}
	CODE.TYPE2.REGX:=OPERAND1.REG;
	CODE.TYPE3.SIZE:=SIZE DIV 2;
	CODE.TYPE2.REGY:=OPERAND2.REG;
	CODE.TYPE2.B5:=TRUE;
      END
      ELSE
      IF NOT MEMALT(OPERAND1) THEN
	BEGIN              {#<DATA>,DY}
	  CODE.TYPE2.REGX:=OPERAND1.VALUE.OFFSET.BYTE4 MOD 8;
	  CODE.TYPE3.SIZE:=SIZE DIV 2;
	  CODE.TYPE2.REGY:=OPERAND2.REG;
	  CODE.TYPE2.B5:=FALSE;
	END
	ELSE
	BEGIN              {<EA>}
	  BUILDEA(OPERAND1,2,CODE.IDX[2]);
	END;
  END;

7: {Bcc (BRANCH ON CONDITION) ,BRA,BSR}  {<LABEL>}
  IF OPERAND1.SIZE = 1 THEN                       {.BYTE}
    CODE.BYT[2]:=OPERAND1.VALUE.OFFSET.BYTE4
  ELSE
    BEGIN          { .WORD or .LONG }
    IF OPERAND1.SIZE = 2 THEN
      BEGIN
      CODE.BYT[2]:=0;
      CODE.INT[2]:=OPERAND1.VALUE.OFFSET.LOHALF;
      CODELENGTH:=CODELENGTH+2;
      END
    ELSE (* MUST BE OPERAND1.SIZE=4 *)
      BEGIN
      CODE.BYT[2]:=255;
      CODE.INT[2]:=OPERAND1.VALUE.OFFSET.HIHALF;
      CODE.INT[3]:=OPERAND1.VALUE.OFFSET.LOHALF;
      CODELENGTH:=CODELENGTH+4;
      END;
    IF ( OPERAND1.VALUE.EXPREFS <> NIL) OR
       ((OPERAND1.VALUE.BASE=ABSOLUT ) AND (PCMODE=REL)) or
       ((operand1.value.base=relative) and (pcmode=abs)) THEN
      BEGIN
      OPERAND1.MODE:=7; OPERAND1.REG:=2;
      IF OPERAND1.SIZE=2 THEN LINKPATCH:=TRUE;
      DOLINKXTREF(OPERAND1,2,LINKPATCH, EXWORDADDR);
      END;
    END;

8: {BCHG, BCLR, BSET, BTST}
  IF OPERAND1.MODE = 0 THEN  {DN,<EA>}
    BEGIN
      CODE.TYPE2.REGX:=OPERAND1.REG;
      BUILDEA(OPERAND2,2,CODE.IDX[2]);
    END
    ELSE                     {#<DATA>,<EA>}
    BEGIN
      CODE.TYPE2.REGX:=4;
      CODE.TYPE3.B8:=FALSE;
      BUILDEA(OPERAND2,3,CODE.IDX[3]);
      size:=1;
      code.int[2]:=operand1.value.offset.byte4;
      dolinkxtref(operand1,3,false, exwordaddr);
      codelength:=codelength+2;
    END;

 9,19: {CHK, DIVS, DIVU, MULS, MULU} {LEA  <EA>,AN}
   BEGIN
     CODE.TYPE2.REGX:=OPERAND2.REG;  {<EA>,DN}
     BUILDEA(OPERAND1,2,CODE.IDX[2]);
   END;

 10: {CLR, NEG, NEGX, NOT, TST}
   BEGIN                      {<EA>}
     CODE.TYPE3.SIZE:=SIZE DIV 2;
     BUILDEA(OPERAND1,2,CODE.IDX[2]);
   END;
 11: {CMP,CMPA}
   BEGIN
     IF OPERAND2.MODE = 1 THEN
	 CODE.TYPE2.OPM1:=(SIZE * 2)-1 {<EA>,AN}
       ELSE
	 CODE.TYPE2.OPM1:=SIZE DIV 2;   {<EA>,DN}
     CODE.TYPE2.REGX:=OPERAND2.REG;
     BUILDEA(OPERAND1,2,CODE.IDX[2]);
   END;

 12: { STOP #XXXX }
   BEGIN
     CODE.INT[2]:=OPERAND1.VALUE.OFFSET.LOHALF;
     DOLINKXTREF(OPERAND1, 2, FALSE, EXWORDADDR);
     CODELENGTH:=CODELENGTH+2;
   END;

 13: {DBCC,DBRA} {TEST CONDITION DECREMENT & BRANCH}
   BEGIN                       {DN,<LABEL>}
     CODE.TYPE2.REGY:=OPERAND1.REG;
     CODE.INT[2]:=OPERAND2.VALUE.OFFSET.LOHALF;
     CODELENGTH:=CODELENGTH+2;
     OPERAND2.SIZE:=2;  (* KLUDGES FOR BRANCHES *)
     OPERAND2.MODE:=7;  (* KLUDGES FOR BRANCHES *)
     OPERAND2.REG :=2;  (* KLUDGES FOR BRANCHES *)
     DOLINKXTREF(OPERAND2,2,TRUE,EXWORDADDR);
   END;

 14: {EOR} {DN,<EA>}
   BEGIN
     CODE.TYPE2.OPM1:=(SIZE DIV 2)+4;
     CODE.TYPE2.REGX:=OPERAND1.REG;
     BUILDEA(OPERAND2,2,CODE.IDX[2]);
   END;

 15: {EXG} {RX,RY}
   BEGIN
     CODE.TYPE2.REGX:=OPERAND1.REG;
     CODE.TYPE2.REGY:=OPERAND2.REG;
     CODE.TYPE4.MODE:=OPERAND2.MODE;
     IF OPERAND1.MODE = OPERAND2.MODE
       THEN CODE.TYPE3.SIZE:=1
       ELSE CODE.TYPE3.SIZE:=2;
   END;

 16: {EXT}  {DN}
   BEGIN
     CODE.TYPE2.REGY:=OPERAND1.REG;
   END;

 17,25: {JMP, JSR, PEA}{NBCD, SCC (SET BY CONDITION), TAS}  {<EA>}
   BEGIN
     IF (CURROP.CLASS=17) AND (CURROP.NAME<>'PEA      ') THEN LINKPATCH:=TRUE;
     BUILDEA(OPERAND1,2,CODE.IDX[2]);
   END;

 18: {ADDI,CMPI,SUBI}
   BEGIN           {#<DATA>,<EA>}
     CODE.TYPE3.SIZE:=SIZE DIV 2;
     BUILDEA(OPERAND1,2,CODE.IDX[2]);
     IF SIZE = 4 THEN BUILDEA(OPERAND2,4,CODE.IDX[4])
		 ELSE BUILDEA(OPERAND2,3,CODE.IDX[3]);
   END;

  20: {LINK}  {AN,#<DISP>}
   BEGIN
     CODE.TYPE2.REGY:=OPERAND1.REG;
     IF SIZE=2 THEN
       BEGIN
       code.int[2]:=operand2.value.offset.lohalf;
       dolinkxtref(operand2, 2, false, exwordaddr);
       END
     ELSE
       BEGIN
       code.int[2]:=operand2.value.offset.hihalf;
       code.int[3]:=operand2.value.offset.lohalf;
       dolinkxtref(operand2, 2, false, exwordaddr);
       END;
     codelength:=codelength+SIZE;
   END;

 21: {MOVE, MOVEA}  {<EA>,<EA>}
   IF (OPERAND2.MODE = 7) AND (OPERAND2.REG > 4) THEN
     BEGIN                  {<EA>,SPECIAL REGISTER}
       CODE.TYPE3.OPCODE:=4;
       CASE OPERAND2.REG OF
       5: BEGIN             {CCR}
	    CODE.TYPE2.REGX:=2;
	    CODE.TYPE2.OPM1:=3;
	    BUILDEA(OPERAND1,2,CODE.IDX[2]);
	  END;
       6: BEGIN             {SR}
	    CODE.TYPE2.REGX:=3;
	    CODE.TYPE2.OPM1:=3;
	    BUILDEA(OPERAND1,2,CODE.IDX[2]);
	  END;
       7: BEGIN             {USP}
	    CODE.TYPE2.REGX:=7;
	    CODE.TYPE2.OPM1:=1;
	    BUILDEA(OPERAND1,2,CODE.IDX[2]);
	    CODE.TYPE4.MODE:=4; (* FIX UP MODE FIELD *)
	  END;
       END;

     END {OP2 = 7 AND REG > 4}
     ELSE
     IF (OPERAND1.MODE = 7) AND (OPERAND1.REG > 4) THEN
       BEGIN                 {SPECIAL REGISTER,<EA>}
	 CODE.TYPE3.OPCODE:=4;
	 CASE OPERAND1.REG OF
	 5: BEGIN            {CCR -- allowed on 68010/12 }
	      code.type2.regx:=1;
	      code.type2.opm1:=3;
	    END;
	 6: BEGIN            {SR}
	      CODE.TYPE2.REGX:=0;
	      CODE.TYPE2.OPM1:=3;
	    END;
	 7: BEGIN            {USP}
	      CODE.TYPE2.REGX:=7;
	      CODE.TYPE2.OPM1:=1;
	    END;
	 END;
	 BUILDEA(OPERAND2,2,CODE.IDX[2]);
	 IF OPERAND1.REG = 7 THEN CODE.TYPE4.MODE:=5;
       END {OP1 = 7 AND REG > 4}
       ELSE
       BEGIN                {<EA>,<EA>}
	 IF SIZE = 1 THEN CODE.TYPE2.MSIZE:=1
	   ELSE
	     IF SIZE =2 THEN CODE.TYPE2.MSIZE:=3
			ELSE CODE.TYPE2.MSIZE:=2;
	 BUILDEA(OPERAND1,2,CODE.IDX[2]);
	 SAVEREGY:=CODE.TYPE2.REGY;
	 SAVEMODE:=CODE.TYPE4.MODE;
	 DUMMY:=2+(OPERAND1.SIZE DIV 2);
	 BUILDEA(OPERAND2,DUMMY,CODE.IDX[DUMMY]);
	 CODE.TYPE2.REGX:=CODE.TYPE2.REGY;
	 CODE.TYPE2.OPM1:=CODE.TYPE4.MODE;
	 CODE.TYPE2.REGY:=SAVEREGY;
	 CODE.TYPE4.MODE:=SAVEMODE;
       END;

 22: {MOVEM} {<LIST>,<EA> OR <EA>,<LIST>  LIST WILL BE IMMED DATA}
   BEGIN
     CODELENGTH:=4;
     CODE.TYPE5.B6:= SIZE = 4;
     CODE.TYPE4.B10:= (OPERAND2.MODE = 7) AND (OPERAND2.REG = 4);
     IF CODE.TYPE4.B10 = FALSE THEN
       BEGIN                       {<LIST>,<EA>}
	 CODE.INT[2]:=OPERAND1.VALUE.OFFSET.LOHALF;
	 BUILDEA(OPERAND2,3,CODE.IDX[3]);
       END
       ELSE
       BEGIN                       {<EA>,<LIST>}
	 CODE.INT[2]:=OPERAND2.VALUE.OFFSET.LOHALF;
	 BUILDEA(OPERAND1,3,CODE.IDX[3]);
       END;
    END;

 23: {MOVEP} {DX,D(AY)  OR D(AY),DX}
    BEGIN
      IF OPERAND1.MODE = 0 THEN
	BEGIN {DX,D(AY)}
	  CODE.TYPE2.REGX:=OPERAND1.REG;
	  BUILDEA(OPERAND2,2,CODE.IDX[2]);
	  CODE.TYPE2.OPM1:=6;
	END
	ELSE
	BEGIN
	  CODE.TYPE2.REGX:=OPERAND2.REG;
	  BUILDEA(OPERAND1,2,CODE.IDX[2]);
	  CODE.TYPE2.OPM1:=4;
	END;
      CODE.TYPE4.MODE:=1;
      IF SIZE = 4 THEN CODE.TYPE2.OPM1:=CODE.TYPE2.OPM1+1;
   END;


 24: {MOVEQ} {#<DATA>,DN}
   BEGIN
     CODE.TYPE2.REGX:=OPERAND2.REG;
     CODE.BYT[2]:=OPERAND1.VALUE.OFFSET.BYTE4;
   END;

 26: {NOP,RESET,RTE,RTR,RTS,STOP,TRAPV}
   BEGIN  END;

 27: {ANDI,EORI,ORI} {#<DATA>,<EA>}
   BEGIN
     CODE.TYPE3.SIZE:= SIZE DIV 2;
     BUILDEA(OPERAND1,2,CODE.IDX[2]);
     IF SIZE = 4 THEN BUILDEA(OPERAND2,4,CODE.IDX[4])
		 ELSE BUILDEA(OPERAND2,3,CODE.IDX[3]);
     IF OPERAND2.MODE = 7 THEN
       BEGIN
	 IF OPERAND2.REG = 5 THEN CODE.TYPE3.SIZE:=0; {CCR}
	 IF OPERAND2.REG = 6 THEN CODE.TYPE3.SIZE:=1; {SR}
       END;
   END;

 28,30: {SWAP}{UNLK}  {REG}
   CODE.TYPE2.REGY:=OPERAND1.REG;

 29: {TRAP}
   BEGIN
   CODE.TYPE5.VECTOR:=OPERAND1.VALUE.OFFSET.BYTE4 MOD 16;
   IF SIZE=2 THEN
     BEGIN
     CODE.INT[2]:=OPERAND2.VALUE.OFFSET.LOHALF;
     CODELENGTH:=CODELENGTH+2;
     END;
   END;

 31: {CMPM} {(AY)+,(AX)+}
   BEGIN
     CODE.TYPE3.SIZE:=SIZE DIV 2;
     CODE.TYPE2.REGX:=OPERAND2.REG;
     CODE.TYPE2.REGY:=OPERAND1.REG;
   END;

 32: { MOVEC }
   BEGIN
     CODELENGTH:=4;
     CODE.INT[2]:=0;
     IF (OPERAND1.MODE<=1) THEN CODE.INT[1]:=CODE.INT[1]+1;
     IF ODD(CODE.INT[1]) THEN BEGIN { GENERAL TO CONTROL REG }
       CODE.IDX[2].DA:=OPERAND1.MODE=1;
       CODE.IDX[2].REGI:=OPERAND1.REG;
       CASE OPERAND2.REG OF
	 7:  { USP  } I:=HEX('800');
	 8:  { DFC  } I:=HEX('001');
	 9:  { SFC  } I:=HEX('000');
	 10: { VBR  } I:=HEX('801');
	 11: { MSP  } I:=HEX('803');
	 12: { ISP  } I:=HEX('804');
	 13: { CACR } I:=HEX('002');
	 14: { CAAR } I:=HEX('802');
       { Added 12/26/89 for the new '040 registers : }
	 15: { TC }   I:= HEX('003');
	 16: { ITT0 } I:= hex('004');
	 17: { ITT1 } I:= hex('005');
	 18: { DTT0 } I:= hex('006');
	 19: { DTT1 } I:= hex('007');
	 20: { MMUSR } I:= hex('805');
	 21: { URP } I:= hex('806');
	 22: { SRP } I:= hex('807');
       END;
     END
     ELSE BEGIN
       CODE.IDX[2].DA:=OPERAND2.MODE=1;
       CODE.IDX[2].REGI:=OPERAND2.REG;
       CASE OPERAND1.REG OF
	 7:  { USP  } I:=HEX('800');
	 8:  { DFC  } I:=HEX('001');
	 9:  { SFC  } I:=HEX('000');
	 10: { VBR  } I:=HEX('801');
	 11: { MSP  } I:=HEX('803');
	 12: { ISP  } I:=HEX('804');
	 13: { CACR } I:=HEX('002');
	 14: { CAAR } I:=HEX('802');
       { Added 12/26/89 for the new '040 registers : }
	 15: { TC }   I:= HEX('003');
	 16: { ITT0 } I:= hex('004');
	 17: { ITT1 } I:= hex('005');
	 18: { DTT0 } I:= hex('006');
	 19: { DTT1 } I:= hex('007');
	 20: { MMUSR } I:= hex('805');
	 21: { URP } I:= hex('806');
	 22: { SRP } I:= hex('807');
       END
     END;
     CODE.INT[2]:=CODE.INT[2]+I;
   END;

 33: { MOVES }
   BEGIN
     CODE.INT[2]:=0;
     CODELENGTH:=4;
     CODE.TYPE2.OPM1:=SIZE DIV 2;
     IF (OPERAND1.MODE<=1) THEN BEGIN { REG, <EA>}
       CODE.IDX[2].DA:=OPERAND1.MODE=1;
       CODE.IDX[2].REGI:=OPERAND1.REG;
       CODE.IDX[2].WL:=TRUE;
       BUILDEA(OPERAND2, 3, CODE.IDX[3]);
     END
     ELSE BEGIN          { <EA>, REG }
       CODE.IDX[2].DA:=OPERAND2.MODE=1;
       CODE.IDX[2].REGI:=OPERAND2.REG;
       BUILDEA(OPERAND1, 3, CODE.IDX[3]);
     END;
   END;

 34: { RTM }
   BEGIN
   CODE.BITS.B3:=OPERAND1.MODE=1;
   CODE.OITS.O0:=OPERAND1.REG;
   END;

 35: { BKPT }
   CODE.OITS.O0:=OPERAND1.VALUE.OFFSET.BYTE4;

 36: { TRAPcc }
   BEGIN
   IF      SIZESUFFIX='W' THEN
     BEGIN
     CODE.OITS.O0:=2; CODELENGTH:=4;
     CODE.INT[2]:=OPERAND1.VALUE.OFFSET.LOHALF;
     END
   ELSE IF SIZESUFFIX='L' THEN
     BEGIN
     CODE.OITS.O0:=3; CODELENGTH:=6;
     CODE.INT[2]:=OPERAND1.VALUE.OFFSET.HIHALF;
     CODE.INT[3]:=OPERAND1.VALUE.OFFSET.LOHALF;
     END
   ELSE   {SIZESUFFIX=' '}
     BEGIN
     CODE.OITS.O0:=4; CODELENGTH:=2;
     END;
   IF SIZESUFFIX<>' ' THEN
     DOLINKXTREF(OPERAND1,2,FALSE,EXWORDADDR);
   END;

 37: { CALLM }
   BEGIN
   CODELENGTH:=4;
   CODE.INT[2]:=0;
   CODE.BYT[4]:=OPERAND1.VALUE.OFFSET.BYTE4;
   SIZE:=1; DOLINKXTREF(OPERAND1,3,FALSE,EXWORDADDR);
   BUILDEA(OPERAND2,3,CODE.IDX[3]);
   END;

 38: { CAS }
   BEGIN
   CODELENGTH:=4;
   CODE.INT[2]:=0;
   CODE.OITS2.O0:=OPERAND1.REG;
   CODE.OITS2.O2:=OPERAND2.REG;
   BUILDEA(OPERAND3,3,CODE.IDX[3]);
   END;

 39: { CAS2 }
   BEGIN
   CODELENGTH:=6;
   CODE.INT[2]:=0;
   CODE.OITS2.O0 :=OPERAND1.REG;
   CODE.OITS2.O2 :=OPERAND3.REG;
   CODE.OITS2.O4 :=OPERAND5.REG;
   CODE.OITS2.B15:=OPERAND5.MODE=2;
   CODE.INT[3]:=0;
   CODE.OITS3.O0 :=OPERAND2.REG;
   CODE.OITS3.O2 :=OPERAND4.REG;
   CODE.OITS3.O4 :=OPERAND6.REG;
   CODE.OITS3.B15:=OPERAND6.MODE=2;
   END;

 40: { CHK2, CMP2 }
   BEGIN
   CODELENGTH:=4;
   CODE.INT[2]:=0;
   CODE.OITS2.O4 := OPERAND2.REG;
   CODE.BITS2.B15:=(OPERAND2.MODE=1);
   CODE.BITS2.B11:=(CURROP.NAME='CHK2     ');
   BUILDEA(OPERAND1,3,CODE.IDX[3]);
   END;

 41: { PACK, UNPK }
   BEGIN
   CODELENGTH:=4;
   CODE.BITS.B3:=(OPERAND1.MODE=4);
   CODE.OITS.O0:=OPERAND1.REG;
   CODE.OITS.O3:=OPERAND2.REG;
   CODE.INT[2] :=OPERAND3.VALUE.OFFSET.LOHALF;
   DOLINKXTREF(OPERAND3,2,FALSE,EXWORDADDR);
   END;

 42: { BFCHG, BFCLR, BFSET, BFTST }
   BEGIN
   CODELENGTH:=4;
   CODE.INT[2]:=0;
   CODE.BF.DOFF  :=BITFIELD.DOFF;
   CODE.BF.OFFSET:=BITFIELD.OFFSET;
   CODE.BF.DWID  :=BITFIELD.DWID;
   CODE.BF.WIDTH :=BITFIELD.WIDTH;
   BUILDEA(OPERAND1,3,CODE.IDX[3]);
   END;

 43: { BFEXTS, BFEXTU, BFFFO }
   BEGIN
   CODELENGTH:=4;
   CODE.INT[2]:=0;
   CODE.BF.REG   :=OPERAND2.REG;
   CODE.BF.DOFF  :=BITFIELD.DOFF;
   CODE.BF.OFFSET:=BITFIELD.OFFSET;
   CODE.BF.DWID  :=BITFIELD.DWID;
   CODE.BF.WIDTH :=BITFIELD.WIDTH;
   BUILDEA(OPERAND1,3,CODE.IDX[3]);
   END;

 44: { BFINS }
   BEGIN
   CODELENGTH:=4;
   CODE.INT[2]:=0;
   CODE.BF.REG   :=OPERAND1.REG;
   CODE.BF.DOFF  :=BITFIELD.DOFF;
   CODE.BF.OFFSET:=BITFIELD.OFFSET;
   CODE.BF.DWID  :=BITFIELD.DWID;
   CODE.BF.WIDTH :=BITFIELD.WIDTH;
   BUILDEA(OPERAND2,3,CODE.IDX[3]);
   END;

 45: { DIV?.L, DIV?L.L, MUL?.L }
   BEGIN
   CODELENGTH:=4;
   CODE.INT[2]:=0;
   CODE.BITS2.B11:=(CURROP.NAME[4]='S');
   CODE.BITS2.B10:=(OPERAND2.MODE=0); (***** special flag for 64bit mode *****)
				      (* someone unkind may call it a kludge *)
   CODE.OITS2.O0 :=OPERAND2.REG;
   CODE.OITS2.O4 :=OPERAND3.REG;
   BUILDEA(OPERAND1,3,CODE.IDX[3]);
   END;

 46: { MOVE16 }  { JWH 11/21/89 }
   BEGIN
    if operand1.mode <> 0 then { everything's cool }
     begin
     if ((operand1.MODE = 3) and (operand2.MODE = 3)) then  { POST INCR MODE }
      begin
       CODELENGTH := 4;
       CODE.BYT[2] := 32 + OPERAND1.REG;
       CODE.BYT[3] := 128 + 16*OPERAND2.REG;
       CODE.BYT[4] := 0;
      end
     else { ABSOLUTE MODE }
      begin
       CODELENGTH := 6;
       if OPERAND1.MODE = 7 then {it's absolute}
	begin
	 CODE.INT[2] := OPERAND1.VALUE.OFFSET.HIHALF;
	 CODE.INT[3] := OPERAND1.VALUE.OFFSET.LOHALF;
	 dolinkxtref(operand1, 2, false, exwordaddr);
	 if OPERAND2.MODE = 3 then
	   CODE.BYT[2] := 8 + OPERAND2.REG
	 else { operand2.MODE = 2 }
	   CODE.BYT[2] := 24 + OPERAND2.REG;
	end
       else { OPERAND2.MODE = 7 }
	begin
	 CODE.INT[2] := OPERAND2.VALUE.OFFSET.HIHALF;
	 CODE.INT[3] := OPERAND2.VALUE.OFFSET.LOHALF;
	 dolinkxtref(operand2, 2, false, exwordaddr);
	 if OPERAND1.MODE = 3 then
	   CODE.BYT[2] :=  OPERAND1.REG
	 else { operand2.MODE = 2 }
	   CODE.BYT[2] := 16 + OPERAND1.REG;
	end; { OPERAND2.MODE = 7 }
      end; { ABSOLUTE MODE }
     end { operand1.mode <> 0 }
     else { operand1.mode = 0, have BADOPS if we are here }
	  { just put in some generic values }
      begin
       if operand1.size = 0 then
	begin
	 CODELENGTH := 4;
	 CODE.BYT[2] := 32;
	 CODE.BYT[3] := 128;
	 CODE.BYT[4] := 0;
	end
       else { operand1.size = 2 }
	begin
	 CODELENGTH := 6;
	 CODE.BYT[2] := 0;
	 CODE.INT[3] := 0;
	 CODE.INT[4] := 0;
	end;
      end; { code for badops }
   END;  { Case 46 }
   47,48,49,50,51,52 : { CINVL,CINVP,CINVA,CPUSHL,CPUSHP,CPUSHA }
   BEGIN
     { If operand1.mode = 0 we had an operand error }
     CODELENGTH := 2;
     case OPERAND1.MODE of
       0: CODE.BYT[2] := 0;    { cache : 00 no operation }
       1: CODE.BYT[2] := 64;   { cache : 01 data        }
       2: CODE.BYT[2] := 128;  { cache : 10 instruction }
       3: CODE.BYT[2] := 192;  { cache : 11 both        }
     end; { CASE }
     if ((currop.CLASS <> 49) and (currop.CLASS <> 52)) then
       CODE.BYT[2] := CODE.BYT[2] + OPERAND2.REG;
     if ((CURROP.CLASS = 47) or (CURROP.CLASS = 50)) then
	CODE.BYT[2] := CODE.BYT[2] + 8   { scope : 01 - LINE }
     else IF ((currop.class = 48) or (currop.class = 51)) then
       CODE.BYT[2] := CODE.BYT[2] + 16   { scope : 10 - PAGE }
     else { currop.class = 49 or currop.class = 52 }
       CODE.BYT[2] := CODE.BYT[2] + 24; { scope : 11 - ALL }
     if currop.class > 49 then { it is a CPUSHx }
       CODE.BYT[2] := CODE.BYT[2] + 32; { SET BIT 5 to 1 }
   END; { case 47,48,49 }


END;  { OF CASE }
 PUNCHCODE;   (* OUTPUT THE GENERATED CODE *)
END;


@


55.1
log
@Automatic bump of revision number for PWS version 3.25A
@
text
@@


54.1
log
@Automatic bump of revision number for PWS version 3.24
@
text
@@


53.1
log
@Automatic bump of revision number for PWS version 3.24B
@
text
@@


52.1
log
@Automatic bump of revision number for PWS version 3.24A
@
text
@@


51.1
log
@Automatic bump of revision number for PWS version 3.24d
@
text
@@


50.1
log
@Automatic bump of revision number for PWS version 3.23c
@
text
@@


49.1
log
@Automatic bump of revision number for PWS version 3.24b
@
text
@@


48.1
log
@Automatic bump of revision number for PWS version 3.24a
@
text
@@


47.1
log
@Automatic bump of revision number for PWS version 3.23
@
text
@@


46.1
log
@Automatic bump of revision number for PWS version 3.23
@
text
@@


45.1
log
@Automatic bump of revision number for PWS version 3.23C
@
text
@@


44.1
log
@Automatic bump of revision number for PWS version 3.23B
@
text
@@


43.1
log
@Automatic bump of revision number for PWS version 3.23aA
@
text
@@


42.1
log
@Automatic bump of revision number for PWS version 3.23e
@
text
@@


41.4
log
@

        Tightened up MOVE16 processing a bit.
@
text
@@


41.3
log
@

        Fixed a small bug in gencode.
@
text
@d1654 2
d1687 19
@


41.2
log
@

          Enhanced the processing of MOVEC to include the
       registers supported for the first time with the '040.

       JWH 12/26/89.
@
text
@d1688 1
d1691 1
@


41.1
log
@Automatic bump of revision number for PWS version 3.23d
@
text
@d1467 9
d1490 9
@


40.3
log
@
pws2rcs automatic delta on Thu Dec 21 14:54:59 MST 1989
@
text
@@


40.2
log
@

        Added code to handle the new 68040 instructions MOVE16,
    CINV, and CPUSH.

         JWH 11/21/89.
@
text
@a1687 5
END;  { OF CASE }
 PUNCHCODE;   (* OUTPUT THE GENERATED CODE *)
END;


@


40.1
log
@Automatic bump of revision number for PWS version 3.23c
@
text
@d1634 60
@


39.1
log
@Automatic bump of revision number for PWS version 3.23b
@
text
@@


38.1
log
@Automatic bump of revision number for PWS version 3.23a
@
text
@@


37.1
log
@Automatic bump of revision number for PWS version 3.3a
@
text
@@


36.1
log
@Automatic bump of revision number for PWS version 3.22
@
text
@@


35.1
log
@Automatic bump of revision number for PWS version 3.22
@
text
@@


34.1
log
@Automatic bump of revision number for PWS version 3.22
@
text
@@


33.1
log
@Automatic bump of revision number for PWS version 3.22D
@
text
@@


32.1
log
@Automatic bump of revision number for PWS version 3.22C
@
text
@@


31.1
log
@Automatic bump of revision number for PWS version 3.22B
@
text
@@


30.1
log
@Automatic bump of revision number for PWS version 3.22A
@
text
@@


29.1
log
@Automatic bump of revision number for PWS version 3.22b
@
text
@@


28.1
log
@Automatic bump of revision number for PWS version 3.3b
@
text
@@


27.1
log
@Automatic bump of revision number for PWS version 3.3a
@
text
@@


26.1
log
@Automatic bump of revision number for PWS version 3.3 Synch
@
text
@@


25.1
log
@Automatic bump of revision number for PWS version 3.2Y
@
text
@@


24.1
log
@Automatic bump of revision number for PWS version 3.2
@
text
@@


23.1
log
@Automatic bump of revision number for PWS version 3.2P
@
text
@@


22.1
log
@Automatic bump of revision number for PWS version 3.2N
@
text
@@


21.1
log
@Automatic bump of revision number for PWS version 3.2M
@
text
@@


20.1
log
@Automatic bump of revision number for PWS version 3.2L
@
text
@@


19.1
log
@Automatic bump of revision number for PWS version 3.2K
@
text
@@


18.1
log
@Automatic bump of revision number for PWS version 3.2J
@
text
@@


17.1
log
@Automatic bump of revision number for PWS version 3.2I+
@
text
@@


16.1
log
@Automatic bump of revision number for PWS version 3.2I
@
text
@@


15.1
log
@Automatic bump of revision number for PWS version 3.2H
@
text
@@


14.1
log
@Automatic bump of revision number for PWS version 3.2G
@
text
@@


13.1
log
@Automatic bump of revision number for PWS version 3.2F
@
text
@@


12.1
log
@Automatic bump of revision number for PWS version 3.2E
@
text
@@


11.1
log
@Automatic bump of revision number for PWS version 3.2D
@
text
@@


10.1
log
@Automatic bump of revision number for PWS version 3.2C
@
text
@@


9.1
log
@Automatic bump of revision number for PWS version 3.2B
@
text
@@


8.1
log
@Automatic bump of revision number for PWS version 3.2A
@
text
@@


7.2
log
@Fixes for SSS
@
text
@@


7.1
log
@Automatic bump of revision number for PWS version 3.2l
@
text
@a996 2
	  IF OPER.FULL_FORMAT THEN
	    EXWORDADDR.LONGINT:=EXWORDADDR.LONGINT - 2;
d1038 3
a1040 2
	IF NOT OPER.FULL_FORMAT AND
	   NOT FITSIN8(EXWORDADDR) THEN
@


6.1
log
@Automatic bump of revision number for PWS version 3.2k
@
text
@@


5.1
log
@Automatic bump of revision number for PWS version 3.2j
@
text
@@


4.1
log
@Automatic bump of revision number for PWS version 3.2i
@
text
@@


3.1
log
@Automatic bump of revision number for PWS version 3.2h
@
text
@@


2.2
log
@changes to be able to assemble PAWS C compiler output
@
text
@@


2.1
log
@Auto bump rev number to 2.1 for sys 3.2e.
@
text
@d802 2
a803 1
	  IF NOT(LINE[CURCOL] IN ['A'..'Z'])  THEN ESCAPE(BADOPS);
@


1.1
log
@Initial revision
@
text
@@
