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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

42.1
date     90.01.23.17.28.59;  author jwh;  state Exp;
branches ;
next     41.1;

41.1
date     89.12.22.11.11.34;  author jwh;  state Exp;
branches ;
next     40.2;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

23.1
date     87.08.26.09.33.18;  author bayes;  state Exp;
branches ;
next     22.2;

22.2
date     87.08.20.15.48.00;  author larry;  state Exp;
branches ;
next     22.1;

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

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

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

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

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

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

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

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

14.1
date     87.04.01.14.03.28;  author jws;  state Exp;
branches ;
next     13.2;

13.2
date     87.03.23.14.19.45;  author larry;  state Exp;
branches ;
next     13.1;

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

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

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

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

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

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

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

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

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

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

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

3.1
date     86.09.01.11.14.09;  author hal;  state Exp;
branches ;
next     2.1;

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

1.1
date     86.06.30.12.54.53;  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
@{
   THESE PROCEDURES DO OPERAND DECODING AND EVALUATION IF NECESSARY.
								       }
FUNCTION PARSE_CACHES : integer;
{-----------------------------------------------------------}
{ The following routine is included for the CPUSH and CINV  }
{ instructions added with the 68040 support. The parsing of }
{ the first operand with these instructions is so elementary}
{ that it didn't seem worth it to mess with PARSEOPERAND.   }

{ Returns : 1 if DATA cache only                            }
{           2 if INSTRUCTION CACHE only                     }
{           3 if BOTH CACHES                                }
{           0 if an ERROR                                   }
{ Expects the syntax to be EXACTLY as follows :             }
{           DC - specifies DATA cache                       }
{           IC - specifies INSTRUCTION cache                }
{           DC/IC or IC/DC -  specifies BOTH caches         }
{ except that lowercase letters are permitted (they're      }
{ converted to uppercase by the line scanner ).             }
LABEL 1,2;
{ LABEL 1 : clean exit point.                               }
{ LABEL 2 : error exit point.                               }
BEGIN
  IF LINE[CURCOL] = 'D' THEN
   BEGIN
    IF LINE[CURCOL+1] = 'C' THEN PARSE_CACHES := 1 ELSE GOTO 2;
    CURCOL := CURCOL + 2;
    IF LINE[CURCOL] <> '/' THEN GOTO 1 ELSE
     BEGIN
      CURCOL := CURCOL + 1;
      IF LINE[CURCOL] = 'I' THEN
       BEGIN
	IF LINE[CURCOL+1] = 'C' THEN
	 BEGIN PARSE_CACHES :=  3; CURCOL := CURCOL + 2; GOTO 1; END
	ELSE GOTO 2;
       END
      ELSE GOTO 2;
     END;
   END;

  { IF LINE[CURCOL] = 'D' WAS TRUE, CONTROL SHOULDN'T BE HERE. }

  IF LINE[CURCOL] = 'I' THEN
   BEGIN
    IF LINE[CURCOL+1] = 'C' THEN PARSE_CACHES := 2 ELSE GOTO 2;
    CURCOL := CURCOL + 2;
    IF LINE[CURCOL] <> '/' THEN GOTO 1 ELSE
     BEGIN
      CURCOL := CURCOL + 1;
      IF LINE[CURCOL] = 'D' THEN
       BEGIN
	IF LINE[CURCOL+1] = 'C' THEN
	 BEGIN PARSE_CACHES :=  3; CURCOL := CURCOL + 2; GOTO 1; END
	ELSE GOTO 2;
       END
      ELSE GOTO 2;
     END;
   END;

2: PARSE_CACHES := 0;
1:
END;

PROCEDURE PARSE_BITFIELD{(VAR BF: BITFIELDTYPE)};  {FWD}
VAR
  TEMPOP: OPERAND;
BEGIN
IF LINE[CURCOL]<>'{' THEN
  BEGIN IF PASS=2 THEN ERROR(ERRLBRACEEXP); ESCAPE(BADOPS); END;
CURCOL:=CURCOL+1;
TEMPOP.VALUE.EXPREFS:=NIL;
PARSEOPERAND(TEMPOP);
IF (TEMPOP.MODE<>0) AND ((TEMPOP.MODE<>7) OR (TEMPOP.REG<>0)) THEN
  BEGIN IF PASS=2 THEN ERROR(ERRBADMODE); ESCAPE(BADOPS); END;
IF (TEMPOP.VALUE.EXPREFS<>NIL) THEN
  BEGIN
  TEMPOP.VALUE.EXPREFS:=NIL;
  TEMPOP.VALUE.OFFSET :=ZERO32;
  IF PASS=2 THEN ERROR(ERREXTREFS);
  ESCAPE(BADOPS);
  END;
IF (TEMPOP.MODE<>0) AND
   ((0>TEMPOP.VALUE.OFFSET.LONGINT) OR (TEMPOP.VALUE.OFFSET.LONGINT>=32)) THEN
  BEGIN IF PASS=2 THEN ERROR(ERRFIELDOFLO); ESCAPE(BADOPS); END;
IF TEMPOP.MODE=0 THEN
  BEGIN   (* D-register *)
  BF.DOFF:=TRUE;
  BF.OFFSET:=TEMPOP.REG;
  END
ELSE
  BEGIN   (* constant *)
  BF.DOFF:=FALSE;
  BF.OFFSET:=TEMPOP.VALUE.OFFSET.LONGINT;
  END;
IF LINE[CURCOL]<>':' THEN
  BEGIN IF PASS=2 THEN ERROR(ERRCOLONEXP); ESCAPE(BADOPS); END;
CURCOL:=CURCOL+1;
TEMPOP.VALUE.EXPREFS:=NIL;
PARSEOPERAND(TEMPOP);
IF (TEMPOP.MODE<>0) AND ((TEMPOP.MODE<>7) OR (TEMPOP.REG<>0)) THEN
  BEGIN IF PASS=2 THEN ERROR(ERRBADMODE); ESCAPE(BADOPS); END;
IF (TEMPOP.VALUE.EXPREFS<>NIL) THEN
  BEGIN
  TEMPOP.VALUE.EXPREFS:=NIL;
  TEMPOP.VALUE.OFFSET :=ZERO32;
  IF PASS=2 THEN ERROR(ERREXTREFS);
  ESCAPE(BADOPS);
  END;
IF (TEMPOP.MODE<>0) AND   (* different from offset field *)
   ((0>=TEMPOP.VALUE.OFFSET.LONGINT) OR (TEMPOP.VALUE.OFFSET.LONGINT>32)) THEN
  BEGIN IF PASS=2 THEN ERROR(ERRFIELDOFLO); ESCAPE(BADOPS); END;
IF (TEMPOP.MODE<>0) AND
   (TEMPOP.VALUE.OFFSET.LONGINT=32) THEN
    TEMPOP.VALUE.OFFSET.LONGINT:=0;
IF TEMPOP.MODE=0 THEN
  BEGIN   (* D-register *)
  BF.DWID:=TRUE;
  BF.WIDTH :=TEMPOP.REG;
  END
ELSE
  BEGIN   (* constant *)
  BF.DWID:=FALSE;
  BF.WIDTH :=TEMPOP.VALUE.OFFSET.LONGINT;
  END;
IF LINE[CURCOL]<>'}' THEN
  BEGIN IF PASS=2 THEN ERROR(ERRRBRACEEXP); ESCAPE(BADOPS); END;
CURCOL:=CURCOL+1;
END;


FUNCTION CHECKREGS; { FWD DECLARED }
VAR
  HOLDCOL: SHORTINT;
  RVALUE: EXPRVALUE;
  TPASS: 1..2;
BEGIN
HOLDCOL:=CURCOL;
TPASS:=PASS; PASS:=1;  { KLUGE TO AVOID UNDEFINED SYMBOL ERRORS }
GETSYMBOL(RVALUE, HOLDCOL);
PASS:=TPASS;
IF (RVALUE.BASE=AREG) OR (RVALUE.BASE=DREG) OR (RVALUE.BASE=FPREG) THEN
  BEGIN
  CHECKREGNO:=RVALUE.OFFSET.LOHALF;
  CHECKREGMODE:=RVALUE.BASE;
  CHECKREGS:=TRUE;
  CURCOL:=HOLDCOL;
  END
ELSE
  CHECKREGS:=FALSE;
END;


FUNCTION CHECKSPREGS; { CHECKS FOR CCR, SR, USP } { FWD DECLARED }
VAR                   { ALSO DFC, SFC, VBR } { AND MSP,ISP,CACR,CAAR }
  HOLDCOL: SHORTINT;
  RVALUE: EXPRVALUE;
  TPASS: 1..2;
BEGIN
HOLDCOL:=CURCOL;
TPASS:=PASS; PASS:=1;  { KLUGE TO AVOID UNDEF SYMBOL ERRORS }
GETSYMBOL(RVALUE, HOLDCOL);
PASS:=TPASS;
IF (RVALUE.BASE=STREG) OR (RVALUE.BASE=FPSTREG) THEN
  BEGIN
  CHECKREGNO:=RVALUE.OFFSET.LOHALF;
  CHECKREGMODE:=RVALUE.BASE;
  CHECKSPREGS:=TRUE;
  CURCOL:=HOLDCOL;
  END
ELSE
  CHECKSPREGS:=FALSE
END;


PROCEDURE PARSEOPERAND{(VAR OP:OPERAND)};  {FWD}
VAR HOLDCOL: SHORTINT;
    REGSUFFIX: CHAR;


PROCEDURE GETINDEX;
BEGIN
IF CHECKREGS THEN
  BEGIN
  IF LINE[CURCOL]='.' THEN
    BEGIN
    REGSUFFIX:=LINE[CURCOL+1];
    IF LINE[CURCOL+1]<>BLANK THEN CURCOL:=CURCOL+2;
    END (* LINE[CURCOL]='.' *)
  ELSE
    REGSUFFIX:=' ';
  OP.INDEX:=CHECKREGNO;
  IF CHECKREGMODE=AREG
    THEN OP.INDEXMODE:=ADDRS
    ELSE OP.INDEXMODE:=DATA;
$if mc68881$
  if (pass=2) and (checkregmode=fpreg) then
      error(errfpregnotallowed);
$end$
  IF      REGSUFFIX='L' THEN
    OP.INDEXSIZE:=LONG
  ELSE IF REGSUFFIX='W' THEN
    OP.INDEXSIZE:=WRD
  ELSE IF REGSUFFIX=' ' THEN
    OP.INDEXSIZE:=WRD
  ELSE
    IF PASS=2 THEN ERROR(ERRBADSUFFIX);

  IF LINE[CURCOL]<>'*' THEN
    OP.INDEXSCALE:=0
  ELSE
    BEGIN { MUST BE A SCALE FACTOR }
    CURCOL:=CURCOL+1;
    IF      LINE[CURCOL]='1' THEN
      OP.INDEXSCALE:=0
    ELSE IF LINE[CURCOL]='2' THEN
      OP.INDEXSCALE:=1
    ELSE IF LINE[CURCOL]='4' THEN
      OP.INDEXSCALE:=2
    ELSE IF LINE[CURCOL]='8' THEN
      OP.INDEXSCALE:=3
    ELSE
      IF PASS=2 THEN ERROR(ERRBADSCALE);
    IF LINE[CURCOL]<>BLANK THEN CURCOL:=CURCOL+1;
    END;

  END (* CHECKREGS *)
ELSE (* NOT CHECKREGS *)
  IF PASS=2 THEN ERROR(ERRREGEXP)
END; (* GETINDEX *)


PROCEDURE GETDISPSIZE(VALUE: EXPRVALUE;
		  VAR SIZE: DISPSIZE;
		  VAR INCRSIZE: OPSIZETYPE);
(* Based on VALUE.OFFSET, set SIZE to S_NULL, S_WORD, or S_LONG,
(* and increment INCRSIZE by 0, 2, or 4 bytes
(**)
(* mostly swiped from ABSORINDEXED *)
BEGIN
IF VALUE.EMODE=NOMODE THEN
  BEGIN
  IF VALUE.BASE=RELATIVE THEN
    BEGIN
    IF ORGMODE=LONGFWDS
      THEN SIZE:=S_LONG
      ELSE SIZE:=S_WORD;
    END (* VALUE.BASE=RELATIVE *)
  ELSE
    BEGIN
    IF (EVALOK<>OK1) OR (VALUE.EXPREFS<>NIL) THEN { FWD OR EXT REF }
      BEGIN
      IF ORGMODE=LONGFWDS THEN
	SIZE:=S_LONG
      ELSE
	BEGIN
	SIZE:=S_WORD;
	IF (PASS=2) AND NOT(FITSIN16(VALUE.OFFSET))
	   THEN ERROR(ERRFIELDOFLO);
	END
      END (* (EVALOK<>OK1) OR (VALUE.EXPREFS<>NIL) *)
    ELSE { NOT FWD REF }
      IF      0 =     (VALUE.OFFSET.LONGINT) THEN (* FITSIN0 *)
	SIZE:=S_NULL
      ELSE IF FITSIN16(VALUE.OFFSET) THEN
	SIZE:=S_WORD
      ELSE (* FITSIN32(VALUE.OFFSET) *)
	SIZE:=S_LONG;
    END (* VALUE.BASE<>RELATIVE *)
  END (* VALUE.EMODE=NOMODE *)
ELSE IF VALUE.EMODE=RMODE THEN
  SIZE:=S_WORD
ELSE IF VALUE.EMODE=LMODE THEN
  SIZE:=S_LONG
ELSE (* VALUE.EMODE=SMODE *)
  BEGIN
  SIZE:=S_WORD;
  IF (PASS=2) AND NOT(FITSIN16(VALUE.OFFSET)) THEN
    ERROR(ERRFIELDOFLO);
  END; (* VALUE.EMODE=SMODE *)
IF      SIZE=S_LONG THEN INCRSIZE:=INCRSIZE+4
ELSE IF SIZE=S_WORD THEN INCRSIZE:=INCRSIZE+2;
END;


PROCEDURE IMMEDOP;
$if fpimmed$
var
  specialcaseit : boolean;        (* handling FMOVE.P FPn,<ea>(#k)
					   or FMOVECR.X #ccc,FPn ? *)
$end$
BEGIN
  CURCOL := CURCOL + 1;
$if fpimmed$
  if (currop.class = (fpbase+0))        (* FMOVE instructions *)
     and ( ((currop.name[6] = 'C') and (currop.name[7] = 'R'))  (* FMOVECR *)
	or ((line[curcol-2] = '{') and (operand1.mode = 8)
	and (sizesuffix = 'P')) ) (* FMOVE FPn,<ea>(#k) *) then
    specialcaseit := true
  else
    specialcaseit := false;
if (sizesuffix = 'D') and not specialcaseit then
  begin
  if fpimmedexp( pass=2, evalok, evalue, curcol ) then
    begin
    if (not allowfpopds) and (pass = 2) then
      error( errfpopdnotallowed );
    end
  else
    begin
    if pass = 2 then
      error( errfpconstneeded );
    end;
  end
else
$end$
EXPRESS(PASS=2,EVALOK,EVALUE,CURCOL);
OP.MODE:=7;
OP.REG:=4;
OP.VALUE:=EVALUE;
$if fpimmed$
if specialcaseit then
  op.size := 0
else
$end$
if sizesuffix = 'B' then
  BEGIN
  OP.SIZE:=2;
  IF PASS=2 THEN
    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);
  END
else if (sizesuffix = 'W') or (sizesuffix = ' ') then
  BEGIN
  OP.SIZE:=2;
  IF PASS=2 THEN
    IF NOT(FITSIN16(EVALUE.OFFSET)) AND
       (EVALUE.OFFSET.HIHALF<>0) AND
       (EVALUE.EXPREFS=NIL)
      THEN ERROR(ERRFIELDOFLO);
  END
else if sizesuffix = 'L' then
$if not fpimmed$
  OP.SIZE:=4;
$end$
$if fpimmed$
  op.size := 4
else if sizesuffix = 'D' then op.size := 8
else
  begin
  error( errfpimmedsize );
  op.size := 8;
  with op.value do
    begin
    base := absolut;
    offset.fltpt := 0.0;
    exprefs := nil;
    emode := nomode;
    end;
  end;
			(* full flt. pt. support will require mods
			   here, note too that sizesuffix = ' ' will
			   likely need to allow implicit flt. pt.
			   minimum req'rd size selection

else if sizesuffix = 'S' then op.size := 4
else if sizesuffix = 'D' then op.size := 8
else if sizesuffix = 'X' then op.size := 12
else if sizesuffix = 'P' then op.size := 12;
					---------------------- ??? *)
$end$
END;


PROCEDURE INDIRECT;
(* NOW INCLUDES:
(* 2n (An)                      An IND.
(* 3n (An)+                     An IND. WITH POSTINCREMENT
(* 5n (d16,An)                  An IND. WITH DISP.
(* 6n (d8,An,Xn.SIZE*SCALE)     An IND. WITH INDEX (8-BIT DISP.)
(* 6n (bd,An,Xn.SIZE*SCALE)     An IND. WITH INDEX (BASE DISP.)
(* 6n ([bd,An],Xn.SIZE*SCALE,od)   MEMORY IND. POST-INDEXED
(* 6n ([bd,An,Xn.SIZE*SCALE],od)   MEMORY IND. PRE-INDEXED
(* 73 (rd8,Xn.SIZE*SCALE)       PC IND. WITH INDEX (8-BIT DISP.)
(* 73 (rbd,Xn.SIZE*SCALE)       PC IND. WITH INDEX (BASE DISP.)
(* 73 ([rbd],Xn.SIZE*SCALE,od)  PC MEMORY IND. POST-INDEXED
(* 73 ([rbd,Xn.SIZE*SCALE],od)  PC MEMORY IND. PRE-INDEXED
(*
(* OPERAND RECORD:
(*      SIZE:           total size of operand
(*      MODE:           mode, goes in EA
(*      REG:            An, goes in EA

(*      INDEXMODE:      index is An/Dn (ADDRS,DATA)
(*      INDEX:          Xn
(*      INDEXSIZE:      SIZE (WRD,LONG)
(*      INDEXSCALE:     SCALE (0..3)
(*      FULL_FORMAT:
(*      BASE_SUPPRESS:  didn't see base
(*      INDEX_SUPPRESS: didn't see index
(*      BD_SIZE:        size of bd (S_RES,S_NULL,S_WORD,S_LONG)
(*      FILL:           zero bit
(*      POST_INDEXED:   index was seen outside ']'
(*      OD_SIZE:        size of od (S_RES,S_NULL,S_WORD,S_LONG)

(*      VALUE:          inner (also called base) or only displacement
(*      OD_VALUE:       outer displacement
(**)
VAR
  ININNER,SEENINNER,SEENID,SEENOD,SEENAN,SEENZPC,SEENINDEX: BOOLEAN;
  COLL: SHORTINT;
  VAL: EXPRVALUE;
  VALUEOK: EVALWHEN;
  INDISPLACEMENT,ININDEX: BOOLEAN;


  PROCEDURE CHANGE_An_TO_INDEX(NEW_POST_INDEXED: BOOLEAN);
  BEGIN
  IF SEENAN AND NOT SEENZPC THEN
    BEGIN (* NEED TO CHANGE OLD An TO INDEX *)
    IF SEENINDEX THEN
      BEGIN IF PASS=2 THEN ERROR(ERR2INDEX); ESCAPE(BADOPS); END;
    SEENINDEX:=TRUE;
    SEENAN   :=FALSE;
    OP.POST_INDEXED:=NEW_POST_INDEXED;
    OP.INDEXMODE :=ADDRS;
    OP.INDEX     :=OP.REG;
    OP.INDEXSIZE :=WRD;
    OP.INDEXSCALE:=0;
    END;
  END;


BEGIN
ININNER    :=FALSE;
SEENINNER  :=FALSE;
SEENID     :=FALSE;
SEENOD     :=FALSE;
SEENAN     :=FALSE;
SEENZPC    :=FALSE;
SEENINDEX  :=FALSE;
VALUEOK:=OK1;   (* 870814 *)
EVALOK :=OK1;   (* 870814 *)
OP.FILL:=           FALSE;
OP.POST_INDEXED:=   FALSE;
OP.VALUE.OFFSET:=   ZERO32;
OP.VALUE.EXPREFS:=  NIL;
OP.VALUE.BASE:=     ABSOLUT;
OP.VALUE.EMODE:=    NOMODE; (* 870814 *)
OP.OD_VALUE.OFFSET:=   ZERO32;
OP.OD_VALUE.EXPREFS:=  NIL;
OP.OD_VALUE.BASE:=     ABSOLUT;
OP.OD_VALUE.EMODE:=    NOMODE; (* 870814 *)
CURCOL:=CURCOL+1;
TRY
  WHILE TRUE DO (* exits with ESCAPE(OPSOK) *)
    BEGIN
    IF LINE[CURCOL]='[' THEN
      BEGIN
      IF SEENINNER THEN
	BEGIN IF PASS=2 THEN ERROR(ERR2INNER); ESCAPE(BADOPS); END;
      IF SEENZPC THEN
	BEGIN IF PASS=2 THEN ERROR(ERRMISZPC); ESCAPE(BADOPS); END;
      CHANGE_An_TO_INDEX(TRUE);
      ININNER:=TRUE;
      SEENINNER:=TRUE;
      OP.OD_VALUE:=OP.VALUE;
      IF SEENINDEX THEN OP.POST_INDEXED:=TRUE;
      CURCOL:=CURCOL+1;
      END;
    IF ('A'<=LINE[CURCOL]) AND (LINE[CURCOL]<='Z') OR (LINE[CURCOL]='_') THEN
      BEGIN
      COLL:=CURCOL;
      GETSYMBOL(VAL,COLL);
      INDISPLACEMENT:=(VAL.BASE<>AREG) AND (VAL.BASE<>DREG) AND (VAL.BASE<>PREG);
      (* THIS WILL CATCH SPREG, AND FP REGS IN EXPRESS BELOW *)
      END
    ELSE
      INDISPLACEMENT:=TRUE;
    IF INDISPLACEMENT THEN
      BEGIN (* INDISPLACEMENT *)
      EXPRESS(PASS=2,EVALOK,EVALUE,CURCOL);
      (* ININNER T T T T F F F F
      (* SEENID  T T F F T T F F
      (* SEENOD  T F T F T F T F
      (*         e e m v e o e v
      (*
      (* e: error;  m: move VALUE to OD_VALUE, store in VALUE
      (* v: store in VALUE;  o: store in OD_VALUE
      (**)
      IF ININNER THEN
	BEGIN
	IF SEENID THEN
	  BEGIN IF PASS=2 THEN ERROR(ERR2DISP); ESCAPE(BADOPS); END;
	SEENID:=TRUE;
	IF SEENOD THEN
	  BEGIN
	  OP.OD_VALUE:=OP.VALUE;
	  IF OP.OD_VALUE.BASE=RELATIVE THEN
	    BEGIN IF PASS=2 THEN ERROR(ERRRELREFS); ESCAPE(BADOPS); END;
	  END;
	OP.VALUE:=EVALUE;
	VALUEOK:=EVALOK;
	IF OP.VALUE.BASE=RELATIVE THEN
	  CHANGE_An_TO_INDEX(FALSE);
	END
      ELSE
	BEGIN
	IF SEENOD THEN
	  BEGIN IF PASS=2 THEN ERROR(ERR2DISP); ESCAPE(BADOPS); END;
	SEENOD:=TRUE;
	IF SEENINNER THEN
	  BEGIN
	  OP.OD_VALUE:=EVALUE;
	  IF OP.OD_VALUE.BASE=RELATIVE THEN
	    BEGIN IF PASS=2 THEN ERROR(ERRRELREFS); ESCAPE(BADOPS); END;
	  END
	ELSE
	  BEGIN
	  OP.   VALUE:=EVALUE;
	  VALUEOK:=EVALOK;
	  IF OP.VALUE.BASE=RELATIVE THEN
	    CHANGE_An_TO_INDEX(FALSE);
	  END;
	END;
      END (* INDISPLACEMENT *)
    ELSE
      BEGIN (* NOT INDISPLACEMENT *)
      (* THIS CAN ONLY HAPPEN IF GETSYMBOL(VAL,COLL) WAS CALLED *)
      IF      VAL.BASE=AREG THEN
	ININDEX:=(LINE[COLL]='*') OR (LINE[COLL]='.') OR SEENAN OR
		 (SEENINNER AND NOT ININNER) OR (OP.VALUE.BASE=RELATIVE)
      ELSE IF VAL.BASE=DREG THEN
	ININDEX:=TRUE
      ELSE (* VAL.BASE=PREG *)
	BEGIN
	ININDEX:=FALSE;
	IF SEENZPC THEN
	  BEGIN IF PASS=2 THEN ERROR(ERR2ZPC); ESCAPE(BADOPS); END;
	IF SEENINNER AND NOT ININNER THEN
	  BEGIN IF PASS=2 THEN ERROR(ERRMISZPC); ESCAPE(BADOPS); END;
	CHANGE_An_TO_INDEX(FALSE);
	SEENZPC:=TRUE;
	END;
      IF ININDEX THEN
	BEGIN (* ININDEX *)
	IF SEENINDEX THEN
	  BEGIN IF PASS=2 THEN ERROR(ERR2INDEX); ESCAPE(BADOPS); END;
	SEENINDEX:=TRUE;
	GETINDEX;
	OP.POST_INDEXED:=NOT ININNER AND SEENINNER;
	END (* ININDEX *)
      ELSE
	BEGIN (* ADDRESS REGISTER OR ZPC *)
	CURCOL:=COLL; (* ALREADY PARSED BY GETSYMBOL *)
	SEENAN:=TRUE;
	OP.REG:=VAL.OFFSET.LONGINT; (* 16 FOR ZPC *)
	END; (* ADDRESS REGISTER OR ZPC *)
      END; (* NOT INDISPLACEMENT *)
    IF LINE[CURCOL]=']' THEN
      BEGIN
      IF NOT ININNER THEN
	BEGIN IF PASS=2 THEN ERROR(ERRRBRACKUNEXP); ESCAPE(BADOPS); END;
      ININNER:=FALSE;
      CURCOL:=CURCOL+1;
      END;
    IF LINE[CURCOL]=')' THEN
      BEGIN
      IF ININNER THEN
	BEGIN IF PASS=2 THEN ERROR(ERRRBRACKEXP); ESCAPE(BADOPS); END;
      ESCAPE(OPSOK);
      END;
    IF LINE[CURCOL]=',' THEN
      CURCOL:=CURCOL+1
    ELSE
      BEGIN IF PASS=2 THEN ERROR(ERRCOMMAEXP); ESCAPE(BADOPS); END;
  END; (* infinite WHILE *)
RECOVER
  IF ESCAPECODE=BADOPS THEN
    BEGIN (* BADOPS *)
    OP.REG:=            0;
    OP.INDEXMODE:=      DATA;
    OP.INDEX:=          0;
    OP.INDEXSIZE:=      WRD;
    OP.INDEXSCALE:=     0;
    OP.POST_INDEXED:=   FALSE;
    OP.VALUE.OFFSET:=   ZERO32;
    OP.VALUE.EXPREFS:=  NIL;
    OP.VALUE.BASE:=     ABSOLUT;
    OP.OD_VALUE.OFFSET:=   ZERO32;
    OP.OD_VALUE.EXPREFS:=  NIL;
    OP.OD_VALUE.BASE:=     ABSOLUT;
    END; (* BADOPS *)
(*
(* SEENINNER T T T T T T T T T T T T T T T T F F F F F F F F F F F F F F F F
(* SEENID    T T T T T T T T F F F F F F F F T T T T T T T T F F F F F F F F
(* SEENOD    T T T T F F F F T T T T F F F F T T T T F F F F T T T T F F F F
(* SEENAN    T T F F T T F F T T F F T T F F T T F F T T F F T T F F T T F F
(* SEENINDEX T F T F T F T F T F T F T F T F T F T F T F T F T F T F T F T F
(*           6 6 ? ? 6 6 ? ? 6 6 . . 6 6 . . . . . . . . . . 6 5 ? ? 6 2 6 .
(* ?: MODE=IF VALUE IS REL THEN 7 ELSE 6
(* .: IMPOSSIBLE
(**)
CURCOL:=CURCOL+1;
OP.SIZE:=0; (* LET'S START WITH THIS *)
(* The following code is needed to reduce the address to an offset,
(* if possible, so that GETDISPSIZE and FITSIN16 will produce the
(* correct size.
(**)
VAL:=OP.VALUE;
IF OP.VALUE.BASE=RELATIVE THEN
  BEGIN
  IF VALUEOK=OK1 THEN
    BEGIN
    VAL.BASE:=ABSOLUT;
    (* A guess is made here that the distance between the operator
    (* start (LOCCTR) and the operand start is 2 bytes.  The operand
    (* start is where PC is at runtime when the operand is evaluated
    (* (at runtime).
    (**)
    VAL.OFFSET.LONGINT:=VAL.OFFSET.LONGINT-(LOCCTR.LONGINT+2);
    END;
  END;
IF  SEENAN    AND
NOT SEENINNER AND
NOT SEENID    AND
NOT SEENINDEX AND
NOT SEENZPC   AND
FITSIN16(VAL.OFFSET) THEN
  BEGIN (* EA=2n, 3n, or 5n *)
  IF SEENOD THEN
    BEGIN (* EA=5n *)
    OP.SIZE:=OP.SIZE+2;
    OP.MODE:=5;
    END (* EA=5n *)
  ELSE
    BEGIN (* EA=2n or 3n *)
    IF LINE[CURCOL]='+' THEN
      BEGIN (* EA=3n *)
      OP.MODE:=3;
      CURCOL:=CURCOL+1;
      END (* EA=3n *)
    ELSE
      BEGIN (* EA=2n *)
      OP.MODE:=2;
      END; (* EA=2n *)
    END (* EA=2n or 3n *)
  END (* EA=2n, 3n, or 5n *)
ELSE
  BEGIN (* EA=6n or 73 *)
  OP.SIZE:=OP.SIZE+2; (* ROOM FOR EXTENSION WORD *)
  IF ({NOT SEENAN AND} (OP.VALUE.BASE=RELATIVE)) OR SEENZPC THEN
    BEGIN OP.MODE:=7; OP.REG:=3; END
  ELSE
    OP.MODE:=6;
  OP.FULL_FORMAT:=
    SEENINNER OR
    NOT SEENINDEX OR
    NOT SEENOD OR
    NOT FITSIN8(VAL.OFFSET) OR
       (VALUEOK<>OK1) OR (VAL.EXPREFS<>NIL) OR   { LAF 870323 SR46894 & others }
    (NOT SEENAN AND (OP.VALUE.BASE=ABSOLUT)) OR
    SEENZPC;
  IF OP.FULL_FORMAT THEN
    BEGIN
    OP.BASE_SUPPRESS:=(NOT SEENAN AND (OP.MODE=6)) OR SEENZPC;
    IF OP.BASE_SUPPRESS AND NOT SEENZPC THEN
      OP.REG:=0; (* MAKE IT A LITTLE CLEANER *)
    IF SEENINNER THEN
      BEGIN
      GETDISPSIZE(      VAL  ,OP.BD_SIZE,OP.SIZE);
      GETDISPSIZE(OP.OD_VALUE,OP.OD_SIZE,OP.SIZE);
      END
    ELSE
      BEGIN
      GETDISPSIZE(      VAL  ,OP.BD_SIZE,OP.SIZE);
			      OP.OD_SIZE:=S_RES;
      END;
    OP.INDEX_SUPPRESS:=NOT SEENINDEX;
    IF OP.INDEX_SUPPRESS THEN
      BEGIN (* MAKE IT A LITTLE CLEANER *)
      OP.INDEXMODE:=      DATA;
      OP.INDEX:=          0;
      OP.INDEXSIZE:=      WRD;
      OP.INDEXSCALE:=     0;
      END;
    IF NOT SEENINNER THEN
      OP.POST_INDEXED:=FALSE;
    END; (* OP.FULL_FORMAT *)
  END; (* EA=6n or 73 *)
END;


$IF FALSE$
PROCEDURE  INDORAUTOINC;  (* REPLACED BY 'INDIRECT' *)
BEGIN
CURCOL:=CURCOL+1;
OP.MODE:=2;
OP.SIZE:=0;
IF CHECKREGS THEN
  IF CHECKREGMODE=AREG THEN
    BEGIN
    OP.REG:=CHECKREGNO;
    IF (LINE[CURCOL]=')') AND (LINE[CURCOL+1]='+') THEN
      BEGIN
      OP.MODE:=3;
      CURCOL:=CURCOL+2;
      END
    ELSE (* <>')+' *)
      BEGIN
      IF LINE[CURCOL]=')'
	THEN CURCOL:=CURCOL+1
	ELSE IF PASS=2 THEN ERROR(ERRCLOSEPEXP);
      END; (* <>')+' *)
    END (* CHECKREGMODE=AREG *)
  ELSE (* CHECKREGMODE<>AREG *)
    IF PASS=2 THEN ERROR(ERRAREGEXP) ELSE
ELSE (* NOT CHECKREGS *)
  IF PASS=2 THEN ERROR(ERRAREGEXP);
END;
$END$


PROCEDURE AUTODEC;
BEGIN
CURCOL:=CURCOL+2;
OP.MODE:=4;
OP.SIZE:=0;
IF CHECKREGS THEN
  IF CHECKREGMODE=AREG THEN
    IF LINE[CURCOL]=')' THEN
      BEGIN
      CURCOL:=CURCOL+1;
      OP.REG:=CHECKREGNO;
      END
    ELSE
       BEGIN IF PASS=2 THEN ERROR(ERRCLOSEPEXP) END
  ELSE
    BEGIN IF PASS=2 THEN ERROR(ERRAREGEXP) END
ELSE IF PASS=2 THEN ERROR(ERRAREGEXP);
END;


PROCEDURE ABSORINDEXED;
BEGIN
EXPRESS(PASS=2, EVALOK, EVALUE, CURCOL);
OP.VALUE:=EVALUE;
IF LINE[CURCOL]='(' THEN  { INDEXED }
  BEGIN
  OP.FULL_FORMAT:=FALSE;
  CURCOL:=CURCOL+1;
  IF EVALUE.BASE=RELATIVE THEN
    BEGIN
    OP.MODE:=7; OP.REG :=3; OP.SIZE:=2;
    GETINDEX;
    IF LINE[CURCOL]<>')' THEN
      BEGIN IF PASS=2 THEN ERROR(ERRCLOSEPEXP) END
    ELSE
      CURCOL:=CURCOL+1;
    END (* EVALUE.BASE=RELATIVE *)
  ELSE
    BEGIN { ABSOLUTE INDEXED }
    { ASSUMPTION FOR NOW }
    OP.MODE:=5; OP.REG :=0; OP.SIZE:=2;
    OP.INDEXMODE:=ADDRS;
    OP.INDEXSIZE:=WRD;
    IF CHECKREGS THEN
      BEGIN
      IF (CHECKREGMODE=AREG) OR (PASS=1) THEN
	BEGIN
	OP.REG:=CHECKREGNO;
	IF LINE[CURCOL]=',' THEN { LOOK FOR ANOTHER REG }
	  BEGIN
	  CURCOL:=CURCOL+1;
	  OP.MODE:=6;
	  GETINDEX;
	  IF LINE[CURCOL]<>')' THEN
	    BEGIN IF PASS=2 THEN ERROR(ERRCLOSEPEXP) END
	  ELSE
	    CURCOL:=CURCOL+1;
	  IF (PASS=2) AND NOT(FITSIN8(EVALUE.OFFSET)) THEN
	    ERROR(ERRFIELDOFLO);
	  END (* LINE[CURCOL]=',' *)
	ELSE { ADDR REG PLUS DISPLACEMENT }
	  BEGIN
	  IF PASS=1 THEN
	    IF LINE[CURCOL]='.' THEN
	      BEGIN
	      CURCOL:=CURCOL+1;
	      IF (LINE[CURCOL]<>')') AND (LINE[CURCOL]<>' ') THEN
		CURCOL:=CURCOL+1;
	      END; (* LINE[CURCOL]='.' *) (* PASS=1 *)
	  IF LINE[CURCOL]<>')' THEN
	    BEGIN IF PASS=2 THEN ERROR(ERRCLOSEPEXP) END
	  ELSE (* LINE[CURCOL]=')' *)
	    BEGIN
	    CURCOL:=CURCOL+1;
	    IF (PASS=2) AND NOT(FITSIN16(EVALUE.OFFSET)) THEN
	      ERROR(ERRFIELDOFLO);
	    END (* LINE[CURCOL]=')' *)
	  END (* LINE[CURCOL]<>',' *)
	END (* (CHECKREGMODE=AREG) OR (PASS=1) *)
      ELSE
	BEGIN IF PASS=2 THEN ERROR(ERRAREGEXP) END;
      END (* CHECKREGS *)
    ELSE
      BEGIN IF PASS=2 THEN ERROR(ERRAREGEXP) END
    END (* EVALUE.BASE<>RELATIVE *)
  END (* LINE[CURCOL]='(' *)
ELSE
  BEGIN { ABS OR REL WITH NO INDEX REGS }
  OP.MODE:=7;
  IF EVALUE.EMODE=NOMODE THEN
    BEGIN
    IF EVALUE.BASE=RELATIVE THEN
      BEGIN
      if orgmode=longfwds then
	begin op.reg :=1; op.size:=4; end
      else
	begin OP.REG :=2; OP.SIZE:=2; end
      END (* EVALUE.BASE=RELATIVE *)
    ELSE
      BEGIN
      IF (EVALOK<>OK1) OR (EVALUE.EXPREFS<>NIL) THEN { FWD OR EXT REF }
	BEGIN
	IF ORGMODE=LONGFWDS THEN
	  BEGIN OP.REG :=1; OP.SIZE:=4; END
	ELSE
	  BEGIN
	  OP.REG :=0; OP.SIZE:=2;
	  IF (PASS=2) AND NOT(FITSIN16(OP.VALUE.OFFSET))
	     THEN ERROR(ERRFIELDOFLO);
	  END
	END (* (EVALOK<>OK1) OR (EVALUE.EXPREFS<>NIL) *)
      ELSE { NOT FWD REF }
	IF FITSIN16(EVALUE.OFFSET) THEN
	  BEGIN OP.REG :=0; OP.SIZE:=2; END
	ELSE
	  BEGIN OP.REG :=1; OP.SIZE:=4; END
      END (* EVALUE.BASE<>RELATIVE *)
    END (* EVALUE.EMODE=NOMODE *)
  ELSE IF EVALUE.EMODE=RMODE THEN
    BEGIN OP.REG :=2; OP.SIZE:=2; END
  ELSE IF EVALUE.EMODE=LMODE THEN
    BEGIN OP.REG :=1; OP.SIZE:=4; END
  ELSE (* EVALUE.EMODE=SMODE *)
    BEGIN
    OP.REG :=0; OP.SIZE:=2;
    IF (PASS=2) AND NOT(FITSIN16(EVALUE.OFFSET)) THEN
      ERROR(ERRFIELDOFLO);
    END (* EVALUE.EMODE=SMODE *)
  END (* LINE[CURCOL]<>'(' *)
END; { OF PROCEDURE ABSORINDEXED -- I HOPE }


BEGIN (* PARSEOPERAND *)
IF       LINE[CURCOL]='#' THEN IMMEDOP
ELSE IF  LINE[CURCOL]='(' THEN INDIRECT (* WAS INDORAUTOINC *)
ELSE IF (LINE[CURCOL]='-') AND (LINE[CURCOL+1]='(') THEN AUTODEC
ELSE IF CHECKREGS THEN
  BEGIN
  OP.SIZE:=0;
$if mc68881$
  if      checkregmode=areg then op.mode:=1
  else if checkregmode=fpreg then
    begin
    if allowfpopds then
      op.mode:=8
    else
      begin
      if pass=2 then error(errfpregnotallowed);
      op.mode:=0;
      end;
    end
  else
    op.mode:=0;            (* dreg *)
$end$
$if not mc68881$
  IF CHECKREGMODE=AREG THEN OP.MODE:=1 ELSE OP.MODE:=0;
$end$
  OP.REG:=CHECKREGNO;
  END
ELSE IF CHECKSPREGS THEN
  BEGIN
  OP.SIZE:=0;
$if mc68881$
  if checkregmode=fpstreg then
    begin
    if allowfpopds then
      op.mode:=9
    else
      begin
      if pass=2 then error(errfpregnotallowed);
      op.mode:=7;
      end;
    end
  else
$end$
    OP.MODE:=7;
  OP.REG:=CHECKREGNO;
  END
ELSE ABSORINDEXED;
END; (* PARSEOPERAND *)

$include 'M68KFPMVM'$

@


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


56.1
log
@Automatic bump of revision number for PWS version 3.25
@
text
@a0 910
{
   THESE PROCEDURES DO OPERAND DECODING AND EVALUATION IF NECESSARY.
								       }
FUNCTION PARSE_CACHES : integer;
{-----------------------------------------------------------}
{ The following routine is included for the CPUSH and CINV  }
{ instructions added with the 68040 support. The parsing of }
{ the first operand with these instructions is so elementary}
{ that it didn't seem worth it to mess with PARSEOPERAND.   }

{ Returns : 1 if DATA cache only                            }
{           2 if INSTRUCTION CACHE only                     }
{           3 if BOTH CACHES                                }
{           0 if an ERROR                                   }
{ Expects the syntax to be EXACTLY as follows :             }
{           DC - specifies DATA cache                       }
{           IC - specifies INSTRUCTION cache                }
{           DC/IC or IC/DC -  specifies BOTH caches         }
{ except that lowercase letters are permitted (they're      }
{ converted to uppercase by the line scanner ).             }
LABEL 1,2;
{ LABEL 1 : clean exit point.                               }
{ LABEL 2 : error exit point.                               }
BEGIN
  IF LINE[CURCOL] = 'D' THEN
   BEGIN
    IF LINE[CURCOL+1] = 'C' THEN PARSE_CACHES := 1 ELSE GOTO 2;
    CURCOL := CURCOL + 2;
    IF LINE[CURCOL] <> '/' THEN GOTO 1 ELSE
     BEGIN
      CURCOL := CURCOL + 1;
      IF LINE[CURCOL] = 'I' THEN
       BEGIN
	IF LINE[CURCOL+1] = 'C' THEN
	 BEGIN PARSE_CACHES :=  3; CURCOL := CURCOL + 2; GOTO 1; END
	ELSE GOTO 2;
       END
      ELSE GOTO 2;
     END;
   END;

  { IF LINE[CURCOL] = 'D' WAS TRUE, CONTROL SHOULDN'T BE HERE. }

  IF LINE[CURCOL] = 'I' THEN
   BEGIN
    IF LINE[CURCOL+1] = 'C' THEN PARSE_CACHES := 2 ELSE GOTO 2;
    CURCOL := CURCOL + 2;
    IF LINE[CURCOL] <> '/' THEN GOTO 1 ELSE
     BEGIN
      CURCOL := CURCOL + 1;
      IF LINE[CURCOL] = 'D' THEN
       BEGIN
	IF LINE[CURCOL+1] = 'C' THEN
	 BEGIN PARSE_CACHES :=  3; CURCOL := CURCOL + 2; GOTO 1; END
	ELSE GOTO 2;
       END
      ELSE GOTO 2;
     END;
   END;

2: PARSE_CACHES := 0;
1:
END;

PROCEDURE PARSE_BITFIELD{(VAR BF: BITFIELDTYPE)};  {FWD}
VAR
  TEMPOP: OPERAND;
BEGIN
IF LINE[CURCOL]<>'{' THEN
  BEGIN IF PASS=2 THEN ERROR(ERRLBRACEEXP); ESCAPE(BADOPS); END;
CURCOL:=CURCOL+1;
TEMPOP.VALUE.EXPREFS:=NIL;
PARSEOPERAND(TEMPOP);
IF (TEMPOP.MODE<>0) AND ((TEMPOP.MODE<>7) OR (TEMPOP.REG<>0)) THEN
  BEGIN IF PASS=2 THEN ERROR(ERRBADMODE); ESCAPE(BADOPS); END;
IF (TEMPOP.VALUE.EXPREFS<>NIL) THEN
  BEGIN
  TEMPOP.VALUE.EXPREFS:=NIL;
  TEMPOP.VALUE.OFFSET :=ZERO32;
  IF PASS=2 THEN ERROR(ERREXTREFS);
  ESCAPE(BADOPS);
  END;
IF (TEMPOP.MODE<>0) AND
   ((0>TEMPOP.VALUE.OFFSET.LONGINT) OR (TEMPOP.VALUE.OFFSET.LONGINT>=32)) THEN
  BEGIN IF PASS=2 THEN ERROR(ERRFIELDOFLO); ESCAPE(BADOPS); END;
IF TEMPOP.MODE=0 THEN
  BEGIN   (* D-register *)
  BF.DOFF:=TRUE;
  BF.OFFSET:=TEMPOP.REG;
  END
ELSE
  BEGIN   (* constant *)
  BF.DOFF:=FALSE;
  BF.OFFSET:=TEMPOP.VALUE.OFFSET.LONGINT;
  END;
IF LINE[CURCOL]<>':' THEN
  BEGIN IF PASS=2 THEN ERROR(ERRCOLONEXP); ESCAPE(BADOPS); END;
CURCOL:=CURCOL+1;
TEMPOP.VALUE.EXPREFS:=NIL;
PARSEOPERAND(TEMPOP);
IF (TEMPOP.MODE<>0) AND ((TEMPOP.MODE<>7) OR (TEMPOP.REG<>0)) THEN
  BEGIN IF PASS=2 THEN ERROR(ERRBADMODE); ESCAPE(BADOPS); END;
IF (TEMPOP.VALUE.EXPREFS<>NIL) THEN
  BEGIN
  TEMPOP.VALUE.EXPREFS:=NIL;
  TEMPOP.VALUE.OFFSET :=ZERO32;
  IF PASS=2 THEN ERROR(ERREXTREFS);
  ESCAPE(BADOPS);
  END;
IF (TEMPOP.MODE<>0) AND   (* different from offset field *)
   ((0>=TEMPOP.VALUE.OFFSET.LONGINT) OR (TEMPOP.VALUE.OFFSET.LONGINT>32)) THEN
  BEGIN IF PASS=2 THEN ERROR(ERRFIELDOFLO); ESCAPE(BADOPS); END;
IF (TEMPOP.MODE<>0) AND
   (TEMPOP.VALUE.OFFSET.LONGINT=32) THEN
    TEMPOP.VALUE.OFFSET.LONGINT:=0;
IF TEMPOP.MODE=0 THEN
  BEGIN   (* D-register *)
  BF.DWID:=TRUE;
  BF.WIDTH :=TEMPOP.REG;
  END
ELSE
  BEGIN   (* constant *)
  BF.DWID:=FALSE;
  BF.WIDTH :=TEMPOP.VALUE.OFFSET.LONGINT;
  END;
IF LINE[CURCOL]<>'}' THEN
  BEGIN IF PASS=2 THEN ERROR(ERRRBRACEEXP); ESCAPE(BADOPS); END;
CURCOL:=CURCOL+1;
END;


FUNCTION CHECKREGS; { FWD DECLARED }
VAR
  HOLDCOL: SHORTINT;
  RVALUE: EXPRVALUE;
  TPASS: 1..2;
BEGIN
HOLDCOL:=CURCOL;
TPASS:=PASS; PASS:=1;  { KLUGE TO AVOID UNDEFINED SYMBOL ERRORS }
GETSYMBOL(RVALUE, HOLDCOL);
PASS:=TPASS;
IF (RVALUE.BASE=AREG) OR (RVALUE.BASE=DREG) OR (RVALUE.BASE=FPREG) THEN
  BEGIN
  CHECKREGNO:=RVALUE.OFFSET.LOHALF;
  CHECKREGMODE:=RVALUE.BASE;
  CHECKREGS:=TRUE;
  CURCOL:=HOLDCOL;
  END
ELSE
  CHECKREGS:=FALSE;
END;


FUNCTION CHECKSPREGS; { CHECKS FOR CCR, SR, USP } { FWD DECLARED }
VAR                   { ALSO DFC, SFC, VBR } { AND MSP,ISP,CACR,CAAR }
  HOLDCOL: SHORTINT;
  RVALUE: EXPRVALUE;
  TPASS: 1..2;
BEGIN
HOLDCOL:=CURCOL;
TPASS:=PASS; PASS:=1;  { KLUGE TO AVOID UNDEF SYMBOL ERRORS }
GETSYMBOL(RVALUE, HOLDCOL);
PASS:=TPASS;
IF (RVALUE.BASE=STREG) OR (RVALUE.BASE=FPSTREG) THEN
  BEGIN
  CHECKREGNO:=RVALUE.OFFSET.LOHALF;
  CHECKREGMODE:=RVALUE.BASE;
  CHECKSPREGS:=TRUE;
  CURCOL:=HOLDCOL;
  END
ELSE
  CHECKSPREGS:=FALSE
END;


PROCEDURE PARSEOPERAND{(VAR OP:OPERAND)};  {FWD}
VAR HOLDCOL: SHORTINT;
    REGSUFFIX: CHAR;


PROCEDURE GETINDEX;
BEGIN
IF CHECKREGS THEN
  BEGIN
  IF LINE[CURCOL]='.' THEN
    BEGIN
    REGSUFFIX:=LINE[CURCOL+1];
    IF LINE[CURCOL+1]<>BLANK THEN CURCOL:=CURCOL+2;
    END (* LINE[CURCOL]='.' *)
  ELSE
    REGSUFFIX:=' ';
  OP.INDEX:=CHECKREGNO;
  IF CHECKREGMODE=AREG
    THEN OP.INDEXMODE:=ADDRS
    ELSE OP.INDEXMODE:=DATA;
$if mc68881$
  if (pass=2) and (checkregmode=fpreg) then
      error(errfpregnotallowed);
$end$
  IF      REGSUFFIX='L' THEN
    OP.INDEXSIZE:=LONG
  ELSE IF REGSUFFIX='W' THEN
    OP.INDEXSIZE:=WRD
  ELSE IF REGSUFFIX=' ' THEN
    OP.INDEXSIZE:=WRD
  ELSE
    IF PASS=2 THEN ERROR(ERRBADSUFFIX);

  IF LINE[CURCOL]<>'*' THEN
    OP.INDEXSCALE:=0
  ELSE
    BEGIN { MUST BE A SCALE FACTOR }
    CURCOL:=CURCOL+1;
    IF      LINE[CURCOL]='1' THEN
      OP.INDEXSCALE:=0
    ELSE IF LINE[CURCOL]='2' THEN
      OP.INDEXSCALE:=1
    ELSE IF LINE[CURCOL]='4' THEN
      OP.INDEXSCALE:=2
    ELSE IF LINE[CURCOL]='8' THEN
      OP.INDEXSCALE:=3
    ELSE
      IF PASS=2 THEN ERROR(ERRBADSCALE);
    IF LINE[CURCOL]<>BLANK THEN CURCOL:=CURCOL+1;
    END;

  END (* CHECKREGS *)
ELSE (* NOT CHECKREGS *)
  IF PASS=2 THEN ERROR(ERRREGEXP)
END; (* GETINDEX *)


PROCEDURE GETDISPSIZE(VALUE: EXPRVALUE;
		  VAR SIZE: DISPSIZE;
		  VAR INCRSIZE: OPSIZETYPE);
(* Based on VALUE.OFFSET, set SIZE to S_NULL, S_WORD, or S_LONG,
(* and increment INCRSIZE by 0, 2, or 4 bytes
(**)
(* mostly swiped from ABSORINDEXED *)
BEGIN
IF VALUE.EMODE=NOMODE THEN
  BEGIN
  IF VALUE.BASE=RELATIVE THEN
    BEGIN
    IF ORGMODE=LONGFWDS
      THEN SIZE:=S_LONG
      ELSE SIZE:=S_WORD;
    END (* VALUE.BASE=RELATIVE *)
  ELSE
    BEGIN
    IF (EVALOK<>OK1) OR (VALUE.EXPREFS<>NIL) THEN { FWD OR EXT REF }
      BEGIN
      IF ORGMODE=LONGFWDS THEN
	SIZE:=S_LONG
      ELSE
	BEGIN
	SIZE:=S_WORD;
	IF (PASS=2) AND NOT(FITSIN16(VALUE.OFFSET))
	   THEN ERROR(ERRFIELDOFLO);
	END
      END (* (EVALOK<>OK1) OR (VALUE.EXPREFS<>NIL) *)
    ELSE { NOT FWD REF }
      IF      0 =     (VALUE.OFFSET.LONGINT) THEN (* FITSIN0 *)
	SIZE:=S_NULL
      ELSE IF FITSIN16(VALUE.OFFSET) THEN
	SIZE:=S_WORD
      ELSE (* FITSIN32(VALUE.OFFSET) *)
	SIZE:=S_LONG;
    END (* VALUE.BASE<>RELATIVE *)
  END (* VALUE.EMODE=NOMODE *)
ELSE IF VALUE.EMODE=RMODE THEN
  SIZE:=S_WORD
ELSE IF VALUE.EMODE=LMODE THEN
  SIZE:=S_LONG
ELSE (* VALUE.EMODE=SMODE *)
  BEGIN
  SIZE:=S_WORD;
  IF (PASS=2) AND NOT(FITSIN16(VALUE.OFFSET)) THEN
    ERROR(ERRFIELDOFLO);
  END; (* VALUE.EMODE=SMODE *)
IF      SIZE=S_LONG THEN INCRSIZE:=INCRSIZE+4
ELSE IF SIZE=S_WORD THEN INCRSIZE:=INCRSIZE+2;
END;


PROCEDURE IMMEDOP;
$if fpimmed$
var
  specialcaseit : boolean;        (* handling FMOVE.P FPn,<ea>(#k)
					   or FMOVECR.X #ccc,FPn ? *)
$end$
BEGIN
  CURCOL := CURCOL + 1;
$if fpimmed$
  if (currop.class = (fpbase+0))        (* FMOVE instructions *)
     and ( ((currop.name[6] = 'C') and (currop.name[7] = 'R'))  (* FMOVECR *)
	or ((line[curcol-2] = '{') and (operand1.mode = 8)
	and (sizesuffix = 'P')) ) (* FMOVE FPn,<ea>(#k) *) then
    specialcaseit := true
  else
    specialcaseit := false;
if (sizesuffix = 'D') and not specialcaseit then
  begin
  if fpimmedexp( pass=2, evalok, evalue, curcol ) then
    begin
    if (not allowfpopds) and (pass = 2) then
      error( errfpopdnotallowed );
    end
  else
    begin
    if pass = 2 then
      error( errfpconstneeded );
    end;
  end
else
$end$
EXPRESS(PASS=2,EVALOK,EVALUE,CURCOL);
OP.MODE:=7;
OP.REG:=4;
OP.VALUE:=EVALUE;
$if fpimmed$
if specialcaseit then
  op.size := 0
else
$end$
if sizesuffix = 'B' then
  BEGIN
  OP.SIZE:=2;
  IF PASS=2 THEN
    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);
  END
else if (sizesuffix = 'W') or (sizesuffix = ' ') then
  BEGIN
  OP.SIZE:=2;
  IF PASS=2 THEN
    IF NOT(FITSIN16(EVALUE.OFFSET)) AND
       (EVALUE.OFFSET.HIHALF<>0) AND
       (EVALUE.EXPREFS=NIL)
      THEN ERROR(ERRFIELDOFLO);
  END
else if sizesuffix = 'L' then
$if not fpimmed$
  OP.SIZE:=4;
$end$
$if fpimmed$
  op.size := 4
else if sizesuffix = 'D' then op.size := 8
else
  begin
  error( errfpimmedsize );
  op.size := 8;
  with op.value do
    begin
    base := absolut;
    offset.fltpt := 0.0;
    exprefs := nil;
    emode := nomode;
    end;
  end;
			(* full flt. pt. support will require mods
			   here, note too that sizesuffix = ' ' will
			   likely need to allow implicit flt. pt.
			   minimum req'rd size selection

else if sizesuffix = 'S' then op.size := 4
else if sizesuffix = 'D' then op.size := 8
else if sizesuffix = 'X' then op.size := 12
else if sizesuffix = 'P' then op.size := 12;
					---------------------- ??? *)
$end$
END;


PROCEDURE INDIRECT;
(* NOW INCLUDES:
(* 2n (An)                      An IND.
(* 3n (An)+                     An IND. WITH POSTINCREMENT
(* 5n (d16,An)                  An IND. WITH DISP.
(* 6n (d8,An,Xn.SIZE*SCALE)     An IND. WITH INDEX (8-BIT DISP.)
(* 6n (bd,An,Xn.SIZE*SCALE)     An IND. WITH INDEX (BASE DISP.)
(* 6n ([bd,An],Xn.SIZE*SCALE,od)   MEMORY IND. POST-INDEXED
(* 6n ([bd,An,Xn.SIZE*SCALE],od)   MEMORY IND. PRE-INDEXED
(* 73 (rd8,Xn.SIZE*SCALE)       PC IND. WITH INDEX (8-BIT DISP.)
(* 73 (rbd,Xn.SIZE*SCALE)       PC IND. WITH INDEX (BASE DISP.)
(* 73 ([rbd],Xn.SIZE*SCALE,od)  PC MEMORY IND. POST-INDEXED
(* 73 ([rbd,Xn.SIZE*SCALE],od)  PC MEMORY IND. PRE-INDEXED
(*
(* OPERAND RECORD:
(*      SIZE:           total size of operand
(*      MODE:           mode, goes in EA
(*      REG:            An, goes in EA

(*      INDEXMODE:      index is An/Dn (ADDRS,DATA)
(*      INDEX:          Xn
(*      INDEXSIZE:      SIZE (WRD,LONG)
(*      INDEXSCALE:     SCALE (0..3)
(*      FULL_FORMAT:
(*      BASE_SUPPRESS:  didn't see base
(*      INDEX_SUPPRESS: didn't see index
(*      BD_SIZE:        size of bd (S_RES,S_NULL,S_WORD,S_LONG)
(*      FILL:           zero bit
(*      POST_INDEXED:   index was seen outside ']'
(*      OD_SIZE:        size of od (S_RES,S_NULL,S_WORD,S_LONG)

(*      VALUE:          inner (also called base) or only displacement
(*      OD_VALUE:       outer displacement
(**)
VAR
  ININNER,SEENINNER,SEENID,SEENOD,SEENAN,SEENZPC,SEENINDEX: BOOLEAN;
  COLL: SHORTINT;
  VAL: EXPRVALUE;
  VALUEOK: EVALWHEN;
  INDISPLACEMENT,ININDEX: BOOLEAN;


  PROCEDURE CHANGE_An_TO_INDEX(NEW_POST_INDEXED: BOOLEAN);
  BEGIN
  IF SEENAN AND NOT SEENZPC THEN
    BEGIN (* NEED TO CHANGE OLD An TO INDEX *)
    IF SEENINDEX THEN
      BEGIN IF PASS=2 THEN ERROR(ERR2INDEX); ESCAPE(BADOPS); END;
    SEENINDEX:=TRUE;
    SEENAN   :=FALSE;
    OP.POST_INDEXED:=NEW_POST_INDEXED;
    OP.INDEXMODE :=ADDRS;
    OP.INDEX     :=OP.REG;
    OP.INDEXSIZE :=WRD;
    OP.INDEXSCALE:=0;
    END;
  END;


BEGIN
ININNER    :=FALSE;
SEENINNER  :=FALSE;
SEENID     :=FALSE;
SEENOD     :=FALSE;
SEENAN     :=FALSE;
SEENZPC    :=FALSE;
SEENINDEX  :=FALSE;
VALUEOK:=OK1;   (* 870814 *)
EVALOK :=OK1;   (* 870814 *)
OP.FILL:=           FALSE;
OP.POST_INDEXED:=   FALSE;
OP.VALUE.OFFSET:=   ZERO32;
OP.VALUE.EXPREFS:=  NIL;
OP.VALUE.BASE:=     ABSOLUT;
OP.VALUE.EMODE:=    NOMODE; (* 870814 *)
OP.OD_VALUE.OFFSET:=   ZERO32;
OP.OD_VALUE.EXPREFS:=  NIL;
OP.OD_VALUE.BASE:=     ABSOLUT;
OP.OD_VALUE.EMODE:=    NOMODE; (* 870814 *)
CURCOL:=CURCOL+1;
TRY
  WHILE TRUE DO (* exits with ESCAPE(OPSOK) *)
    BEGIN
    IF LINE[CURCOL]='[' THEN
      BEGIN
      IF SEENINNER THEN
	BEGIN IF PASS=2 THEN ERROR(ERR2INNER); ESCAPE(BADOPS); END;
      IF SEENZPC THEN
	BEGIN IF PASS=2 THEN ERROR(ERRMISZPC); ESCAPE(BADOPS); END;
      CHANGE_An_TO_INDEX(TRUE);
      ININNER:=TRUE;
      SEENINNER:=TRUE;
      OP.OD_VALUE:=OP.VALUE;
      IF SEENINDEX THEN OP.POST_INDEXED:=TRUE;
      CURCOL:=CURCOL+1;
      END;
    IF ('A'<=LINE[CURCOL]) AND (LINE[CURCOL]<='Z') OR (LINE[CURCOL]='_') THEN
      BEGIN
      COLL:=CURCOL;
      GETSYMBOL(VAL,COLL);
      INDISPLACEMENT:=(VAL.BASE<>AREG) AND (VAL.BASE<>DREG) AND (VAL.BASE<>PREG);
      (* THIS WILL CATCH SPREG, AND FP REGS IN EXPRESS BELOW *)
      END
    ELSE
      INDISPLACEMENT:=TRUE;
    IF INDISPLACEMENT THEN
      BEGIN (* INDISPLACEMENT *)
      EXPRESS(PASS=2,EVALOK,EVALUE,CURCOL);
      (* ININNER T T T T F F F F
      (* SEENID  T T F F T T F F
      (* SEENOD  T F T F T F T F
      (*         e e m v e o e v
      (*
      (* e: error;  m: move VALUE to OD_VALUE, store in VALUE
      (* v: store in VALUE;  o: store in OD_VALUE
      (**)
      IF ININNER THEN
	BEGIN
	IF SEENID THEN
	  BEGIN IF PASS=2 THEN ERROR(ERR2DISP); ESCAPE(BADOPS); END;
	SEENID:=TRUE;
	IF SEENOD THEN
	  BEGIN
	  OP.OD_VALUE:=OP.VALUE;
	  IF OP.OD_VALUE.BASE=RELATIVE THEN
	    BEGIN IF PASS=2 THEN ERROR(ERRRELREFS); ESCAPE(BADOPS); END;
	  END;
	OP.VALUE:=EVALUE;
	VALUEOK:=EVALOK;
	IF OP.VALUE.BASE=RELATIVE THEN
	  CHANGE_An_TO_INDEX(FALSE);
	END
      ELSE
	BEGIN
	IF SEENOD THEN
	  BEGIN IF PASS=2 THEN ERROR(ERR2DISP); ESCAPE(BADOPS); END;
	SEENOD:=TRUE;
	IF SEENINNER THEN
	  BEGIN
	  OP.OD_VALUE:=EVALUE;
	  IF OP.OD_VALUE.BASE=RELATIVE THEN
	    BEGIN IF PASS=2 THEN ERROR(ERRRELREFS); ESCAPE(BADOPS); END;
	  END
	ELSE
	  BEGIN
	  OP.   VALUE:=EVALUE;
	  VALUEOK:=EVALOK;
	  IF OP.VALUE.BASE=RELATIVE THEN
	    CHANGE_An_TO_INDEX(FALSE);
	  END;
	END;
      END (* INDISPLACEMENT *)
    ELSE
      BEGIN (* NOT INDISPLACEMENT *)
      (* THIS CAN ONLY HAPPEN IF GETSYMBOL(VAL,COLL) WAS CALLED *)
      IF      VAL.BASE=AREG THEN
	ININDEX:=(LINE[COLL]='*') OR (LINE[COLL]='.') OR SEENAN OR
		 (SEENINNER AND NOT ININNER) OR (OP.VALUE.BASE=RELATIVE)
      ELSE IF VAL.BASE=DREG THEN
	ININDEX:=TRUE
      ELSE (* VAL.BASE=PREG *)
	BEGIN
	ININDEX:=FALSE;
	IF SEENZPC THEN
	  BEGIN IF PASS=2 THEN ERROR(ERR2ZPC); ESCAPE(BADOPS); END;
	IF SEENINNER AND NOT ININNER THEN
	  BEGIN IF PASS=2 THEN ERROR(ERRMISZPC); ESCAPE(BADOPS); END;
	CHANGE_An_TO_INDEX(FALSE);
	SEENZPC:=TRUE;
	END;
      IF ININDEX THEN
	BEGIN (* ININDEX *)
	IF SEENINDEX THEN
	  BEGIN IF PASS=2 THEN ERROR(ERR2INDEX); ESCAPE(BADOPS); END;
	SEENINDEX:=TRUE;
	GETINDEX;
	OP.POST_INDEXED:=NOT ININNER AND SEENINNER;
	END (* ININDEX *)
      ELSE
	BEGIN (* ADDRESS REGISTER OR ZPC *)
	CURCOL:=COLL; (* ALREADY PARSED BY GETSYMBOL *)
	SEENAN:=TRUE;
	OP.REG:=VAL.OFFSET.LONGINT; (* 16 FOR ZPC *)
	END; (* ADDRESS REGISTER OR ZPC *)
      END; (* NOT INDISPLACEMENT *)
    IF LINE[CURCOL]=']' THEN
      BEGIN
      IF NOT ININNER THEN
	BEGIN IF PASS=2 THEN ERROR(ERRRBRACKUNEXP); ESCAPE(BADOPS); END;
      ININNER:=FALSE;
      CURCOL:=CURCOL+1;
      END;
    IF LINE[CURCOL]=')' THEN
      BEGIN
      IF ININNER THEN
	BEGIN IF PASS=2 THEN ERROR(ERRRBRACKEXP); ESCAPE(BADOPS); END;
      ESCAPE(OPSOK);
      END;
    IF LINE[CURCOL]=',' THEN
      CURCOL:=CURCOL+1
    ELSE
      BEGIN IF PASS=2 THEN ERROR(ERRCOMMAEXP); ESCAPE(BADOPS); END;
  END; (* infinite WHILE *)
RECOVER
  IF ESCAPECODE=BADOPS THEN
    BEGIN (* BADOPS *)
    OP.REG:=            0;
    OP.INDEXMODE:=      DATA;
    OP.INDEX:=          0;
    OP.INDEXSIZE:=      WRD;
    OP.INDEXSCALE:=     0;
    OP.POST_INDEXED:=   FALSE;
    OP.VALUE.OFFSET:=   ZERO32;
    OP.VALUE.EXPREFS:=  NIL;
    OP.VALUE.BASE:=     ABSOLUT;
    OP.OD_VALUE.OFFSET:=   ZERO32;
    OP.OD_VALUE.EXPREFS:=  NIL;
    OP.OD_VALUE.BASE:=     ABSOLUT;
    END; (* BADOPS *)
(*
(* SEENINNER T T T T T T T T T T T T T T T T F F F F F F F F F F F F F F F F
(* SEENID    T T T T T T T T F F F F F F F F T T T T T T T T F F F F F F F F
(* SEENOD    T T T T F F F F T T T T F F F F T T T T F F F F T T T T F F F F
(* SEENAN    T T F F T T F F T T F F T T F F T T F F T T F F T T F F T T F F
(* SEENINDEX T F T F T F T F T F T F T F T F T F T F T F T F T F T F T F T F
(*           6 6 ? ? 6 6 ? ? 6 6 . . 6 6 . . . . . . . . . . 6 5 ? ? 6 2 6 .
(* ?: MODE=IF VALUE IS REL THEN 7 ELSE 6
(* .: IMPOSSIBLE
(**)
CURCOL:=CURCOL+1;
OP.SIZE:=0; (* LET'S START WITH THIS *)
(* The following code is needed to reduce the address to an offset,
(* if possible, so that GETDISPSIZE and FITSIN16 will produce the
(* correct size.
(**)
VAL:=OP.VALUE;
IF OP.VALUE.BASE=RELATIVE THEN
  BEGIN
  IF VALUEOK=OK1 THEN
    BEGIN
    VAL.BASE:=ABSOLUT;
    (* A guess is made here that the distance between the operator
    (* start (LOCCTR) and the operand start is 2 bytes.  The operand
    (* start is where PC is at runtime when the operand is evaluated
    (* (at runtime).
    (**)
    VAL.OFFSET.LONGINT:=VAL.OFFSET.LONGINT-(LOCCTR.LONGINT+2);
    END;
  END;
IF  SEENAN    AND
NOT SEENINNER AND
NOT SEENID    AND
NOT SEENINDEX AND
NOT SEENZPC   AND
FITSIN16(VAL.OFFSET) THEN
  BEGIN (* EA=2n, 3n, or 5n *)
  IF SEENOD THEN
    BEGIN (* EA=5n *)
    OP.SIZE:=OP.SIZE+2;
    OP.MODE:=5;
    END (* EA=5n *)
  ELSE
    BEGIN (* EA=2n or 3n *)
    IF LINE[CURCOL]='+' THEN
      BEGIN (* EA=3n *)
      OP.MODE:=3;
      CURCOL:=CURCOL+1;
      END (* EA=3n *)
    ELSE
      BEGIN (* EA=2n *)
      OP.MODE:=2;
      END; (* EA=2n *)
    END (* EA=2n or 3n *)
  END (* EA=2n, 3n, or 5n *)
ELSE
  BEGIN (* EA=6n or 73 *)
  OP.SIZE:=OP.SIZE+2; (* ROOM FOR EXTENSION WORD *)
  IF ({NOT SEENAN AND} (OP.VALUE.BASE=RELATIVE)) OR SEENZPC THEN
    BEGIN OP.MODE:=7; OP.REG:=3; END
  ELSE
    OP.MODE:=6;
  OP.FULL_FORMAT:=
    SEENINNER OR
    NOT SEENINDEX OR
    NOT SEENOD OR
    NOT FITSIN8(VAL.OFFSET) OR
       (VALUEOK<>OK1) OR (VAL.EXPREFS<>NIL) OR   { LAF 870323 SR46894 & others }
    (NOT SEENAN AND (OP.VALUE.BASE=ABSOLUT)) OR
    SEENZPC;
  IF OP.FULL_FORMAT THEN
    BEGIN
    OP.BASE_SUPPRESS:=(NOT SEENAN AND (OP.MODE=6)) OR SEENZPC;
    IF OP.BASE_SUPPRESS AND NOT SEENZPC THEN
      OP.REG:=0; (* MAKE IT A LITTLE CLEANER *)
    IF SEENINNER THEN
      BEGIN
      GETDISPSIZE(      VAL  ,OP.BD_SIZE,OP.SIZE);
      GETDISPSIZE(OP.OD_VALUE,OP.OD_SIZE,OP.SIZE);
      END
    ELSE
      BEGIN
      GETDISPSIZE(      VAL  ,OP.BD_SIZE,OP.SIZE);
			      OP.OD_SIZE:=S_RES;
      END;
    OP.INDEX_SUPPRESS:=NOT SEENINDEX;
    IF OP.INDEX_SUPPRESS THEN
      BEGIN (* MAKE IT A LITTLE CLEANER *)
      OP.INDEXMODE:=      DATA;
      OP.INDEX:=          0;
      OP.INDEXSIZE:=      WRD;
      OP.INDEXSCALE:=     0;
      END;
    IF NOT SEENINNER THEN
      OP.POST_INDEXED:=FALSE;
    END; (* OP.FULL_FORMAT *)
  END; (* EA=6n or 73 *)
END;


$IF FALSE$
PROCEDURE  INDORAUTOINC;  (* REPLACED BY 'INDIRECT' *)
BEGIN
CURCOL:=CURCOL+1;
OP.MODE:=2;
OP.SIZE:=0;
IF CHECKREGS THEN
  IF CHECKREGMODE=AREG THEN
    BEGIN
    OP.REG:=CHECKREGNO;
    IF (LINE[CURCOL]=')') AND (LINE[CURCOL+1]='+') THEN
      BEGIN
      OP.MODE:=3;
      CURCOL:=CURCOL+2;
      END
    ELSE (* <>')+' *)
      BEGIN
      IF LINE[CURCOL]=')'
	THEN CURCOL:=CURCOL+1
	ELSE IF PASS=2 THEN ERROR(ERRCLOSEPEXP);
      END; (* <>')+' *)
    END (* CHECKREGMODE=AREG *)
  ELSE (* CHECKREGMODE<>AREG *)
    IF PASS=2 THEN ERROR(ERRAREGEXP) ELSE
ELSE (* NOT CHECKREGS *)
  IF PASS=2 THEN ERROR(ERRAREGEXP);
END;
$END$


PROCEDURE AUTODEC;
BEGIN
CURCOL:=CURCOL+2;
OP.MODE:=4;
OP.SIZE:=0;
IF CHECKREGS THEN
  IF CHECKREGMODE=AREG THEN
    IF LINE[CURCOL]=')' THEN
      BEGIN
      CURCOL:=CURCOL+1;
      OP.REG:=CHECKREGNO;
      END
    ELSE
       BEGIN IF PASS=2 THEN ERROR(ERRCLOSEPEXP) END
  ELSE
    BEGIN IF PASS=2 THEN ERROR(ERRAREGEXP) END
ELSE IF PASS=2 THEN ERROR(ERRAREGEXP);
END;


PROCEDURE ABSORINDEXED;
BEGIN
EXPRESS(PASS=2, EVALOK, EVALUE, CURCOL);
OP.VALUE:=EVALUE;
IF LINE[CURCOL]='(' THEN  { INDEXED }
  BEGIN
  OP.FULL_FORMAT:=FALSE;
  CURCOL:=CURCOL+1;
  IF EVALUE.BASE=RELATIVE THEN
    BEGIN
    OP.MODE:=7; OP.REG :=3; OP.SIZE:=2;
    GETINDEX;
    IF LINE[CURCOL]<>')' THEN
      BEGIN IF PASS=2 THEN ERROR(ERRCLOSEPEXP) END
    ELSE
      CURCOL:=CURCOL+1;
    END (* EVALUE.BASE=RELATIVE *)
  ELSE
    BEGIN { ABSOLUTE INDEXED }
    { ASSUMPTION FOR NOW }
    OP.MODE:=5; OP.REG :=0; OP.SIZE:=2;
    OP.INDEXMODE:=ADDRS;
    OP.INDEXSIZE:=WRD;
    IF CHECKREGS THEN
      BEGIN
      IF (CHECKREGMODE=AREG) OR (PASS=1) THEN
	BEGIN
	OP.REG:=CHECKREGNO;
	IF LINE[CURCOL]=',' THEN { LOOK FOR ANOTHER REG }
	  BEGIN
	  CURCOL:=CURCOL+1;
	  OP.MODE:=6;
	  GETINDEX;
	  IF LINE[CURCOL]<>')' THEN
	    BEGIN IF PASS=2 THEN ERROR(ERRCLOSEPEXP) END
	  ELSE
	    CURCOL:=CURCOL+1;
	  IF (PASS=2) AND NOT(FITSIN8(EVALUE.OFFSET)) THEN
	    ERROR(ERRFIELDOFLO);
	  END (* LINE[CURCOL]=',' *)
	ELSE { ADDR REG PLUS DISPLACEMENT }
	  BEGIN
	  IF PASS=1 THEN
	    IF LINE[CURCOL]='.' THEN
	      BEGIN
	      CURCOL:=CURCOL+1;
	      IF (LINE[CURCOL]<>')') AND (LINE[CURCOL]<>' ') THEN
		CURCOL:=CURCOL+1;
	      END; (* LINE[CURCOL]='.' *) (* PASS=1 *)
	  IF LINE[CURCOL]<>')' THEN
	    BEGIN IF PASS=2 THEN ERROR(ERRCLOSEPEXP) END
	  ELSE (* LINE[CURCOL]=')' *)
	    BEGIN
	    CURCOL:=CURCOL+1;
	    IF (PASS=2) AND NOT(FITSIN16(EVALUE.OFFSET)) THEN
	      ERROR(ERRFIELDOFLO);
	    END (* LINE[CURCOL]=')' *)
	  END (* LINE[CURCOL]<>',' *)
	END (* (CHECKREGMODE=AREG) OR (PASS=1) *)
      ELSE
	BEGIN IF PASS=2 THEN ERROR(ERRAREGEXP) END;
      END (* CHECKREGS *)
    ELSE
      BEGIN IF PASS=2 THEN ERROR(ERRAREGEXP) END
    END (* EVALUE.BASE<>RELATIVE *)
  END (* LINE[CURCOL]='(' *)
ELSE
  BEGIN { ABS OR REL WITH NO INDEX REGS }
  OP.MODE:=7;
  IF EVALUE.EMODE=NOMODE THEN
    BEGIN
    IF EVALUE.BASE=RELATIVE THEN
      BEGIN
      if orgmode=longfwds then
	begin op.reg :=1; op.size:=4; end
      else
	begin OP.REG :=2; OP.SIZE:=2; end
      END (* EVALUE.BASE=RELATIVE *)
    ELSE
      BEGIN
      IF (EVALOK<>OK1) OR (EVALUE.EXPREFS<>NIL) THEN { FWD OR EXT REF }
	BEGIN
	IF ORGMODE=LONGFWDS THEN
	  BEGIN OP.REG :=1; OP.SIZE:=4; END
	ELSE
	  BEGIN
	  OP.REG :=0; OP.SIZE:=2;
	  IF (PASS=2) AND NOT(FITSIN16(OP.VALUE.OFFSET))
	     THEN ERROR(ERRFIELDOFLO);
	  END
	END (* (EVALOK<>OK1) OR (EVALUE.EXPREFS<>NIL) *)
      ELSE { NOT FWD REF }
	IF FITSIN16(EVALUE.OFFSET) THEN
	  BEGIN OP.REG :=0; OP.SIZE:=2; END
	ELSE
	  BEGIN OP.REG :=1; OP.SIZE:=4; END
      END (* EVALUE.BASE<>RELATIVE *)
    END (* EVALUE.EMODE=NOMODE *)
  ELSE IF EVALUE.EMODE=RMODE THEN
    BEGIN OP.REG :=2; OP.SIZE:=2; END
  ELSE IF EVALUE.EMODE=LMODE THEN
    BEGIN OP.REG :=1; OP.SIZE:=4; END
  ELSE (* EVALUE.EMODE=SMODE *)
    BEGIN
    OP.REG :=0; OP.SIZE:=2;
    IF (PASS=2) AND NOT(FITSIN16(EVALUE.OFFSET)) THEN
      ERROR(ERRFIELDOFLO);
    END (* EVALUE.EMODE=SMODE *)
  END (* LINE[CURCOL]<>'(' *)
END; { OF PROCEDURE ABSORINDEXED -- I HOPE }


BEGIN (* PARSEOPERAND *)
IF       LINE[CURCOL]='#' THEN IMMEDOP
ELSE IF  LINE[CURCOL]='(' THEN INDIRECT (* WAS INDORAUTOINC *)
ELSE IF (LINE[CURCOL]='-') AND (LINE[CURCOL+1]='(') THEN AUTODEC
ELSE IF CHECKREGS THEN
  BEGIN
  OP.SIZE:=0;
$if mc68881$
  if      checkregmode=areg then op.mode:=1
  else if checkregmode=fpreg then
    begin
    if allowfpopds then
      op.mode:=8
    else
      begin
      if pass=2 then error(errfpregnotallowed);
      op.mode:=0;
      end;
    end
  else
    op.mode:=0;            (* dreg *)
$end$
$if not mc68881$
  IF CHECKREGMODE=AREG THEN OP.MODE:=1 ELSE OP.MODE:=0;
$end$
  OP.REG:=CHECKREGNO;
  END
ELSE IF CHECKSPREGS THEN
  BEGIN
  OP.SIZE:=0;
$if mc68881$
  if checkregmode=fpstreg then
    begin
    if allowfpopds then
      op.mode:=9
    else
      begin
      if pass=2 then error(errfpregnotallowed);
      op.mode:=7;
      end;
    end
  else
$end$
    OP.MODE:=7;
  OP.REG:=CHECKREGNO;
  END
ELSE ABSORINDEXED;
END; (* PARSEOPERAND *)

$include 'M68KFPMVM'$

@


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.1
log
@Automatic bump of revision number for PWS version 3.23d
@
text
@@


40.2
log
@

          Added function PARSE_CACHES which parses the operands
     for the new 68040 instructions CPUSH and CINV.

          JWH 11/21/89.
@
text
@@


40.1
log
@Automatic bump of revision number for PWS version 3.23c
@
text
@d4 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.2
log
@added initialization for VALUEOK, EVALOK, OP.VALUE.EMODE, OP.OD_VALUE.EMODE
in INDIRECT
@
text
@@


22.1
log
@Automatic bump of revision number for PWS version 3.2N
@
text
@d386 2
d393 1
d397 1
@


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.2
log
@fix for bug reported in STARS REPORT 46894 and
from Northwest Digital Research, Norm Jaffe
@
text
@@


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


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
@d357 1
d363 1
a363 1
  IF SEENAN THEN
d402 2
d407 2
d411 1
a411 1
    IF ('A'<=LINE[CURCOL]) AND (LINE[CURCOL]<='Z') THEN
d443 1
d452 1
a452 1
	IF SEENID THEN
d461 1
d463 1
a463 1
	    CHANGE_An_TO_INDEX(NOT SEENINNER);
d480 3
a483 1
	CHANGE_An_TO_INDEX(TRUE);
d491 1
a491 1
	OP.POST_INDEXED:=NOT ININNER;
a495 2
	IF SEENAN THEN
	  BEGIN IF PASS=2 THEN ERROR(ERR2AN); ESCAPE(BADOPS); END;
d546 24
a569 1
IF SEENAN AND NOT SEENINNER AND NOT SEENID AND NOT SEENINDEX AND NOT SEENZPC THEN
a591 1
  OP.MODE:=6; (* TEMPORARY ASSUMPTION *)
d593 3
a595 1
    BEGIN OP.MODE:=7; OP.REG:=3; END;
d600 1
a600 1
    NOT FITSIN8(OP.VALUE.OFFSET) OR
d610 1
a610 1
      GETDISPSIZE(OP.   VALUE,OP.BD_SIZE,OP.SIZE);
d615 1
a615 1
      GETDISPSIZE(OP.   VALUE,OP.BD_SIZE,OP.SIZE);
@


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.1
log
@Auto bump rev number to 2.1 for sys 3.2e.
@
text
@@


1.1
log
@Initial revision
@
text
@@
