/* code68k.c */
/*****************************************************************************/
/* AS-Portierung                                                             */
/*                                                                           */
/* Codegenerator 680x0-Familie                                               */
/*                                                                           */
/* Historie:  9. 9.1996 Grundsteinlegung                                     */
/*           14.11.1997 Coldfire-Erweiterungen                               */
/*           31. 5.1998 68040-Erweiterungen                                  */
/*            7. 7.1998 Fix Zugriffe auf CharTransTable wg. signed chars     */
/*            3. 1.1999 ChkPC-Anpassung                                      */
/*           17. 1.1999 automatische Laengenanpassung OutDisp                */
/*           23. 1.1999 Einen String an sich selber anzuhaengen, ist keine   */
/*                      gute Idee gewesen :-)                                */
/*           25. 1.1999 falscher Code fuer SBCD korrigiert                   */
/*            5. 7.1999 bei FMOVE FPreg, <ea> war die Modusmaske Humbug...   */
/*                      FSMOVE/FDMOVE fuer 68040 fehlten noch                */
/*            9. 7.1999 In der Bitfeld-Dekodierung war bei der Portierung    */
/*                      ein call-by-reference verlorengegangen               */
/*            3.11.1999 ...in SplitBitField auch!                            */
/*            4.11.1999 FSMOVE/DMOVE auch mit FPn als Quelle                 */
/*                      F(S/D)(ADD/SUB/MUL/DIV)                              */
/*                      FMOVEM statt FMOVE fpcr<->ea erlaubt                 */
/*                                                                           */
/*****************************************************************************/

#include "stdinc.h"
#include <string.h>
#include <ctype.h>

#include "nls.h"
#include "bpemu.h"
#include "endian.h"
#include "strutil.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "asmallg.h"
#include "codepseudo.h"
#include "codevars.h"
#include "asmitree.h"


typedef struct 
         {
	  Word Code;
          Boolean MustSup;
          Word CPUMask;
	 } FixedOrder;

typedef struct 
         {
	  char *Name;
	  Word Code;
	  CPUVar FirstCPU,LastCPU;
	 } CtReg;

typedef struct
         {
          char *Name;
          Byte Code;
          Boolean Dya;
          CPUVar MinCPU;
         } FPUOp;

typedef struct
         {
          char *Name;
          Byte Code;
         } FPUCond;

#define FixedOrderCnt 10
#define CtRegCnt 29
#define CondCnt 20
#define FPUOpCnt 43
#define FPUCondCnt 26
#define PMMUCondCnt 16
#define PMMURegCnt 13

#define PMMUAvailName  "HASPMMU"     /* PMMU-Befehle erlaubt */
#define FullPMMUName   "FULLPMMU"    /* voller PMMU-Befehlssatz */

#define Mdata 1                      /* Adressierungsmasken */
#define Madr 2
#define Madri 4
#define Mpost 8
#define Mpre 16       
#define Mdadri 32
#define Maix 64
#define Mpc 128
#define Mpcidx 256
#define Mabs 512
#define Mimm 1024
#define Mfpn 2048
#define Mfpcr 4096

static Byte OpSize;
static ShortInt RelPos;
static Boolean PMMUAvail;               /* PMMU-Befehle erlaubt? */
static Boolean FullPMMU;                /* voller PMMU-Befehlssatz? */
static Byte AdrNum;                     /* Adressierungsnummer */
static Word AdrMode;                    /* Adressierungsmodus */
static Word AdrVals[10];                /* die Worte selber */

static FixedOrder *FixedOrders;
static CtReg *CtRegs;
static char **CondNams;
static Byte *CondVals;
static FPUOp *FPUOps;
static FPUCond *FPUConds;
static char **PMMUConds;
static char **PMMURegNames;
static Byte *PMMURegSizes;
static Word *PMMURegCodes;
static PInstTable InstTable,FInstTable,CInstTable;

static SimpProc SaveInitProc;

static CPUVar CPU68008,CPU68000,CPU68010,CPU68012,
              CPUCOLD,
              CPU68332,CPU68340,CPU68360,
              CPU68020,CPU68030,CPU68040;

static Word Masks[14]={0,1,2,4,8,16,32,64,128,256,512,1024,2048,4096};
static Byte FSizeCodes[8]={6,4,0,7,1,5,2,3};

/*-------------------------------------------------------------------------*/

#ifdef DEBSTRCNT
static int strcnt=0;

	static int strccmp(const char *s1, const char *s2)
BEGIN
   strcnt++;
   return strcmp(s1,s2);
END

#undef Memo
#define strcmp(s1,s2) strccmp(s1,s2)
#define Memo(s1) (strccmp(s1,OpPart)==0)
#endif

/*-------------------------------------------------------------------------*/
/* Unterroutinen */

#define CopyAdrVals(Dest) memcpy(Dest,AdrVals,AdrCnt)

	static void ACheckCPU(CPUVar MinCPU)
BEGIN
   if (MomCPU<MinCPU) 
    BEGIN
     WrError(1505); AdrNum=0; AdrCnt=0;
    END
END

        static void CheckCPU(CPUVar Level)
BEGIN
   if (MomCPU<Level) 
    BEGIN
     WrError(1500); CodeLen=0;
    END
END

	static void Check020(void)
BEGIN
   if (MomCPU!=CPU68020)
    BEGIN
     WrError(1500); CodeLen=0;
    END
END

	static void Check32(void)
BEGIN
   if ((MomCPU<CPU68332) OR (MomCPU>CPU68360))
    BEGIN
     WrError(1500); CodeLen=0;
    END
END

        static void CheckSup(void)
BEGIN
   if (NOT SupAllowed) WrError(50);
END

	static Boolean CheckColdSize(void)
BEGIN
   if ((OpSize>2) OR ((MomCPU==CPUCOLD) AND (OpSize<2)))
    BEGIN
     WrError(1130); return False;
    END
   else return True;
END

/*-------------------------------------------------------------------------*/
/* Adressparser */

typedef enum {PC,AReg,Index,indir,Disp,None} CompType;
typedef struct 
         {
          String Name;
          CompType Art;
          Word ANummer,INummer;
          Boolean Long;
          Word Scale;
          Word Size;
          LongInt Wert;
         } AdrComp;

	static Boolean ValReg(char Ch)
BEGIN
   return ((Ch>='0') AND (Ch<='7'));
END

	static Boolean CodeReg(char *s, Word *Erg)
BEGIN
   Boolean Result=True;

   if (strcasecmp(s,"SP")==0) *Erg=15;
   else if (ValReg(s[1])) 
    if (toupper(*s)=='D') *Erg=s[1]-'0';
    else if (toupper(*s)=='A') *Erg=s[1]-'0'+8;
    else Result=False;
   else Result=False;

   return Result;
END

        static Boolean CodeRegPair(char *Asc, Word *Erg1, Word *Erg2)
BEGIN
   if (strlen(Asc)!=5) return False;
   if (toupper(*Asc)!='D') return False;
   if (Asc[2]!=':') return False;
   if (toupper(Asc[3])!='D') return False;
   if (NOT (ValReg(Asc[1]) AND ValReg(Asc[4]))) return False;

   *Erg1=Asc[1]-'0'; *Erg2=Asc[4]-'0';

   return True;
END

        static Boolean CodeIndRegPair(char *Asc, Word *Erg1, Word *Erg2)
BEGIN
   if (strlen(Asc)!=9) return False;
   if (*Asc!='(') return False;
   if ((toupper(Asc[1])!='D') AND (toupper(Asc[1])!='A')) return False;
   if (Asc[3]!=')') return False;
   if (Asc[4]!=':') return False;
   if (Asc[5]!='(') return False;
   if ((toupper(Asc[6])!='D') AND (toupper(Asc[6])!='A')) return False;
   if (Asc[8]!=')') return False;
   if (NOT (ValReg(Asc[2]) AND ValReg(Asc[7]))) return False;

   *Erg1=Asc[2]-'0'; if (toupper(Asc[1])=='A') *Erg1+=8;
   *Erg2=Asc[7]-'0'; if (toupper(Asc[6])=='A') *Erg2+=8;

   return True;
END

	static Boolean CodeCache(char *Asc, Word *Erg)
BEGIN
   if (strcasecmp(Asc,"IC")==0) *Erg=2;
   else if (strcasecmp(Asc,"DC")==0) *Erg=1;
   else if (strcasecmp(Asc,"IC/DC")==0) *Erg=3;
   else if (strcasecmp(Asc,"DC/IC")==0) *Erg=3;
   else return False;
   return True;
END	

        static Boolean DecodeCtrlReg(char *Asc, Word *Erg)
BEGIN
   Byte z;
   String Asc_N;
   CtReg *Reg;

   strmaxcpy(Asc_N,Asc,255); NLS_UpString(Asc_N); Asc=Asc_N;

   for (z=0,Reg=CtRegs; z<CtRegCnt; z++,Reg++)
    if (strcmp(Reg->Name,Asc)==0) break;
   if (z>=CtRegCnt) return False;
   if ((MomCPU<Reg->FirstCPU) OR (MomCPU>Reg->LastCPU)) return False;
   *Erg=Reg->Code; return True;
END

	static int FindICondition(char *Name)
BEGIN
   int i;

   for (i=0; i<CondCnt; i++)
    if (strcmp(Name,CondNams[i])==0) break;

   return i;
END

	static Boolean OneField(char *Asc, Word *Erg, Boolean Ab1)
BEGIN
   Boolean ValOK;

   if ((strlen(Asc)==2) AND (toupper(*Asc)=='D') AND (ValReg(Asc[1])))
    BEGIN
     *Erg=0x20+(Asc[1]-'0'); return True;
    END
   else
    BEGIN
     *Erg=EvalIntExpression(Asc,Int8,&ValOK);
     if ((Ab1) AND (*Erg==32)) *Erg=0;
     return ((ValOK) AND (*Erg<32));
    END
END

	static Boolean SplitBitField(char *Arg, Word *Erg)
BEGIN
   char *p;
   Word OfsVal;
   String Desc;

   p = strchr(Arg, '{');
   if (p == Nil) return False;
   *p = '\0'; strcpy(Desc, p + 1);
   if (Desc[strlen(Desc) - 1] != '}') return False;
   Desc[strlen(Desc) - 1] = '\0';

   p = strchr(Desc, ':');
   if (p == Nil) return False;
   *p = '\0';
   if (NOT OneField(Desc, &OfsVal, False)) return False;
   if (NOT OneField(p + 1, Erg, True)) return False;
   *Erg += OfsVal << 6;
   return True;
END

	static Boolean ClassComp(AdrComp *C)
BEGIN
   char sh[10];

   if ((*C->Name=='[') AND (C->Name[strlen(C->Name)-1]==']'))
    BEGIN
     C->Art=indir; return True;
    END

   if (strcasecmp(C->Name,"PC")==0) 
    BEGIN
     C->Art=PC; return True;
    END

   sh[0]=C->Name[0]; sh[1]=C->Name[1]; sh[2]='\0';
   if (CodeReg(sh,&C->ANummer)) 
    BEGIN
     if ((C->ANummer>7) AND (strlen(C->Name)==2)) 
      BEGIN
       C->Art=AReg; C->ANummer-=8; return True;
      END
     else
      BEGIN
       if ((strlen(C->Name)>3) AND (C->Name[2]=='.')) 
        BEGIN
	 switch (toupper(C->Name[3]))
          BEGIN
	   case 'L': C->Long=True; break;
	   case 'W': C->Long=False; break;
	   default: return False;
	  END
	 strcpy(C->Name+2,C->Name+4);
        END
       else C->Long=(MomCPU==CPUCOLD);
       if ((strlen(C->Name)>3) AND (C->Name[2]=='*')) 
        BEGIN
 	 switch (C->Name[3])
          BEGIN
	   case '1': C->Scale=0; break;
	   case '2': C->Scale=1; break;
	   case '4': C->Scale=2; break;
	   case '8': if (MomCPU==CPUCOLD) return False;
	             C->Scale=3; break;
	   default: return False;
	  END
	 strcpy(C->Name+2,C->Name+4);
        END
       else C->Scale=0;
       C->INummer=C->ANummer; C->Art=Index; return True;
      END
    END

   C->Art=Disp;
   if (C->Name[strlen(C->Name)-2]=='.') 
    BEGIN
     switch (toupper(C->Name[strlen(C->Name)-1]))
      BEGIN
       case 'L': C->Size=2; break;
       case 'W': C->Size=1; break;
       default: return False;
      END
     C->Name[strlen(C->Name)-2]='\0';
    END
   else C->Size=1;
   C->Art=Disp;
   return True;
END

	static void ChkAdr(Word Erl)
BEGIN
   if ((Erl & Masks[AdrNum])==0) 
    BEGIN
     WrError(1350); AdrNum=0;
    END
END

	static Boolean IsShortAdr(LongInt Adr)
BEGIN
   Word WHi=(Adr>>16)&0xffff,WLo=Adr&0xffff;
 
   return ((WHi==0     ) AND (WLo<=0x7fff))
       OR ((WHi==0xffff) AND (WLo>=0x8000));
END

	static Boolean IsDisp8(LongInt Disp)
BEGIN
   return ((Disp>=-128) AND (Disp<=127));
END

	static Boolean IsDisp16(LongInt Disp)
BEGIN
   if (Disp<-32768) return False;
   if (Disp>32767) return False;
   return True;
END

	static void ChkEven(LongInt Adr)
BEGIN
   if ((MomCPU<=CPU68340) AND (Odd(Adr))) WrError(180);
END

       	static void DecodeAdr(char *Asc_O, Word Erl)
BEGIN
   Byte l,i;
   char *p;
   Word rerg;
   Byte lklamm,rklamm,lastrklamm;
   Boolean doklamm;

   AdrComp AdrComps[3],OneComp;
   Byte CompCnt;
   String OutDisp;
   ShortInt OutDispLen;
   Boolean PreInd;

#ifdef HAS64
   QuadInt QVal;
#endif
   LongInt HVal;
   Integer HVal16;
   ShortInt HVal8;
   Double DVal;
   Boolean ValOK;
   Word SwapField[6];
   String Asc;
   char CReg[10];

   strmaxcpy(Asc,Asc_O,255); KillBlanks(Asc);
   l=strlen(Asc);
   AdrNum=0; AdrCnt=0;

   /* immediate : */

   if (*Asc=='#') 
    BEGIN
     strcpy(Asc,Asc+1);
     AdrNum=11;
     AdrMode=0x3c;
     switch (OpSize)
      BEGIN
       case 0:
	AdrCnt=2;
	HVal8=EvalIntExpression(Asc,Int8,&ValOK);
	if (ValOK) AdrVals[0]=(Word)((Byte) HVal8);
        break;
       case 1:
	AdrCnt=2;
	HVal16=EvalIntExpression(Asc,Int16,&ValOK);
	if (ValOK) AdrVals[0]=(Word) HVal16;
        break;
       case 2:
	AdrCnt=4;
	HVal=EvalIntExpression(Asc,Int32,&ValOK);
	if (ValOK) 
	 BEGIN
	  AdrVals[0]=HVal >> 16;
	  AdrVals[1]=HVal & 0xffff;
	 END
        break;
#ifdef HAS64
       case 3:
	AdrCnt=8;
	QVal=EvalIntExpression(Asc,Int64,&ValOK);
	if (ValOK) 
	 BEGIN
	  AdrVals[0]=(QVal >> 48) & 0xffff;
	  AdrVals[1]=(QVal >> 32) & 0xffff;
	  AdrVals[2]=(QVal >> 16) & 0xffff;
	  AdrVals[3]=(QVal      ) & 0xffff;
	 END
        break;
#endif
       case 4:
	AdrCnt=4;
	DVal=EvalFloatExpression(Asc,Float32,&ValOK);
	if (ValOK) 
	 BEGIN
          Double_2_ieee4(DVal,(Byte *) SwapField,BigEndian);
          if (BigEndian) DWSwap((Byte *) SwapField,4);
	  AdrVals[0]=SwapField[1];
	  AdrVals[1]=SwapField[0];
	 END
        break;
       case 5:
	AdrCnt=8;
	DVal=EvalFloatExpression(Asc,Float64,&ValOK);
	if (ValOK) 
	 BEGIN
          Double_2_ieee8(DVal,(Byte *) SwapField,BigEndian);
          if (BigEndian) QWSwap((Byte *) SwapField,8);
	  AdrVals[0]=SwapField[3];
	  AdrVals[1]=SwapField[2];
	  AdrVals[2]=SwapField[1];
	  AdrVals[3]=SwapField[0];
	 END
        break;
       case 6:
	AdrCnt=12;
	DVal=EvalFloatExpression(Asc,Float64,&ValOK);
	if (ValOK) 
	 BEGIN
          Double_2_ieee10(DVal,(Byte *) SwapField,False);
	  if (BigEndian) WSwap((Byte *) SwapField,10);
	  AdrVals[0]=SwapField[4];
	  AdrVals[1]=0;
	  AdrVals[2]=SwapField[3];
	  AdrVals[3]=SwapField[2];
	  AdrVals[4]=SwapField[1];
	  AdrVals[5]=SwapField[0];
	 END
        break;
       case 7:
	AdrCnt=12;
	DVal=EvalFloatExpression(Asc,Float64,&ValOK);
	if (ValOK) 
	 BEGIN
	  ConvertDec(DVal,SwapField);
	  AdrVals[0]=SwapField[5];
	  AdrVals[1]=SwapField[4];
	  AdrVals[2]=SwapField[3];
	  AdrVals[3]=SwapField[2];
	  AdrVals[4]=SwapField[1];
	  AdrVals[5]=SwapField[0];
	 END
        break;
      END
     ChkAdr(Erl); return;
    END

   /* CPU-Register direkt: */

   if (CodeReg(Asc,&AdrMode)) 
    BEGIN
     AdrCnt=0; AdrNum=(AdrMode >> 3)+1; ChkAdr(Erl); return;
    END

   /* Gleitkommaregister direkt: */

   if (strncasecmp(Asc,"FP",2)==0) 
    BEGIN
     if ((strlen(Asc)==3) AND (ValReg(Asc[2]))) 
      BEGIN
       AdrMode=Asc[2]-'0'; AdrCnt=0; AdrNum=12; ChkAdr(Erl); return;
      END;
     if (strcasecmp(Asc,"FPCR")==0) 
      BEGIN
       AdrMode=4; AdrNum=13; ChkAdr(Erl); return;
      END
     if (strcasecmp(Asc,"FPSR")==0) 
      BEGIN
       AdrMode=2; AdrNum=13; ChkAdr(Erl); return;
      END
     if (strcasecmp(Asc,"FPIAR")==0) 
      BEGIN
       AdrMode=1; AdrNum=13; ChkAdr(Erl); return;
      END
    END

   /* Adressregister indirekt mit Predekrement: */

   if ((l==5) AND (*Asc=='-') AND (Asc[1]=='(') AND (Asc[4]==')'))
    BEGIN
     strcpy(CReg,Asc+2); CReg[2]='\0';
     if (CodeReg(CReg,&rerg)) 
      if (rerg>7) 
       BEGIN
        AdrMode=rerg+24; AdrCnt=0; AdrNum=5; ChkAdr(Erl); return;
       END
    END

   /* Adressregister indirekt mit Postinkrement */

   if ((l==5) AND (*Asc=='(') AND (Asc[3]==')') AND (Asc[4]=='+')) 
    BEGIN
     strcpy(CReg,Asc+1); CReg[2]='\0';
     if (CodeReg(CReg,&rerg)) 
      if (rerg>7) 
       BEGIN
        AdrMode=rerg+16; AdrCnt=0; AdrNum=4; ChkAdr(Erl); return;
       END
    END

   /* Unterscheidung direkt<->indirekt: */

   lklamm=0; rklamm=0; lastrklamm=0; doklamm=True;
   for (p=Asc; *p!='\0'; p++)
    BEGIN
     if (*p=='[') doklamm=False;
     if (*p==']') doklamm=True;
     if (doklamm) 
      if (*p=='(') lklamm++;
      else if (*p==')') 
       BEGIN
	rklamm++; lastrklamm=p-Asc;
       END
    END

   if ((lklamm==1) AND (rklamm==1) AND (lastrklamm==strlen(Asc)-1)) 
    BEGIN

     /* aeusseres Displacement abspalten, Klammern loeschen: */

     p=strchr(Asc,'('); *p='\0'; strmaxcpy(OutDisp,Asc,255); strcpy(Asc,p+1);
     if ((strlen(OutDisp)>2) AND (OutDisp[strlen(OutDisp)-2]=='.')) 
      BEGIN
       switch (toupper(OutDisp[strlen(OutDisp)-1]))
        BEGIN
         case 'B': OutDispLen=0; break;
         case 'W': OutDispLen=1; break;
         case 'L': OutDispLen=2; break;
         default:
	  WrError(1130); return;
        END
       OutDisp[strlen(OutDisp)-2]='\0';
      END
     else OutDispLen=-1;
     Asc[strlen(Asc)-1]='\0';

     /* in Komponenten zerteilen: */

     CompCnt=0;
     do
      BEGIN
       doklamm=True;
       p=Asc;
       do
        BEGIN
         if (*p=='[') doklamm=False;
         else if (*p==']') doklamm=True;
         p++;
        END
       while (((NOT doklamm) OR (*p!=',')) AND (*p!='\0'));
       if (*p=='\0')
        BEGIN
         strcpy(AdrComps[CompCnt].Name,Asc); *Asc='\0';
        END
       else
        BEGIN
         *p='\0'; strcpy(AdrComps[CompCnt].Name,Asc); strcpy(Asc,p+1);
        END
       if (NOT ClassComp(AdrComps+CompCnt)) 
	BEGIN
	 WrError(1350); return;
	END
       if ((CompCnt==1) AND (AdrComps[CompCnt].Art==AReg)) 
	BEGIN
	 AdrComps[CompCnt].Art=Index; 
         AdrComps[CompCnt].INummer=AdrComps[CompCnt].ANummer+8; 
         AdrComps[CompCnt].Long=False; 
         AdrComps[CompCnt].Scale=0;
	END
       if ((AdrComps[CompCnt].Art==Disp) OR ((AdrComps[CompCnt].Art!=Index) AND (CompCnt!=0))) 
	BEGIN
	 WrError(1350); return;
	END
       CompCnt++;
      END
     while (*Asc!='\0');
     if ((CompCnt>2) OR ((AdrComps[0].Art==Index) AND (CompCnt!=1))) 
      BEGIN
       WrError(1350); return;
      END

     /* 1. Variante (An....), d(An....) */

     if (AdrComps[0].Art==AReg) 
      BEGIN

       /* 1.1. Variante (An), d(An) */

       if (CompCnt==1) 
	BEGIN

         /* 1.1.1. Variante (An) */

	 if ((*OutDisp=='\0') AND ((Madri & Erl)!=0)) 
	  BEGIN
	   AdrMode=0x10+AdrComps[0].ANummer; AdrNum=3; AdrCnt=0;
	   ChkAdr(Erl); return;
	  END

         /* 1.1.2. Variante d(An) */

	 else
	  BEGIN
	   if ((OutDispLen < 0) OR (OutDispLen >= 2))
            HVal = EvalIntExpression(OutDisp, SInt32, &ValOK);
           else
            HVal = EvalIntExpression(OutDisp, SInt16, &ValOK);
	   if (NOT ValOK) 
	    BEGIN
	     WrError(1350); return;
	    END
	   if ((ValOK) AND (HVal==0) AND ((Madri & Erl)!=0) AND (OutDispLen==-1)) 
	    BEGIN
             AdrMode=0x10+AdrComps[0].ANummer; AdrNum=3; AdrCnt=0;
	     ChkAdr(Erl); return;
	    END
	   if (OutDispLen == -1)
            OutDispLen = (IsDisp16(HVal)) ? 1 : 2;
	   switch (OutDispLen)
            BEGIN
	     case 1:                   /* d16(An) */
	      AdrMode=0x28+AdrComps[0].ANummer; AdrNum=6;
	      AdrCnt=2; AdrVals[0]=HVal&0xffff;
	      ChkAdr(Erl); return;
	     case 2:                   /* d32(An) */
	      AdrMode=0x30+AdrComps[0].ANummer; AdrNum=7;
	      AdrCnt=6; AdrVals[0]=0x0170;
	      AdrVals[1]=(HVal >> 16) & 0xffff; AdrVals[2]=HVal & 0xffff;
	      ACheckCPU(CPU68332); ChkAdr(Erl); return;
	    END
	  END
	END

       /* 1.2. Variante d(An,Xi) */

       else
	BEGIN
         AdrVals[0]=(AdrComps[1].INummer << 12)+(Ord(AdrComps[1].Long) << 11)+(AdrComps[1].Scale << 9);
	 AdrMode=0x30+AdrComps[0].ANummer;
         switch (OutDispLen)
          BEGIN
           case 0:
            HVal = EvalIntExpression(OutDisp, SInt8, &ValOK);
            break;
           case 1:
            HVal = EvalIntExpression(OutDisp, SInt16, &ValOK);
            break;
           default:
            HVal = EvalIntExpression(OutDisp, SInt32, &ValOK);
          END
         if (ValOK)
          BEGIN
           if (OutDispLen == -1)
            BEGIN
             if (IsDisp8(HVal)) OutDispLen = 0;
             else if (IsDisp16(HVal)) OutDispLen = 1;
             else OutDispLen = 2;
            END
 	   switch (OutDispLen)
            BEGIN
 	     case 0:
 	      AdrNum=7; AdrCnt=2; AdrVals[0]+=(HVal & 0xff);
 	      if (AdrComps[1].Scale!=0) ACheckCPU(CPUCOLD);
              ChkAdr(Erl); return;
 	     case 1:
 	      AdrNum=7; AdrCnt=4;
 	      AdrVals[0]+=0x120; AdrVals[1]=HVal & 0xffff;
 	      ACheckCPU(CPU68332);
 	      ChkAdr(Erl); return;
 	     case 2:
 	      AdrNum=7; AdrCnt=6; AdrVals[0]+=0x130;
 	      AdrVals[1]=HVal >> 16; AdrVals[2]=HVal & 0xffff;
 	      ACheckCPU(CPU68332);
  	      ChkAdr(Erl); return;
 	    END
          END
	END
      END

     /* 2. Variante d(PC....) */

     else if (AdrComps[0].Art==PC) 
      BEGIN

       /* 2.1. Variante d(PC) */

       if (CompCnt==1) 
	BEGIN
	 HVal=EvalIntExpression(OutDisp,Int32,&ValOK)-(EProgCounter()+RelPos);
	 if (NOT ValOK) 
	  BEGIN
	   WrError(1350); return;
	  END
         if (OutDispLen < 0)
           OutDispLen = (IsDisp16(HVal)) ? 1 : 2;
	 switch (OutDispLen)
          BEGIN
	   case 1:
	    AdrMode=0x3a;
	    if (NOT IsDisp16(HVal)) 
	     BEGIN
	      WrError(1330); return;
	     END
	    AdrNum=8; AdrCnt=2; AdrVals[0]=HVal & 0xffff;
	    ChkAdr(Erl); return;
	   case 2:
	    AdrMode=0x3b;
	    AdrNum=9; AdrCnt=6; AdrVals[0]=0x170;
	    AdrVals[1]=HVal >> 16; AdrVals[2]=HVal & 0xffff;
	    ACheckCPU(CPU68332); ChkAdr(Erl); return;
	  END
	END

       /* 2.2. Variante d(PC,Xi) */

       else
	BEGIN
         AdrVals[0]=(AdrComps[1].INummer << 12)+(Ord(AdrComps[1].Long) << 11)+(AdrComps[1].Scale << 9);
	 HVal=EvalIntExpression(OutDisp,Int32,&ValOK)-(EProgCounter()+RelPos);
	 if (NOT ValOK) 
	  BEGIN
	   WrError(1350); return;
	  END;
         if (OutDispLen < 0)
          BEGIN
           if (IsDisp8(HVal)) OutDispLen = 0;
           else if (IsDisp16(HVal)) OutDispLen = 1;
           else OutDispLen = 2;
          END
	 AdrMode=0x3b;
	 switch (OutDispLen)
          BEGIN
	   case 0:
	    if (NOT IsDisp8(HVal)) 
	     BEGIN
	      WrError(1330); return;
	     END
	    AdrVals[0]+=(HVal & 0xff); AdrCnt=2; AdrNum=9;
	    if (AdrComps[1].Scale!=0) ACheckCPU(CPUCOLD);
	    ChkAdr(Erl); return;
	   case 1:
	    if (NOT IsDisp16(HVal)) 
	     BEGIN
	      WrError(1330); return;
	     END
	    AdrVals[0]+=0x120; AdrCnt=4; AdrNum=9;
	    AdrVals[1]=HVal & 0xffff;
	    ACheckCPU(CPU68332);
	    ChkAdr(Erl); return;
	   case 2:
	    AdrVals[0]=AdrVals[0]+0x120; AdrCnt=6; AdrNum=9;
	    AdrVals[1]=HVal >> 16; AdrVals[2]=HVal & 0xffff;
	    ACheckCPU(CPU68332);
	    ChkAdr(Erl); return;
	  END
	END
      END

     /* 3. Variante (Xi), d(Xi) */

     else if (AdrComps[0].Art==Index) 
      BEGIN
       AdrVals[0]=(AdrComps[0].INummer << 12)+(Ord(AdrComps[0].Long) << 11)+(AdrComps[0].Scale << 9)+0x180;
       AdrMode=0x30;
       if (*OutDisp=='\0') 
	BEGIN
	 AdrVals[0]=AdrVals[0]+0x0010; AdrCnt=2;
	 AdrNum=7; ACheckCPU(CPU68332); ChkAdr(Erl); return;
	END
       else
        BEGIN
         if (OutDispLen != 1)
          HVal = EvalIntExpression(OutDisp,SInt32,&ValOK);
         else
          HVal = EvalIntExpression(OutDisp,SInt16,&ValOK);
         if (ValOK)
          BEGIN
           if (OutDispLen == -1)
            BEGIN
             if (IsDisp16(HVal)) OutDispLen = 1;
             else OutDispLen = 2;
            END
           switch (OutDispLen)
            BEGIN
             case 0:
             case 1:
 	      AdrVals[0]=AdrVals[0]+0x0020; AdrVals[1]=HVal & 0xffff;
	      AdrNum=7; AdrCnt=4; ACheckCPU(CPU68332);
	      ChkAdr(Erl); return;
             case 2:
	      AdrVals[0]=AdrVals[0]+0x0030; AdrNum=7; AdrCnt=6;
	      AdrVals[1]=HVal >> 16; AdrVals[2]=HVal & 0xffff;
	      ACheckCPU(CPU68332);
	      ChkAdr(Erl); return;
            END
          END
        END
      END

     /* 4. Variante indirekt: */

     else if (AdrComps[0].Art==indir) 
      BEGIN

       /* erst ab 68020 erlaubt */

       if (MomCPU<CPU68020) 
        BEGIN
         WrError(1505); return;
        END

       /* Unterscheidung Vor- <---> Nachindizierung: */

       if (CompCnt==2) 
	BEGIN
	 PreInd=False;
	 AdrComps[2]=AdrComps[1];
	END
       else
	BEGIN
	 PreInd=True;
	 AdrComps[2].Art=None;
	END

       /* indirektes Argument herauskopieren: */

       strcpy(Asc,AdrComps[0].Name+1);
       Asc[strlen(Asc)-1]='\0';

       /* Felder loeschen: */

       for (i=0; i<2; AdrComps[i++].Art=None);

       /* indirekten Ausdruck auseinanderfieseln: */

       do
        BEGIN

 	 /* abschneiden & klassifizieren: */

	 p=strchr(Asc,',');
	 if (p==Nil)
          BEGIN
           strcpy(OneComp.Name,Asc); *Asc='\0';
          END
         else
          BEGIN
           *p='\0'; strcpy(OneComp.Name,Asc); strcpy(Asc,p+1);
          END
	 if (NOT ClassComp(&OneComp)) 
	  BEGIN
	   WrError(1350); return;
	  END

	/* passend einsortieren: */

	 if ((AdrComps[1].Art!=None) AND (OneComp.Art==AReg)) 
	  BEGIN
	   OneComp.Art=Index; OneComp.INummer=OneComp.ANummer+8; 
           OneComp.Long=False; OneComp.Scale=0;
	  END
	 switch (OneComp.Art)
          BEGIN
	   case Disp  : i=0; break;
	   case AReg  :
           case PC    : i=1; break;
	   case Index : i=2; break;
           default    : i=(-1);
	  END
	 if (AdrComps[i].Art!=None) 
	  BEGIN
	   WrError(1350); return;
	  END
	 else AdrComps[i]=OneComp;
        END
       while (*Asc!='\0');

       /* Vor-oder Nachindizierung? */

       AdrVals[0]=0x100+(Ord(PreInd) << 2);

       /* Indexregister eintragen */

       if (AdrComps[2].Art==None) AdrVals[0]+=0x40;
       else AdrVals[0]+=(AdrComps[2].INummer << 12)+(Ord(AdrComps[2].Long) << 11)+(AdrComps[2].Scale << 9);

       /* 4.1 Variante d([...PC...]...) */

       if (AdrComps[1].Art==PC) 
	BEGIN
	 if (AdrComps[0].Art==None) HVal=0;
	 else HVal=EvalIntExpression(AdrComps[0].Name,Int32,&ValOK);
	 HVal-=EProgCounter()+RelPos;
	 if (NOT ValOK) return;
	 AdrMode=0x3b;
	 switch (AdrComps[0].Size)
          BEGIN
	   case 1:
	    if (NOT IsDisp16(HVal)) 
	     BEGIN
	      WrError(1330); return;
	     END
	    AdrVals[1]=HVal & 0xffff; AdrVals[0]+=0x20; AdrNum=7; AdrCnt=4;
	    break;
	   case 2:
	    AdrVals[1]=HVal >> 16; AdrVals[2]=HVal & 0xffff;
	    AdrVals[0]+=0x30; AdrNum=7; AdrCnt=6;
            break;
	  END
	END

       /* 4.2 Variante d([...An...]...) */

       else
	BEGIN
         if (AdrComps[1].Art==None)
	  BEGIN
	   AdrMode=0x30; AdrVals[0]+=0x80;
	  END
	 else AdrMode=0x30+AdrComps[1].ANummer;

	 if (AdrComps[0].Art==None) 
	  BEGIN
	   AdrNum=7; AdrCnt=2; AdrVals[0]+=0x10;
	  END
	 else switch (AdrComps[0].Size)
          BEGIN
	   case 1:
	    HVal16=EvalIntExpression(AdrComps[0].Name,Int16,&ValOK);
	    if (NOT ValOK) return;
	    AdrNum=7; AdrVals[1]=HVal16; AdrCnt=4; AdrVals[0]+=0x20;
	    break;
	   case 2:
	    HVal=EvalIntExpression(AdrComps[0].Name,Int32,&ValOK);
	    if (NOT ValOK) return;
	    AdrNum=7; AdrCnt=6; AdrVals[0]+=0x30;
	    AdrVals[1]=HVal >> 16; AdrVals[2]=HVal & 0xffff;
	    break;
	  END
	END

       /* aeusseres Displacement: */

       if (OutDispLen == 1)
        HVal = EvalIntExpression(OutDisp, SInt16, &ValOK);
       else
        HVal = EvalIntExpression(OutDisp, SInt32, &ValOK);
       if (NOT ValOK)
        BEGIN
         AdrNum=0; AdrCnt=0; return;
        END;
       if (OutDispLen == -1)
        BEGIN
         if (IsDisp16(HVal)) OutDispLen = 1;
         else OutDispLen = 2;
        END
       if (*OutDisp=='\0')
	BEGIN
	 AdrVals[0]++; ChkAdr(Erl); return;
	END
       else switch (OutDispLen)
        BEGIN
         case 0:
         case 1:
	  AdrVals[AdrCnt >> 1]=HVal & 0xffff; AdrCnt+=2; AdrVals[0]+=2;
	  break;
         case 2:
	  AdrVals[(AdrCnt >> 1)  ]=HVal >> 16;
	  AdrVals[(AdrCnt >> 1)+1]=HVal & 0xffff;
	  AdrCnt+=4; AdrVals[0]+=3;
	  break;
        END

       ChkAdr(Erl); return;

      END

    END

   /* absolut: */

   else
    BEGIN
     AdrCnt=0;
     if (strcasecmp(Asc+strlen(Asc)-2,".W")==0) 
      BEGIN
       AdrCnt=2; Asc[strlen(Asc)-2]='\0';
      END
     else if (strcasecmp(Asc+strlen(Asc)-2,".L")==0) 
      BEGIN
       AdrCnt=4; Asc[strlen(Asc)-2]='\0';
      END

     FirstPassUnknown=False;
     HVal=EvalIntExpression(Asc,Int32,&ValOK);
     if ((NOT FirstPassUnknown) AND (OpSize>0)) ChkEven(HVal);
     HVal16=HVal;

     if (ValOK) 
      BEGIN
       if (AdrCnt==0) AdrCnt=(IsShortAdr(HVal))?2:4; 
       AdrNum=10;

       if (AdrCnt==2) 
	BEGIN
	 if (NOT IsShortAdr(HVal)) 
	  BEGIN
	   WrError(1340); AdrNum=0;
	  END
	 else
	  BEGIN
	   AdrMode=0x38; AdrVals[0]=HVal16;
	  END
	END
       else
	BEGIN
	 AdrMode=0x39; AdrVals[0]=HVal >> 16; AdrVals[1]=HVal & 0xffff;
	END
      END
    END

   ChkAdr(Erl);
END

        static Byte OneReg(char *Asc)
BEGIN
   if (strlen(Asc)!=2) return 16;
   if ((toupper(*Asc)!='A') AND (toupper(*Asc)!='D')) return 16;
   if (NOT ValReg(Asc[1])) return 16;
   return Asc[1]-'0'+((toupper(*Asc)=='D')?0:8);
END

        static Boolean DecodeRegList(char *Asc_o, Word *Erg)
BEGIN
   static Word Masks[16]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};
   Byte h,h2,z;
   char *p;
   String Asc,s;

   *Erg=0; strmaxcpy(Asc,Asc_o,255);
   do
    BEGIN
     p=strchr(Asc,'/');
     if (p==Nil)
      BEGIN
       strcpy(s,Asc); *Asc='\0';
      END
     else
      BEGIN
       *p='\0'; strcpy(s,Asc); strcpy(Asc,p+1);
      END
     if (*Asc=='/') strcpy(Asc,Asc+1);
     p=strchr(s,'-');
     if (p==Nil) 
      BEGIN
       if ((h=OneReg(s))==16) return False;
       *Erg|=Masks[h];
      END
     else
      BEGIN
       *p='\0';
       if ((h=OneReg(s))==16) return False;
       if ((h2=OneReg(p+1))==16) return False;
       for (z=h; z<=h2; *Erg|=Masks[z++]);
      END
    END    
   while (*Asc!='\0');
   return True;
END

/*-------------------------------------------------------------------------*/
/* Dekodierroutinen: Integer-Einheit */

/* 0=MOVE 1=MOVEA */

	static void DecodeMOVE(Word Index)
BEGIN
   int z;

   if (ArgCnt!=2) WrError(1110);
   else if (strcasecmp(ArgStr[1],"USP")==0) 
    BEGIN
     if ((*AttrPart!='\0') AND (OpSize!=2)) WrError(1130);
     else if (MomCPU==CPUCOLD) WrError(1500);
     else
      BEGIN
       DecodeAdr(ArgStr[2],Madr);
       if (AdrNum!=0) 
        BEGIN
         CodeLen=2; WAsmCode[0]=0x4e68 | (AdrMode & 7); CheckSup();
        END
      END
    END
   else if (strcasecmp(ArgStr[2],"USP")==0) 
    BEGIN
     if ((*AttrPart!='\0') AND (OpSize!=2)) WrError(1130);
     else if (MomCPU==CPUCOLD) WrError(1500);
     else
      BEGIN
       DecodeAdr(ArgStr[1],Madr);
       if (AdrNum!=0) 
        BEGIN
         CodeLen=2; WAsmCode[0]=0x4e60 | (AdrMode & 7); CheckSup();
        END
      END
    END
   else if (strcasecmp(ArgStr[1],"SR")==0) 
    BEGIN
     if (OpSize!=1) WrError(1130);
     else
      BEGIN
       if (MomCPU==CPUCOLD) DecodeAdr(ArgStr[2],Mdata);
       else DecodeAdr(ArgStr[2],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
       if (AdrNum!=0) 
        BEGIN
         CodeLen=2+AdrCnt; WAsmCode[0]=0x40c0 | AdrMode;
         CopyAdrVals(WAsmCode+1);
         if (MomCPU>=CPU68010) CheckSup();
        END
      END
    END
   else if (strcasecmp(ArgStr[1],"CCR")==0) 
    BEGIN
     if ((*AttrPart!='\0') AND (OpSize>1)) WrError(1130);
     else
      BEGIN
       OpSize=0;
       if (MomCPU==CPUCOLD) DecodeAdr(ArgStr[2],Mdata);
       else DecodeAdr(ArgStr[2],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
       if (AdrNum!=0) 
        BEGIN
         CodeLen=2+AdrCnt; WAsmCode[0]=0x42c0 | AdrMode;
         CopyAdrVals(WAsmCode+1); CheckCPU(CPU68010);
        END
      END
    END
   else if (strcasecmp(ArgStr[2],"SR")==0) 
    BEGIN
     if (OpSize!=1) WrError(1130);
     else
      BEGIN
       if (MomCPU==CPUCOLD) DecodeAdr(ArgStr[1],Mdata+Mimm);
       else DecodeAdr(ArgStr[1],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm);
       if (AdrNum!=0) 
        BEGIN
         CodeLen=2+AdrCnt; WAsmCode[0]=0x46c0 | AdrMode;
         CopyAdrVals(WAsmCode+1); CheckSup();
        END
      END
    END
   else if (strcasecmp(ArgStr[2],"CCR")==0) 
    BEGIN
     if ((*AttrPart!='\0') AND (OpSize>1)) WrError(1130);
     else
      BEGIN
       OpSize=0;
       if (MomCPU==CPUCOLD) DecodeAdr(ArgStr[1],Mdata+Mimm);
       else DecodeAdr(ArgStr[1],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm);
       if (AdrNum!=0) 
        BEGIN
         CodeLen=2+AdrCnt; WAsmCode[0]=0x44c0 | AdrMode;
         CopyAdrVals(WAsmCode+1);
        END
      END
    END
   else
    BEGIN
     if (OpSize>2) WrError(1130);
     else
      BEGIN
       DecodeAdr(ArgStr[1],Mdata+Madr+Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm);
       if (AdrNum!=0) 
        BEGIN
         z=AdrCnt; CodeLen=2+z; CopyAdrVals(WAsmCode+1);
         if (OpSize==0) WAsmCode[0]=0x1000;
         else if (OpSize==1) WAsmCode[0]=0x3000;
         else WAsmCode[0]=0x2000;
         WAsmCode[0]|=AdrMode;
         DecodeAdr(ArgStr[2],Mdata+Madr+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
         if (AdrMode!=0) 
          if ((MomCPU==CPUCOLD) AND (z>0) AND (AdrCnt>0)) WrError(1350);
          else
           BEGIN
            AdrMode=((AdrMode & 7) << 3) | (AdrMode >> 3);
            WAsmCode[0]|=AdrMode << 6;
            CopyAdrVals(WAsmCode+(CodeLen >> 1));
            CodeLen+=AdrCnt;
           END
        END
      END
    END
END

	static void DecodeLEA(Word Index)
BEGIN
   if ((*AttrPart!='\0') AND (OpSize!=2)) WrError(1130);
   else if (ArgCnt!=2) WrError(1110);
   else
    BEGIN
     DecodeAdr(ArgStr[2],Madr);
     if (AdrNum!=0) 
      BEGIN
       OpSize=0;
       WAsmCode[0]=0x41c0 | ((AdrMode & 7) << 9);
       DecodeAdr(ArgStr[1],Madri+Mdadri+Maix+Mpc+Mpcidx+Mabs);
       if (AdrNum!=0) 
        BEGIN
         WAsmCode[0]|=AdrMode; CodeLen=2+AdrCnt;
         CopyAdrVals(WAsmCode+1);
        END
      END
    END
END

/* 0=ASR 1=ASL 2=LSR 3=LSL 4=ROXR 5=ROXL 6=ROR 7=ROL */

	static void DecodeShift(Word Index)
BEGIN
   Boolean ValOK;
   Byte HVal8;
   Word LFlag=(Index>>2), Op=Index&3;

   if (ArgCnt==1) 
    BEGIN
     strcpy(ArgStr[2],ArgStr[1]); strcpy(ArgStr[1],"#1");
     ArgCnt=2;
    END
   if (ArgCnt!=2) WrError(1110);
   else if ((*OpPart=='R') AND (MomCPU==CPUCOLD)) WrError(1500);
   else
    BEGIN
     DecodeAdr(ArgStr[2],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
     if (AdrNum==1) 
      BEGIN
       if (CheckColdSize())
        BEGIN
         WAsmCode[0]=0xe000 | AdrMode | (Op << 3) | (OpSize << 6) | (LFlag << 8);
         OpSize=1;
         DecodeAdr(ArgStr[1],Mdata+Mimm);
         if ((AdrNum==1) OR ((AdrNum==11) AND (Lo(AdrVals[0])>=1) AND (Lo(AdrVals[0])<=8)))
          BEGIN
           CodeLen=2;
           WAsmCode[0] |= (AdrNum==1) ? 0x20|(AdrMode<<9) : ((AdrVals[0] & 7) << 9);
          END
         else WrError(1380);
        END
      END
     else if (AdrNum!=0) 
      if (MomCPU==CPUCOLD) WrError(1350);
      else
       BEGIN
        if (OpSize!=1) WrError(1130);
        else
         BEGIN
          WAsmCode[0]=0xe0c0 | AdrMode | (Op << 9) | (LFlag << 8);
          CopyAdrVals(WAsmCode+1);
          if (*ArgStr[1]=='#') strcpy(ArgStr[1],ArgStr[1]+1);
          HVal8=EvalIntExpression(ArgStr[1],Int8,&ValOK);
          if ((ValOK) AND (HVal8==1)) CodeLen=2+AdrCnt;
          else WrError(1390);
         END
       END
    END
END

/* ADDQ=0 SUBQ=1 */

	static void DecodeADDQSUBQ(Word Index)
BEGIN
   Byte HVal8;
   Boolean ValOK;

   if (CheckColdSize())
    if (ArgCnt!=2) WrError(1110);
    else
     BEGIN
      DecodeAdr(ArgStr[2],Mdata+Madr+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
      if (AdrNum!=0) 
       BEGIN
        WAsmCode[0]=0x5000 | AdrMode | (OpSize << 6) | (Index << 8);
        CopyAdrVals(WAsmCode+1);
        if (*ArgStr[1]=='#') strcpy(ArgStr[1],ArgStr[1]+1);
        FirstPassUnknown=False;
        HVal8=EvalIntExpression(ArgStr[1],UInt4,&ValOK);
        if (FirstPassUnknown) HVal8=1;
        if ((ValOK) AND (HVal8>=1) AND (HVal8<=8)) 
         BEGIN
          CodeLen=2+AdrCnt;
          WAsmCode[0]|=(((Word) HVal8 & 7) << 9);
         END
        else WrError(1390);
       END
     END
END

/* 0=ADDX 1=SUBX */

	static void DecodeADDXSUBX(Word Index)
BEGIN
   if (CheckColdSize())
    if (ArgCnt!=2) WrError(1110);
    else
     BEGIN
      DecodeAdr(ArgStr[1],Mdata+Mpre);
      if (AdrNum!=0)
       BEGIN
        WAsmCode[0]=0x9100 | (OpSize << 6) OR (AdrMode & 7) | (Index << 14);
        if (AdrNum==5) WAsmCode[0]|=8;
        DecodeAdr(ArgStr[2],Masks[AdrNum]);
        if (AdrNum!=0) 
         BEGIN
          CodeLen=2;
          WAsmCode[0]|= (AdrMode & 7) << 9;
         END
       END
     END
END

	static void DecodeCMPM(Word Index)
BEGIN
   if (OpSize>2) WrError(1130);
   else if (ArgCnt!=2) WrError(1110);
   else if (MomCPU==CPUCOLD) WrError(1500);
   else
    BEGIN
     DecodeAdr(ArgStr[1],Mpost);
     if (AdrNum==4) 
      BEGIN
       WAsmCode[0]=0xb108 | (OpSize << 6) | (AdrMode & 7);
       DecodeAdr(ArgStr[2],Mpost);
       if (AdrNum==4) 
        BEGIN
         WAsmCode[0]|=(AdrMode & 7) << 9;
         CodeLen=2;
        END
      END
    END
END

/* 0=SUB 1=CMP 2=ADD +4=..I +8=..A */

	static void DecodeADDSUBCMP(Word Index)
BEGIN
   Word Op=Index&3;

   if (CheckColdSize())
    if (ArgCnt!=2) WrError(1110);
    else
     BEGIN
      DecodeAdr(ArgStr[2],Mdata+Madr+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
      if (AdrNum==2)        /* ADDA ? */
       if (OpSize==0) WrError(1130);
      else
       BEGIN
        WAsmCode[0]=0x90c0 | ((AdrMode & 7) << 9) | (Op << 13);
        if (OpSize==2) WAsmCode[0]|=0x100;
        DecodeAdr(ArgStr[1],Mdata+Madr+Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm);
        if (AdrNum!=0) 
         BEGIN
          WAsmCode[0]|=AdrMode; CodeLen=2+AdrCnt;
          CopyAdrVals(WAsmCode+1);
         END
       END
      else if (AdrNum==1)      /* ADD <EA>,Dn ? */
       BEGIN
        WAsmCode[0]=0x9000 | (OpSize << 6) | (AdrMode << 9) | (Op << 13);
        DecodeAdr(ArgStr[1],Mdata+Madr+Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm);
        if (AdrNum!=0) 
         BEGIN
          CodeLen=2+AdrCnt; CopyAdrVals(WAsmCode+1);
          WAsmCode[0]|=AdrMode;
         END
       END
      else
       BEGIN
        DecodeAdr(ArgStr[1],Mdata+Mimm);
        if (AdrNum==11)        /* ADDI ? */
         BEGIN
          if (Op==1) Op=8;
          WAsmCode[0]=0x400 | (OpSize << 6) | (Op << 8);
          CodeLen=2+AdrCnt;
          CopyAdrVals(WAsmCode+1);
          if (MomCPU==CPUCOLD) DecodeAdr(ArgStr[2],Mdata);
          else DecodeAdr(ArgStr[2],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
          if (AdrNum!=0) 
           BEGIN
            WAsmCode[0]|=AdrMode;
            CopyAdrVals(WAsmCode+(CodeLen >> 1));
            CodeLen+=AdrCnt;
           END
          else CodeLen=0;
         END
        else if (AdrNum!=0)    /* ADD Dn,<EA> ? */
         BEGIN
          if (Op==1) WrError(1420);
          else
           BEGIN
            WAsmCode[0]=0x9100 | (OpSize << 6) | (AdrMode << 9) | (Op << 13);
            DecodeAdr(ArgStr[2],Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
            if (AdrNum!=0) 
             BEGIN
              CodeLen=2+AdrCnt; CopyAdrVals(WAsmCode+1);
              WAsmCode[0]|=AdrMode;
             END
           END
         END
       END
     END
END

/* 0=OR 1=AND +4=..I */

	static void DecodeANDOR(Word Index)
BEGIN
   Word Op=Index&3;

   if (ArgCnt!=2) WrError(1110);
   else if (CheckColdSize())
    BEGIN
     if ((strcasecmp(ArgStr[2],"CCR")!=0) AND (strcasecmp(ArgStr[2],"SR")!=0)) 
      DecodeAdr(ArgStr[2],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
     if (strcasecmp(ArgStr[2],"CCR")==0)     /* AND #...,CCR */
      BEGIN
       if ((*AttrPart!='\0') AND (OpSize!=0)) WrError(1130);
       else if ((MomCPU==CPU68008) OR (MomCPU==CPUCOLD)) WrError(1500);
       else
        BEGIN
         WAsmCode[0] = 0x003c | (Op << 9);
         OpSize=0; DecodeAdr(ArgStr[1],Mimm);
         if (AdrNum!=0) 
          BEGIN
           CodeLen=4; WAsmCode[1]=AdrVals[0];
          END
        END
      END
     else if (strcasecmp(ArgStr[2],"SR")==0) /* AND #...,SR */
      BEGIN
       if ((*AttrPart!='\0') AND (OpSize!=1)) WrError(1130);
       else if ((MomCPU==CPU68008) OR (MomCPU==CPUCOLD)) WrError(1500);
       else
        BEGIN
         WAsmCode[0] = 0x007c | (Op << 9);
         OpSize=1; DecodeAdr(ArgStr[1],Mimm);
         if (AdrNum!=0) 
          BEGIN
           CodeLen=4; WAsmCode[1]=AdrVals[0]; CheckSup();
          END
        END
      END
     else if (AdrNum==1)                 /* AND <EA>,Dn */
      BEGIN
       WAsmCode[0]=0x8000 | (OpSize << 6) | (AdrMode << 9) | (Op << 14);
       DecodeAdr(ArgStr[1],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm);
       if (AdrNum!=0) 
        BEGIN
         WAsmCode[0]|=AdrMode;
         CodeLen=2+AdrCnt; CopyAdrVals(WAsmCode+1);
        END
      END
     else if (AdrNum!=0)                 /* AND ...,<EA> */
      BEGIN
       DecodeAdr(ArgStr[1],Mdata+Mimm);
       if (AdrNum==11)                   /* AND #..,<EA> */
        BEGIN
         WAsmCode[0]=(OpSize << 6) | (Op << 9);
         CodeLen=2+AdrCnt;
         CopyAdrVals(WAsmCode+1);
         DecodeAdr(ArgStr[2],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
         if (AdrNum!=0)
          BEGIN
           WAsmCode[0]|=AdrMode;
           CopyAdrVals(WAsmCode+(CodeLen >> 1));
           CodeLen+=AdrCnt;
          END
         else CodeLen=0;
        END
       else if (AdrNum!=0)               /* AND Dn,<EA> ? */
        BEGIN
         WAsmCode[0]=0x8100 | (OpSize << 6) | (AdrMode << 9) | (Op << 14);
         DecodeAdr(ArgStr[2],Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
         if (AdrNum!=0)
          BEGIN
           CodeLen=2+AdrCnt; CopyAdrVals(WAsmCode+1);
           WAsmCode[0]|=AdrMode;
          END
        END
      END
    END
END

/* 0=EOR 4=EORI */

	static void DecodeEOR(Word Index)
BEGIN
   if (ArgCnt!=2) WrError(1110);
   else if (strcasecmp(ArgStr[2],"CCR")==0) 
    BEGIN
     if ((*AttrPart!='\0') AND (OpSize!=0)) WrError(1130);
     else if (MomCPU==CPUCOLD) WrError(1500);
     else
      BEGIN
       WAsmCode[0]=0xa3c; OpSize=0;
       DecodeAdr(ArgStr[1],Mimm);
       if (AdrNum!=0)
        BEGIN
         CodeLen=4; WAsmCode[1]=AdrVals[0];
        END
      END
    END
   else if (strcasecmp(ArgStr[2],"SR")==0) 
    BEGIN
     if (OpSize!=1) WrError(1130);
     else if (MomCPU==CPUCOLD) WrError(1500);
     else
      BEGIN
       WAsmCode[0]=0xa7c;
       DecodeAdr(ArgStr[1],Mimm);
       if (AdrNum!=0) 
        BEGIN
         CodeLen=4; WAsmCode[1]=AdrVals[0]; CheckSup();
         CheckCPU(CPU68000);
        END
      END
    END
   else if (CheckColdSize())
    BEGIN
     DecodeAdr(ArgStr[1],Mdata+Mimm);
     if (AdrNum==1) 
      BEGIN
       WAsmCode[0]=0xb100 | (AdrMode << 9) | (OpSize << 6);
       DecodeAdr(ArgStr[2],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
       if (AdrNum!=0)
        BEGIN
         CodeLen=2+AdrCnt; CopyAdrVals(WAsmCode+1);
         WAsmCode[0]|=AdrMode;
        END
      END
     else if (AdrNum==11) 
      BEGIN
       WAsmCode[0]=0x0a00 | (OpSize << 6);
       CopyAdrVals(WAsmCode+1); CodeLen=2+AdrCnt;
       if (MomCPU==CPUCOLD) DecodeAdr(ArgStr[2],Mdata);
       else DecodeAdr(ArgStr[2],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
       if (AdrNum!=0)
        BEGIN
         CopyAdrVals(WAsmCode+(CodeLen >> 1));
         CodeLen+=AdrCnt;
         WAsmCode[0]|=AdrMode;
        END
       else CodeLen=0;
      END
    END
END

	static void DecodePEA(Word Index)
BEGIN
   if ((*AttrPart!='\0') AND (OpSize!=2)) WrError(1100);
   else if (ArgCnt!=1) WrError(1110);
   else
    BEGIN
     OpSize=0;
     DecodeAdr(ArgStr[1],Madri+Mdadri+Maix+Mpc+Mpcidx+Mabs);
     if (AdrNum!=0) 
      BEGIN
       CodeLen=2+AdrCnt;
       WAsmCode[0]=0x4840 | AdrMode;
       CopyAdrVals(WAsmCode+1);
      END
    END
END

/* 0=CLR 1=TST */

	static void DecodeCLRTST(Word Index)
BEGIN
   Word w1;

   if (OpSize>2) WrError(1130);
   else if (ArgCnt!=1) WrError(1110);
   else
    BEGIN
     w1=Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mabs;
     if ((Index==1) AND (OpSize>0) AND (MomCPU>=CPU68332))
      w1+=Madr+Mpc+Mpcidx+Mimm;
     DecodeAdr(ArgStr[1],w1);
     if (AdrNum!=0) 
      BEGIN
       CodeLen=2+AdrCnt;
       WAsmCode[0]=0x4200 | (Index << 11) | (OpSize << 6) | AdrMode;
       CopyAdrVals(WAsmCode+1);
      END
    END
END

/* 0=JSR 1=JMP */

	static void DecodeJSRJMP(Word Index)
BEGIN
   if (*AttrPart!='\0') WrError(1130);
   else if (ArgCnt!=1) WrError(1110);
   else
    BEGIN
     DecodeAdr(ArgStr[1],Madri+Mdadri+Maix+Mpc+Mpcidx+Mabs);
     if (AdrNum!=0) 
      BEGIN
       CodeLen=2+AdrCnt;
       WAsmCode[0]=0x4e80 | (Index << 6) | AdrMode;
       CopyAdrVals(WAsmCode+1);
      END
    END
END

/* 0=TAS 1=NBCD */

	static void DecodeNBCDTAS(Word Index)
BEGIN
   if ((*AttrPart!='\0') AND (OpSize!=0)) WrError(1130);
   else if (ArgCnt!=1) WrError(1110);
   else if (MomCPU==CPUCOLD) WrError(1500);
   else
    BEGIN
     OpSize=0;
     DecodeAdr(ArgStr[1],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
     if (AdrNum!=0) 
      BEGIN
       CodeLen=2+AdrCnt;
       WAsmCode[0]=(Index==1) ? 0x4800 : 0x4ac0;
       WAsmCode[0]|=AdrMode;
       CopyAdrVals(WAsmCode+1);
      END
    END
END

/* 0=NEGX 2=NEG 3=NOT */

	static void DecodeNEGNOT(Word Index)
BEGIN
   if (ArgCnt!=1) WrError(1110);
   else if (CheckColdSize())
    BEGIN
     if (MomCPU==CPUCOLD) DecodeAdr(ArgStr[1],Mdata);
     else DecodeAdr(ArgStr[1],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
     if (AdrNum!=0)
      BEGIN
       CodeLen=2+AdrCnt;
       WAsmCode[0]=0x4000 | (Index << 9) | (OpSize << 6) | AdrMode;
       CopyAdrVals(WAsmCode+1);
      END
    END
END

	static void DecodeSWAP(Word Index)
BEGIN
   if ((*AttrPart!='\0') AND (OpSize!=2)) WrError(1130);
   else if (ArgCnt!=1) WrError(1110);
   else
    BEGIN
     DecodeAdr(ArgStr[1],Mdata);
     if (AdrNum!=0) 
      BEGIN
       CodeLen=2; WAsmCode[0]=0x4840 | AdrMode;
      END
    END
END

	static void DecodeUNLK(Word Index) 
BEGIN
   if (*AttrPart!='\0') WrError(1130);
   else if (ArgCnt!=1) WrError(1110);
   else
    BEGIN
     DecodeAdr(ArgStr[1],Madr);
     if (AdrNum!=0) 
      BEGIN
       CodeLen=2; WAsmCode[0]=0x4e58 | AdrMode;
      END
    END
END

	static void DecodeEXT(Word Index) 
BEGIN
   if (ArgCnt!=1) WrError(1110);
   else if ((OpSize==0) OR (OpSize>2)) WrError(1130);
   else
    BEGIN
     DecodeAdr(ArgStr[1],Mdata);
     if (AdrNum==1) 
      BEGIN
       WAsmCode[0]=0x4880 | AdrMode | (((Word)OpSize-1) << 6);
       CodeLen=2;
      END
    END
END

	static void DecodeWDDATA(Word Index)
BEGIN
   if (ArgCnt!=1) WrError(1110);
   else if (MomCPU!=CPUCOLD) WrError(1500);
   else if (OpSize>2) WrError(1130);
   else
    BEGIN
     DecodeAdr(ArgStr[1],Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
     if (AdrNum!=0)
      BEGIN
       WAsmCode[0]=0xf400+(OpSize << 6)+AdrMode;
       CopyAdrVals(WAsmCode+1); CodeLen=2+AdrCnt;
       CheckSup();
      END
    END
END

	static void DecodeWDEBUG(Word Index)
BEGIN
   if (ArgCnt!=1) WrError(1110);
   else if (MomCPU!=CPUCOLD) WrError(1500);
   else if (CheckColdSize())
    BEGIN
     DecodeAdr(ArgStr[1],Madri+Mdadri);
     if (AdrNum!=0)
      BEGIN
       WAsmCode[0]=0xfbc0+AdrMode; WAsmCode[1]=0x0003;
       CopyAdrVals(WAsmCode+2); CodeLen=4+AdrCnt;
       CheckSup();
      END
    END
END

	static void DecodeFixed(Word Index)
BEGIN
   FixedOrder *FixedZ=FixedOrders+Index;

   if (*AttrPart!='\0') WrError(1100);
   else if (ArgCnt!=0) WrError(1110);
   else if ((FixedZ->CPUMask &(1 << (MomCPU-CPU68008)))==0) WrError(1500);
   else
    BEGIN
     CodeLen=2; WAsmCode[0]=FixedZ->Code;
     if (FixedZ->MustSup) CheckSup();
    END
END

	static void DecodeMOVEM(Word Index)
BEGIN
   int z;

   if (ArgCnt!=2) WrError(1110);
   else if ((OpSize<1) OR (OpSize>2)) WrError(1130);
   else if ((MomCPU==CPUCOLD) AND (OpSize==1)) WrError(1130);
   else
    BEGIN
     if (DecodeRegList(ArgStr[2],WAsmCode+1))
      BEGIN
       if (MomCPU==CPUCOLD) DecodeAdr(ArgStr[1],Madri+Mdadri);
       else DecodeAdr(ArgStr[1],Madri+Mpost+Mdadri+Maix+Mpc+Mpcidx+Mabs);
       if (AdrNum!=0)
        BEGIN
         WAsmCode[0]=0x4c80 | AdrMode | ((OpSize-1) << 6);
         CodeLen=4+AdrCnt; CopyAdrVals(WAsmCode+2);
        END
      END
     else if (DecodeRegList(ArgStr[1],WAsmCode+1)) 
      BEGIN
       if (MomCPU==CPUCOLD) DecodeAdr(ArgStr[2],Madri+Mdadri);
       else DecodeAdr(ArgStr[2],Madri+Mpre+Mdadri+Maix+Mabs);
       if (AdrNum!=0) 
        BEGIN
         WAsmCode[0]=0x4880 | AdrMode | ((OpSize-1) << 6);
         CodeLen=4+AdrCnt; CopyAdrVals(WAsmCode+2);
         if (AdrNum==5) 
          BEGIN
           WAsmCode[9]=WAsmCode[1]; WAsmCode[1]=0;
           for (z=0; z<16; z++)
            BEGIN
             WAsmCode[1]=WAsmCode[1] << 1;
             if ((WAsmCode[9]&1)==1) WAsmCode[1]++;
             WAsmCode[9]=WAsmCode[9] >> 1;
            END
          END
        END
      END
     else WrError(1410);
    END
END

	static void DecodeMOVEQ(Word Index)
BEGIN
    if (ArgCnt!=2) WrError(1110);
    else if ((*AttrPart!='\0') AND (OpSize!=2)) WrError(1130);
    else
     BEGIN
      DecodeAdr(ArgStr[2],Mdata);
      if (AdrNum!=0)
       BEGIN
        WAsmCode[0]=0x7000 | (AdrMode << 9);
        OpSize=0;
        DecodeAdr(ArgStr[1],Mimm);
        if (AdrNum!=0) 
         BEGIN
          CodeLen=2; WAsmCode[0]|=AdrVals[0];
         END
       END
     END
END

	static void DecodeSTOP(Word Index)
BEGIN
   Word HVal;
   Boolean ValOK;

   if (*AttrPart!='\0') WrError(1100);
   else if (ArgCnt!=1) WrError(1110);
   else if (*ArgStr[1]!='#') WrError(1120);
   else
    BEGIN
     HVal=EvalIntExpression(ArgStr[1]+1,Int16,&ValOK);
     if (ValOK) 
      BEGIN
       CodeLen=4; WAsmCode[0]=0x4e72; WAsmCode[1]=HVal; CheckSup();
      END
    END
END

	static void DecodeLPSTOP(Word Index) 
BEGIN
   Word HVal;
   Boolean ValOK;

   if (*AttrPart!='\0') WrError(1100);
   else if (ArgCnt!=1) WrError(1110);
   else if (*ArgStr[1]!='#') WrError(1120);
   else
    BEGIN
     HVal=EvalIntExpression(ArgStr[1]+1,Int16,&ValOK);
     if (ValOK) 
      BEGIN
       CodeLen=6;
       WAsmCode[0]=0xf800;
       WAsmCode[1]=0x01c0;
       WAsmCode[2]=HVal;
       CheckSup(); Check32();
      END
    END
END

        static void DecodeTRAP(Word Index) 
BEGIN
   Byte HVal8;
   Boolean ValOK;

   if (*AttrPart!='\0') WrError(1100);
   else if (ArgCnt!=1) WrError(1110);
   else if (*ArgStr[1]!='#') WrError(1120);
   else
    BEGIN
     HVal8=EvalIntExpression(ArgStr[1]+1,Int4,&ValOK);
     if (ValOK) 
      BEGIN
       CodeLen=2; WAsmCode[0]=0x4e40+(HVal8 & 15);
      END
    END
END

        static void DecodeBKPT(Word Index) 
BEGIN
   Byte HVal8;
   Boolean ValOK;

   if (*AttrPart!='\0') WrError(1100);
   else if (ArgCnt!=1) WrError(1110);
   else if (MomCPU==CPUCOLD) WrError(1500);
   else if (*ArgStr[1]!='#') WrError(1120);
   else
    BEGIN
     HVal8=EvalIntExpression(ArgStr[1]+1,UInt3,&ValOK);
     if (ValOK) 
      BEGIN
       CodeLen=2; WAsmCode[0]=0x4848+(HVal8 & 7);
       CheckCPU(CPU68010);
      END
    END
END

        static void DecodeRTD(Word Index) 
BEGIN
   Word HVal;
   Boolean ValOK;

   if (*AttrPart!='\0') WrError(1100);
   else if (ArgCnt!=1) WrError(1110);
   else if (MomCPU==CPUCOLD) WrError(1500);
   else if (*ArgStr[1]!='#') WrError(1120);
   else
    BEGIN
     HVal=EvalIntExpression(ArgStr[1]+1,Int16,&ValOK);
     if (ValOK) 
      BEGIN
       CodeLen=4; WAsmCode[0]=0x4e74; WAsmCode[1]=HVal;
       CheckCPU(CPU68010);
      END
    END
END

	static void DecodeEXG(Word Index) 
BEGIN
   if ((*AttrPart!='\0') AND (OpSize!=2)) WrError(1130);
   else if (ArgCnt!=2) WrError(1110);
   else if (MomCPU==CPUCOLD) WrError(1500);
   else
    BEGIN
     DecodeAdr(ArgStr[1],Mdata+Madr);
     if (AdrNum==1)
      BEGIN
       WAsmCode[0]=0xc100 | (AdrMode << 9);
       DecodeAdr(ArgStr[2],Mdata+Madr);
       if (AdrNum==1)
        BEGIN
         WAsmCode[0]|=0x40 | AdrMode; CodeLen=2;
        END
       else if (AdrNum==2)
        BEGIN
         WAsmCode[0]|=0x88 | (AdrMode & 7); CodeLen=2;
        END
      END
     else if (AdrNum==2)
      BEGIN
       WAsmCode[0]=0xc100 | (AdrMode & 7);
       DecodeAdr(ArgStr[2],Mdata+Madr);
       if (AdrNum==1)
        BEGIN
         WAsmCode[0]|=0x88 OR (AdrMode << 9); CodeLen=2;
        END
       else
        BEGIN
         WAsmCode[0]|=0x48 | ((AdrMode & 7) << 9); CodeLen=2;
        END
      END
    END
END

	static void DecodeMOVE16(Word Index)
BEGIN
   Word z,z2,w1,w2;
   
   if (*AttrPart!='\0') WrError(1100);
   else if (ArgCnt!=2) WrError(1110);
   else
    BEGIN
     DecodeAdr(ArgStr[1],Mpost+Madri+Mabs);
     if (AdrNum!=0)
      BEGIN
       w1=AdrNum; z=AdrMode & 7;
       if ((w1==10) AND (AdrCnt==2))
        BEGIN
         AdrVals[1]=AdrVals[0];
         AdrVals[0]=0-(AdrVals[1] >> 15);
        END
       DecodeAdr(ArgStr[2],Mpost+Madri+Mabs);
       if (AdrNum!=0)
        BEGIN
         w2=AdrNum; z2=AdrMode & 7;
         if ((w2==10) AND (AdrCnt==2))
          BEGIN
           AdrVals[1]=AdrVals[0];
           AdrVals[0]=0-(AdrVals[1] >> 15);
          END
         if ((w1==4) AND (w2==4))
          BEGIN
           WAsmCode[0]=0xf620+z;
           WAsmCode[1]=0x8000+(z2 << 12);
           CodeLen=4;
          END
         else
          BEGIN
           WAsmCode[1]=AdrVals[0]; WAsmCode[2]=AdrVals[1];
           CodeLen=6;
           if ((w1==4) AND (w2==10)) WAsmCode[0]=0xf600+z;
           else if ((w1==10) AND (w2==4)) WAsmCode[0]=0xf608+z2;
           else if ((w1==3) AND (w2==10)) WAsmCode[0]=0xf610+z;
           else if ((w1==10) AND (w2==3)) WAsmCode[0]=0xf618+z2;
           else
            BEGIN
             WrError(1350); CodeLen=0;
            END
          END
         if (CodeLen>0) CheckCPU(CPU68040);
        END
      END
    END
END	

	static void DecodeCacheAll(Word Index)
BEGIN
   Word w1;
   
   if (*AttrPart!='\0') WrError(1100);
   else if (ArgCnt!=1) WrError(1110);
   else if (NOT CodeCache(ArgStr[1],&w1)) WrXError(1440,ArgStr[1]);
   else
    BEGIN
     WAsmCode[0]=0xf418+(w1 << 6)+(Index << 5);
     CodeLen=2;
     CheckCPU(CPU68040); CheckSup();
    END   
END	

	static void DecodeCache(Word Index)
BEGIN
   Word w1;

   if (*AttrPart!='\0') WrError(1100);
   else if (ArgCnt!=2) WrError(1110);
   else if (NOT CodeCache(ArgStr[1],&w1)) WrXError(1440,ArgStr[1]);
   else
    BEGIN
     DecodeAdr(ArgStr[2],Madri);
     if (AdrNum!=0)
      BEGIN
       WAsmCode[0]=0xf400+(w1 << 6)+(Index << 3)+(AdrMode & 7);
       CodeLen=2;
       CheckCPU(CPU68040); CheckSup();
      END
    END   
END	

	static void DecodeDIVL(Word Index) 
BEGIN
   Word w1,w2;

   if (*AttrPart=='\0') OpSize=2;
   if (ArgCnt!=2) WrError(1110);
   else if (OpSize!=2) WrError(1130);
   else if (NOT CodeRegPair(ArgStr[2],&w1,&w2)) WrXError(1760, ArgStr[2]);
   else
    BEGIN
     RelPos=4;
     WAsmCode[1]=w1|(w2 << 12)|(Index << 11);
     DecodeAdr(ArgStr[1],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm);
     if (AdrNum!=0)
      BEGIN
       WAsmCode[0]=0x4c40+AdrMode;
       CopyAdrVals(WAsmCode+2); CodeLen=4+AdrCnt;
       CheckCPU(CPU68332);
      END
    END
END

	static void DecodeASBCD(Word Index)
BEGIN
   if ((OpSize!=0) AND (*AttrPart!='\0')) WrError(1130);
   else if (ArgCnt!=2) WrError(1110);
   else if (MomCPU==CPUCOLD) WrError(1500);
   else
    BEGIN
     OpSize=0;
     DecodeAdr(ArgStr[1],Mdata+Mpre);
     if (AdrNum!=0)
      BEGIN
       WAsmCode[0]=0x8100 | (AdrMode & 7) | (Index << 14);
       if (AdrNum==5) WAsmCode[0]|=8;
       DecodeAdr(ArgStr[2],Masks[AdrNum]);
       if (AdrNum!=0)
        BEGIN
         CodeLen=2;
         WAsmCode[0]|=(AdrMode & 7) << 9;
        END
      END
    END
END

	static void DecodeCHK(Word Index) 
BEGIN
   if (OpSize!=1) WrError(1130);
   else if (ArgCnt!=2) WrError(1110);
   else if (MomCPU==CPUCOLD) WrError(1500);
   else
    BEGIN
     DecodeAdr(ArgStr[1],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm);
     if (AdrNum!=0)
      BEGIN
       WAsmCode[0]=0x4180 | AdrMode; CodeLen=2+AdrCnt;
       CopyAdrVals(WAsmCode+1);
       DecodeAdr(ArgStr[2],Mdata);
       if (AdrNum==1) WAsmCode[0]|=WAsmCode[0] | (AdrMode << 9);
       else CodeLen=0;
      END
    END
END

	static void DecodeLINK(Word Index) 
BEGIN
   if ((*AttrPart=='\0') AND (MomCPU==CPUCOLD)) OpSize=1;
   if ((OpSize<1) OR (OpSize>2)) WrError(1130);
   else if ((OpSize==2) AND (MomCPU<CPU68332)) WrError(1500);
   else if (ArgCnt!=2) WrError(1110);
   else
    BEGIN
     DecodeAdr(ArgStr[1],Madr);
     if (AdrNum!=0)
      BEGIN
       WAsmCode[0]=(OpSize==1) ? 0x4e50 : 0x4808;
       WAsmCode[0]+=AdrMode & 7;
       DecodeAdr(ArgStr[2],Mimm);
       if (AdrNum==11)
        BEGIN
         CodeLen=2+AdrCnt; memcpy(WAsmCode+1,AdrVals,AdrCnt);
        END
      END
    END
END

	static void DecodeMOVEP(Word Index) 
BEGIN
   if ((OpSize==0) OR (OpSize>2)) WrError(1130);
   else if (ArgCnt!=2) WrError(1110);
   else if (MomCPU==CPUCOLD) WrError(1500);
   else
    BEGIN
     DecodeAdr(ArgStr[1],Mdata+Mdadri);
     if (AdrNum==1)
      BEGIN
       WAsmCode[0]=0x188 | ((OpSize-1) << 6) | (AdrMode << 9);
       DecodeAdr(ArgStr[2],Mdadri);
       if (AdrNum==6)
        BEGIN
         WAsmCode[0]|=AdrMode & 7;
         CodeLen=4; WAsmCode[1]=AdrVals[0];
        END
      END
     else if (AdrNum==6)
      BEGIN
       WAsmCode[0]=0x108 | ((OpSize-1) << 6) | (AdrMode & 7);
       WAsmCode[1]=AdrVals[0];
       DecodeAdr(ArgStr[2],Mdata);
       if (AdrNum==1)
        BEGIN
         WAsmCode[0]|=(AdrMode & 7) << 9;
         CodeLen=4;
        END
      END
    END
END

	static void DecodeMOVEC(Word Index) 
BEGIN
   if ((*AttrPart!='\0') AND (OpSize!=2)) WrError(1130);
   else if (ArgCnt!=2) WrError(1110);
    BEGIN
     if (DecodeCtrlReg(ArgStr[1],WAsmCode+1)) 
      BEGIN
       DecodeAdr(ArgStr[2],Mdata+Madr);
       if (AdrNum!=0)
        BEGIN
         CodeLen=4; WAsmCode[0]=0x4e7a;
         WAsmCode[1]|=AdrMode << 12; CheckSup();
        END
      END
     else if (DecodeCtrlReg(ArgStr[2],WAsmCode+1)) 
      BEGIN
       DecodeAdr(ArgStr[1],Mdata+Madr);
       if (AdrNum!=0) 
        BEGIN
         CodeLen=4; WAsmCode[0]=0x4e7b;
         WAsmCode[1]|=AdrMode << 12; CheckSup();
        END
      END
     else WrError(1440);
    END
END

	static void DecodeMOVES(Word Index) 
BEGIN
   if (ArgCnt!=2) WrError(1110);
   else if (OpSize>2) WrError(1130);
   else if (MomCPU==CPUCOLD) WrError(1500);
   else
    BEGIN
     DecodeAdr(ArgStr[1],Mdata+Madr+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
     if ((AdrNum==1) OR (AdrNum==2)) 
      BEGIN
       WAsmCode[1]=0x800 | (AdrMode << 12);
       DecodeAdr(ArgStr[2],Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
       if (AdrNum!=0)
        BEGIN
         WAsmCode[0]=0xe00 | AdrMode | (OpSize << 6); CodeLen=4+AdrCnt;
         CopyAdrVals(WAsmCode+2); CheckSup();
         CheckCPU(CPU68010);
        END
      END
     else if (AdrNum!=0)
      BEGIN
       WAsmCode[0]=0xe00 | AdrMode | (OpSize << 6);
       CodeLen=4+AdrCnt; CopyAdrVals(WAsmCode+2);
       DecodeAdr(ArgStr[2],Mdata+Madr);
       if (AdrNum!=0)
        BEGIN
         WAsmCode[1]=AdrMode << 12;
         CheckSup();
         CheckCPU(CPU68010);
        END
       else CodeLen=0;
      END
    END
END

	static void DecodeCALLM(Word Index) 
BEGIN
   if (*AttrPart!='\0') WrError(1130);
   else if (ArgCnt!=2) WrError(1110);
   else
    BEGIN
     OpSize=0;
     DecodeAdr(ArgStr[1],Mimm);
     if (AdrNum!=0)
      BEGIN
       WAsmCode[1]=AdrVals[0]; RelPos=4;
       DecodeAdr(ArgStr[2],Madri+Mdadri+Maix+Mpc+Mpcidx+Mabs);
       if (AdrNum!=0)
        BEGIN
         WAsmCode[0]=0x06c0+AdrMode;
         CopyAdrVals(WAsmCode+2); CodeLen=4+AdrCnt;
         CheckCPU(CPU68020); Check020();
        END
      END
    END
END

	static void DecodeCAS(Word Index) 
BEGIN
   if (OpSize>2) WrError(1130);
   else if (ArgCnt!=3) WrError(1110);
   else
    BEGIN
     DecodeAdr(ArgStr[1],Mdata);
     if (AdrNum!=0)
      BEGIN
       WAsmCode[1]=AdrMode;
       DecodeAdr(ArgStr[2],Mdata);
       if (AdrNum!=0)
        BEGIN
         RelPos=4;
         WAsmCode[1]+=(((Word)AdrMode) << 6);
         DecodeAdr(ArgStr[3],Mdata+Madr+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
         if (AdrNum!=0)
          BEGIN
           WAsmCode[0]=0x08c0+AdrMode+(((Word)OpSize+1) << 9);
           CopyAdrVals(WAsmCode+2); CodeLen=4+AdrCnt;
           CheckCPU(CPU68020);
          END
        END
      END
    END
END

	static void DecodeCAS2(Word Index) 
BEGIN
   Word w1,w2;

   if ((OpSize!=1) AND (OpSize!=2)) WrError(1130);
   else if (ArgCnt!=3) WrError(1110);
   else if (NOT CodeRegPair(ArgStr[1],WAsmCode+1,WAsmCode+2)) WrXError(1760, ArgStr[1]);
   else if (NOT CodeRegPair(ArgStr[2],&w1,&w2)) WrXError(1760, ArgStr[2]);
   else
    BEGIN
     WAsmCode[1]+=(w1 << 6);
     WAsmCode[2]+=(w2 << 6);
     if (NOT CodeIndRegPair(ArgStr[3],&w1,&w2)) WrXError(1760, ArgStr[3]);
     else
      BEGIN
       WAsmCode[1]+=(w1 << 12);
       WAsmCode[2]+=(w2 << 12);
       WAsmCode[0]=0x0cfc+(((Word)OpSize-1) << 9);
       CodeLen=6;
       CheckCPU(CPU68020);
      END
    END
END

	static void DecodeCMPCHK2(Word Index)
BEGIN
   if (OpSize>2) WrError(1130);
   else if (ArgCnt!=2) WrError(1110);
   else
    BEGIN
     DecodeAdr(ArgStr[2],Mdata+Madr);
     if (AdrNum!=0)
      BEGIN
       RelPos=4;
       WAsmCode[1]=(((Word)AdrMode) << 12) | (Index << 11);
       DecodeAdr(ArgStr[1],Madri+Mdadri+Maix+Mpc+Mpcidx+Mabs);
       if (AdrNum!=0)
        BEGIN
         WAsmCode[0]=0x00c0+(((Word)OpSize) << 9)+AdrMode;
         CopyAdrVals(WAsmCode+2); CodeLen=4+AdrCnt;
         CheckCPU(CPU68332);
        END
      END
    END
END

	static void DecodeEXTB(Word Index)
BEGIN
   if ((OpSize!=2) AND (*AttrPart!='\0')) WrError(1130);
   else if (ArgCnt!=1) WrError(1110);
   else
    BEGIN
     DecodeAdr(ArgStr[1],Mdata);
     if (AdrNum!=0)
      BEGIN
       WAsmCode[0]=0x49c0+AdrMode; CodeLen=2;
       CheckCPU(CPU68332);
      END
    END
END

	static void DecodePACK(Word Index) 
BEGIN
   if (ArgCnt!=3) WrError(1110);
   else if (*AttrPart!='\0') WrError(1130);
   else
    BEGIN
     DecodeAdr(ArgStr[1],Mdata+Mpre);
     if (AdrNum!=0)
      BEGIN
       WAsmCode[0]=(0x8140+(Index<<6)) | (AdrMode & 7);
       if (AdrNum==5) WAsmCode[0]+=8;
       DecodeAdr(ArgStr[2],Masks[AdrNum]);
       if (AdrNum!=0)
        BEGIN
         WAsmCode[0]|=((AdrMode & 7) << 9);
         DecodeAdr(ArgStr[3],Mimm);
         if (AdrNum!=0)
          BEGIN
           WAsmCode[1]=AdrVals[0]; CodeLen=4;
           CheckCPU(CPU68020);
          END
        END
      END
    END
END

	static void DecodeRTM(Word Index) 
BEGIN
   if (*AttrPart!='\0') WrError(1130);
   else if (ArgCnt!=1) WrError(1110);
   else
    BEGIN
     DecodeAdr(ArgStr[1],Mdata+Madr);
     if (AdrNum!=0)
      BEGIN
       WAsmCode[0]=0x06c0+AdrMode; CodeLen=2;
       CheckCPU(CPU68020); Check020();
      END
    END
END

	static void DecodeTBL(Word Index)
BEGIN
   char *p;
   Word w2,Mode;

   if (ArgCnt!=2) WrError(1110);
   else if (OpSize>2) WrError(1130);
   else if (MomCPU<CPU68332) WrError(1500);
   else
    BEGIN
     DecodeAdr(ArgStr[2],Mdata);
     if (AdrNum!=0)
      BEGIN
       Mode=AdrMode;
       p=strchr(ArgStr[1],':');
       if (p==0)
        BEGIN
         DecodeAdr(ArgStr[1],Madri+Mdadri+Maix+Mabs+Mpc+Mpcidx);
         if (AdrNum!=0) 
          BEGIN
           WAsmCode[0]=0xf800+AdrMode;
           WAsmCode[1]=0x0100+(OpSize << 6)+(Mode << 12)+(Index << 10);
           memcpy(WAsmCode+2,AdrVals,AdrCnt);
           CodeLen=4+AdrCnt; Check32();
          END
        END
       else
        BEGIN
         strcpy(ArgStr[3],p+1); *p='\0';
         DecodeAdr(ArgStr[1],Mdata);
         if (AdrNum!=0)
          BEGIN
           w2=AdrMode;
           DecodeAdr(ArgStr[3],Mdata);
           if (AdrNum!=0)
            BEGIN
             WAsmCode[0]=0xf800+w2;
             WAsmCode[1]=0x0000+(OpSize << 6)+(Mode << 12)+AdrMode;
             if (OpPart[3]=='S') WAsmCode[1]+=0x0800;
             if (OpPart[strlen(OpPart)-1]=='N') WAsmCode[1]+=0x0400;
             CodeLen=4; Check32();
            END
          END
        END
      END
    END
END

/* 0=BTST 1=BCHG 2=BCLR 3=BSET */

	static void DecodeBits(Word Index)
BEGIN
   if (ArgCnt!=2) WrError(1110);
   else
    BEGIN
     if (*AttrPart=='\0') OpSize=0;
     if (Index!=0) DecodeAdr(ArgStr[2],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
     else DecodeAdr(ArgStr[2],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs);
     if (*AttrPart=='\0') OpSize=(AdrNum==1) ? 2 : 0;
     if (AdrNum!=0)
      BEGIN
       if (((AdrNum==1) AND (OpSize!=2)) OR ((AdrNum!=1) AND (OpSize!=0))) WrError(1130);
       else
        BEGIN
         WAsmCode[0]=AdrMode+(Index << 6);
         CodeLen=2+AdrCnt; CopyAdrVals(WAsmCode+1);
         OpSize=0;
         DecodeAdr(ArgStr[1],Mdata+Mimm);
         if (AdrNum==1) 
          BEGIN
           WAsmCode[0]|=0x100 | (AdrMode << 9);
          END
         else if (AdrNum==11) 
          BEGIN
           memmove(WAsmCode+2,WAsmCode+1,CodeLen-2); WAsmCode[1]=AdrVals[0];
           WAsmCode[0]|=0x800;
           CodeLen+=2;
           if ((AdrVals[0]>31)
           OR  (((WAsmCode[0] & 0x38)!=0) AND (AdrVals[0]>7))) 
            BEGIN
             CodeLen=0; WrError(1510);
            END
          END
         else CodeLen=0;
        END
      END
    END
END

/* 0=BFTST 1=BFCHG 2=BFCLR 3=BFSET */

        static void DecodeFBits(Word Index)
BEGIN
    if (ArgCnt!=1) WrError(1110);
    else if (*AttrPart!='\0') WrError(1130);
    else if (NOT SplitBitField(ArgStr[1],WAsmCode+1)) WrError(1750);
    else
     BEGIN
      RelPos=4;
      OpSize=0;
      if (Memo("BFTST")) DecodeAdr(ArgStr[1],Mdata+Madri+Mdadri+Maix+Mpc+Mpcidx+Mabs);
      else DecodeAdr(ArgStr[1],Mdata+Madri+Mdadri+Maix+Mabs);
      if (AdrNum!=0) 
       BEGIN
        WAsmCode[0]=0xe8c0 | AdrMode | (Index << 10);
        CopyAdrVals(WAsmCode+2); CodeLen=4+AdrCnt;
        CheckCPU(CPU68020);
       END
     END
END

/* 0=BFEXTU 1=BFEXTS 2=BFFFO */

	static void DecodeEBits(Word Index)
BEGIN
   if (ArgCnt!=2) WrError(1110);
   else if (*AttrPart!='\0') WrError(1130);
   else if (NOT SplitBitField(ArgStr[1],WAsmCode+1)) WrError(1750);
   else
    BEGIN
     RelPos=4;
     OpSize=0;
     DecodeAdr(ArgStr[1],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs);
     if (AdrNum!=0)
      BEGIN
       WAsmCode[0]=0xe9c0+AdrMode+(Index << 9); CopyAdrVals(WAsmCode+2);
       CodeLen=4+AdrCnt;
       DecodeAdr(ArgStr[2],Mdata);
       if (AdrNum!=0)
        BEGIN
         WAsmCode[1]|=AdrMode << 12;
         CheckCPU(CPU68020);
        END
       else CodeLen=0;
      END
    END
END

	static void DecodeBFINS(Word Index)
BEGIN
   if (ArgCnt!=2) WrError(1110);
   else if (*AttrPart!='\0') WrError(1130);
   else if (NOT SplitBitField(ArgStr[2],WAsmCode+1)) WrError(1750);
   else
    BEGIN
     OpSize=0;
     DecodeAdr(ArgStr[2],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
     if (AdrNum!=0)
      BEGIN
       WAsmCode[0]=0xefc0+AdrMode; CopyAdrVals(WAsmCode+2);
       CodeLen=4+AdrCnt;
       DecodeAdr(ArgStr[1],Mdata);
       if (AdrNum!=0)
        BEGIN
         WAsmCode[1]|=AdrMode << 12;
         CheckCPU(CPU68020);
        END
       else CodeLen=0;
      END
    END
END

static Word CondIndex;
	static void DecodeCondition(Word Index)
BEGIN
   CondIndex=Index;
END

/*-------------------------------------------------------------------------*/
/* Dekodierroutinen Gleitkommaeinheit */

	static void DecodeFPUOp(Word Index)
BEGIN
   FPUOp *Op=FPUOps+Index;

   if ((ArgCnt==1) AND (NOT Op->Dya))
    BEGIN
     strcpy(ArgStr[2],ArgStr[1]); ArgCnt=2;
    END
   if (*AttrPart=='\0') OpSize=6;
   if (OpSize==3) WrError(1130);
   else if (ArgCnt!=2) WrError(1110);
   else
    BEGIN
     DecodeAdr(ArgStr[2],Mfpn);
     if (AdrNum==12)
      BEGIN
       WAsmCode[0]=0xf200;
       WAsmCode[1]=Op->Code | (AdrMode << 7);
       RelPos=4;
       DecodeAdr(ArgStr[1],((OpSize<=2) OR (OpSize==4))?
                           Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm+Mfpn:
                           Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm+Mfpn);
       if (AdrNum==12)
        BEGIN
         WAsmCode[1]|=AdrMode << 10;
         if (OpSize==6) CodeLen=4; else WrError(1130);
         CheckCPU(Op->MinCPU);
        END
       else if (AdrNum!=0)
        BEGIN
         CodeLen=4+AdrCnt; CopyAdrVals(WAsmCode+2);
         WAsmCode[0]|=AdrMode;
         WAsmCode[1]|=0x4000 | (((Word)FSizeCodes[OpSize]) << 10);
         CheckCPU(Op->MinCPU);
        END
      END
    END
END

/*-------------------------------------------------------------------------*/
/* Dekodierroutinen Pseudoinstruktionen: */

        static void PutByte(Byte b)
BEGIN
   if (((CodeLen&1)==1) AND (NOT BigEndian))
    BEGIN
     BAsmCode[CodeLen]=BAsmCode[CodeLen-1];
     BAsmCode[CodeLen-1]=b;
    END
   else
    BEGIN
     BAsmCode[CodeLen]=b;
    END
   CodeLen++;
END

	static void DecodeSTR(Word Index)
BEGIN
   int l,z;

   if (ArgCnt!=1) WrError(1110);
   else if ((l=strlen(ArgStr[1]))<2) WrError(1135);
   else if (*ArgStr[1]!='\'') WrError(1135);
   else if (ArgStr[1][l-1]!='\'') WrError(1135);
   else
    BEGIN
     PutByte(l-2);
     for (z=1; z<l-1; z++)
      PutByte(CharTransTable[((usint) ArgStr[1][z])&0xff]);
     if ((Odd(CodeLen)) AND (DoPadding)) PutByte(0);
    END
END

/*-------------------------------------------------------------------------*/
/* Codetabellenverwaltung */

	static void AddFixed(char *NName, Word NCode, Boolean NSup, Word NMask)
BEGIN
   if (InstrZ>=FixedOrderCnt) exit(255);
   FixedOrders[InstrZ].Code=NCode;
   FixedOrders[InstrZ].MustSup=NSup;
   FixedOrders[InstrZ].CPUMask=NMask;
   AddInstTable(InstTable,NName,InstrZ++,DecodeFixed);
END

	static void AddCtReg(char *NName, Word NCode, CPUVar NFirst, CPUVar NLast)
BEGIN
   if (InstrZ>=CtRegCnt) exit(255);
   CtRegs[InstrZ].Name=NName;
   CtRegs[InstrZ].Code=NCode;
   CtRegs[InstrZ].FirstCPU=NFirst;
   CtRegs[InstrZ++].LastCPU=NLast;
END

	static void AddCond(char *NName, Byte NCode)
BEGIN
   if (InstrZ>=CondCnt) exit(255);
   AddInstTable(CInstTable,NName,NCode,DecodeCondition);
   CondNams[InstrZ]=NName;
   CondVals[InstrZ++]=NCode;
END

	static void AddFPUOp(char *NName, Byte NCode, Boolean NDya, CPUVar NMin)
BEGIN
   if (InstrZ >= FPUOpCnt) exit(255);
   FPUOps[InstrZ].Name = NName;
   FPUOps[InstrZ].Code = NCode;
   FPUOps[InstrZ].Dya = NDya;
   FPUOps[InstrZ].MinCPU = NMin; 
   AddInstTable(FInstTable, NName, InstrZ++, DecodeFPUOp);
END

	static void AddFPUCond(char *NName, Byte NCode)
BEGIN
   if (InstrZ>=FPUCondCnt) exit(255);
   FPUConds[InstrZ].Name=NName;
   FPUConds[InstrZ++].Code=NCode;
END

	static void AddPMMUCond(char *NName)
BEGIN
   if (InstrZ>=PMMUCondCnt) exit(255);
   PMMUConds[InstrZ++]=NName;
END

	static void AddPMMUReg(char *Name, Byte Size, Word Code)
BEGIN
   if (InstrZ>=PMMURegCnt) exit(255);
   PMMURegNames[InstrZ]=Name;
   PMMURegSizes[InstrZ]=Size;
   PMMURegCodes[InstrZ++]=Code;
END

	static void InitFields(void)
BEGIN
   InstTable=CreateInstTable(201);
   FInstTable=CreateInstTable(201);
   CInstTable=CreateInstTable(47);

   AddInstTable(InstTable,"MOVE"   ,0,DecodeMOVE);
   AddInstTable(InstTable,"MOVEA"  ,1,DecodeMOVE);
   AddInstTable(InstTable,"LEA"    ,0,DecodeLEA);
   AddInstTable(InstTable,"ASR"    ,0,DecodeShift);
   AddInstTable(InstTable,"ASL"    ,4,DecodeShift);
   AddInstTable(InstTable,"LSR"    ,1,DecodeShift);
   AddInstTable(InstTable,"LSL"    ,5,DecodeShift);
   AddInstTable(InstTable,"ROXR"   ,2,DecodeShift);
   AddInstTable(InstTable,"ROXL"   ,6,DecodeShift);
   AddInstTable(InstTable,"ROR"    ,3,DecodeShift);
   AddInstTable(InstTable,"ROL"    ,7,DecodeShift);
   AddInstTable(InstTable,"ADDQ"   ,0,DecodeADDQSUBQ);
   AddInstTable(InstTable,"SUBQ"   ,1,DecodeADDQSUBQ);
   AddInstTable(InstTable,"ADDX"   ,0,DecodeADDXSUBX);
   AddInstTable(InstTable,"SUBX"   ,1,DecodeADDXSUBX);
   AddInstTable(InstTable,"CMPM"   ,0,DecodeCMPM);
   AddInstTable(InstTable,"SUB"    ,0,DecodeADDSUBCMP);
   AddInstTable(InstTable,"CMP"    ,1,DecodeADDSUBCMP);
   AddInstTable(InstTable,"ADD"    ,2,DecodeADDSUBCMP);
   AddInstTable(InstTable,"SUBI"   ,4,DecodeADDSUBCMP);
   AddInstTable(InstTable,"CMPI"   ,5,DecodeADDSUBCMP);
   AddInstTable(InstTable,"ADDI"   ,6,DecodeADDSUBCMP);
   AddInstTable(InstTable,"SUBA"   ,8,DecodeADDSUBCMP);
   AddInstTable(InstTable,"CMPA"   ,9,DecodeADDSUBCMP);
   AddInstTable(InstTable,"ADDA"   ,10,DecodeADDSUBCMP);
   AddInstTable(InstTable,"AND"    ,1,DecodeANDOR);
   AddInstTable(InstTable,"OR"     ,0,DecodeANDOR);
   AddInstTable(InstTable,"ANDI"   ,5,DecodeANDOR);
   AddInstTable(InstTable,"ORI"    ,4,DecodeANDOR);
   AddInstTable(InstTable,"EOR"    ,0,DecodeEOR);
   AddInstTable(InstTable,"EORI"   ,4,DecodeEOR);
   AddInstTable(InstTable,"PEA"    ,0,DecodePEA);
   AddInstTable(InstTable,"CLR"    ,0,DecodeCLRTST);
   AddInstTable(InstTable,"TST"    ,1,DecodeCLRTST);
   AddInstTable(InstTable,"JSR"    ,0,DecodeJSRJMP);
   AddInstTable(InstTable,"JMP"    ,1,DecodeJSRJMP);
   AddInstTable(InstTable,"TAS"    ,0,DecodeNBCDTAS);
   AddInstTable(InstTable,"NBCD"   ,1,DecodeNBCDTAS);
   AddInstTable(InstTable,"NEGX"   ,0,DecodeNEGNOT);
   AddInstTable(InstTable,"NEG"    ,2,DecodeNEGNOT);
   AddInstTable(InstTable,"NOT"    ,3,DecodeNEGNOT);
   AddInstTable(InstTable,"SWAP"   ,0,DecodeSWAP);
   AddInstTable(InstTable,"UNLK"   ,0,DecodeUNLK);
   AddInstTable(InstTable,"EXT"    ,0,DecodeEXT);
   AddInstTable(InstTable,"WDDATA" ,0,DecodeWDDATA);
   AddInstTable(InstTable,"WDEBUG" ,0,DecodeWDEBUG);
   AddInstTable(InstTable,"MOVEM"  ,0,DecodeMOVEM); 
   AddInstTable(InstTable,"MOVEQ"  ,0,DecodeMOVEQ);
   AddInstTable(InstTable,"STOP"   ,0,DecodeSTOP);
   AddInstTable(InstTable,"LPSTOP" ,0,DecodeLPSTOP);
   AddInstTable(InstTable,"TRAP"   ,0,DecodeTRAP);
   AddInstTable(InstTable,"BKPT"   ,0,DecodeBKPT);
   AddInstTable(InstTable,"RTD"    ,0,DecodeRTD);
   AddInstTable(InstTable,"EXG"    ,0,DecodeEXG);
   AddInstTable(InstTable,"MOVE16" ,0,DecodeMOVE16);
   AddInstTable(InstTable,"DIVUL"  ,0,DecodeDIVL);
   AddInstTable(InstTable,"DIVSL"  ,1,DecodeDIVL);
   AddInstTable(InstTable,"ABCD"   ,1,DecodeASBCD);
   AddInstTable(InstTable,"SBCD"   ,0,DecodeASBCD);
   AddInstTable(InstTable,"CHK"    ,0,DecodeCHK);
   AddInstTable(InstTable,"LINK"   ,0,DecodeLINK);
   AddInstTable(InstTable,"MOVEP"  ,0,DecodeMOVEP);
   AddInstTable(InstTable,"MOVEC"  ,0,DecodeMOVEC);
   AddInstTable(InstTable,"MOVES"  ,0,DecodeMOVES);
   AddInstTable(InstTable,"CALLM"  ,0,DecodeCALLM);
   AddInstTable(InstTable,"CAS"    ,0,DecodeCAS);
   AddInstTable(InstTable,"CAS2"   ,0,DecodeCAS2);
   AddInstTable(InstTable,"CMP2"   ,0,DecodeCMPCHK2);
   AddInstTable(InstTable,"CHK2"   ,1,DecodeCMPCHK2);
   AddInstTable(InstTable,"EXTB"   ,0,DecodeEXTB);
   AddInstTable(InstTable,"PACK"   ,0,DecodePACK);
   AddInstTable(InstTable,"UNPK"   ,1,DecodePACK);
   AddInstTable(InstTable,"RTM"    ,0,DecodeRTM);
   AddInstTable(InstTable,"TBLU"   ,0,DecodeTBL);
   AddInstTable(InstTable,"TBLUN"  ,1,DecodeTBL);
   AddInstTable(InstTable,"TBLS"   ,2,DecodeTBL);
   AddInstTable(InstTable,"TBLSN"  ,3,DecodeTBL);
   AddInstTable(InstTable,"BTST"   ,0,DecodeBits);
   AddInstTable(InstTable,"BSET"   ,3,DecodeBits);
   AddInstTable(InstTable,"BCLR"   ,2,DecodeBits);
   AddInstTable(InstTable,"BCHG"   ,1,DecodeBits);
   AddInstTable(InstTable,"BFTST"  ,0,DecodeFBits);
   AddInstTable(InstTable,"BFSET"  ,3,DecodeFBits);
   AddInstTable(InstTable,"BFCLR"  ,2,DecodeFBits);
   AddInstTable(InstTable,"BFCHG"  ,1,DecodeFBits);
   AddInstTable(InstTable,"BFEXTU" ,0,DecodeEBits);
   AddInstTable(InstTable,"BFEXTS" ,1,DecodeEBits);
   AddInstTable(InstTable,"BFFFO"  ,2,DecodeEBits);
   AddInstTable(InstTable,"BFINS"  ,0,DecodeBFINS);
   AddInstTable(InstTable,"CINVA"  ,0,DecodeCacheAll);
   AddInstTable(InstTable,"CPUSHA" ,1,DecodeCacheAll);
   AddInstTable(InstTable,"CINVL"  ,1,DecodeCache);
   AddInstTable(InstTable,"CPUSHL" ,5,DecodeCache);
   AddInstTable(InstTable,"CINVP"  ,2,DecodeCache);
   AddInstTable(InstTable,"CPUSHP" ,6,DecodeCache);
   AddInstTable(InstTable,"STR"    ,0,DecodeSTR);

   FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); InstrZ=0;
   AddFixed("NOP"    ,0x4e71,False,0x07ff);
   AddFixed("RESET"  ,0x4e70,False,0x07ef);
   AddFixed("ILLEGAL",0x4afc,False,0x07ff);
   AddFixed("TRAPV"  ,0x4e76,False,0x07ef);
   AddFixed("RTE"    ,0x4e73,True ,0x07ff);
   AddFixed("RTR"    ,0x4e77,False,0x07ef);
   AddFixed("RTS"    ,0x4e75,False,0x07ff);
   AddFixed("BGND"   ,0x4afa,False,0x00e0);
   AddFixed("HALT"   ,0x4ac8,True ,0x0010);
   AddFixed("PULSE"  ,0x4acc,True ,0x0010);

   CtRegs=(CtReg *) malloc(sizeof(CtReg)*CtRegCnt); InstrZ=0;
   AddCtReg("SFC"  ,0x000, CPU68010, CPU68040);
   AddCtReg("DFC"  ,0x001, CPU68010, CPU68040);
   AddCtReg("CACR" ,0x002, CPU68020, CPU68040);
   AddCtReg("TC"   ,0x003, CPU68040, CPU68040);
   AddCtReg("ITT0" ,0x004, CPU68040, CPU68040);
   AddCtReg("ITT1" ,0x005, CPU68040, CPU68040);
   AddCtReg("DTT0" ,0x006, CPU68040, CPU68040);
   AddCtReg("DTT1" ,0x007, CPU68040, CPU68040);
   AddCtReg("USP"  ,0x800, CPU68010, CPU68040);
   AddCtReg("VBR"  ,0x801, CPU68010, CPU68040);
   AddCtReg("CAAR" ,0x802, CPU68020, CPU68030);
   AddCtReg("MSP"  ,0x803, CPU68020, CPU68040);
   AddCtReg("ISP"  ,0x804, CPU68020, CPU68040);
   AddCtReg("MMUSR",0x805, CPU68040, CPU68040);
   AddCtReg("URP"  ,0x806, CPU68040, CPU68040);
   AddCtReg("SRP"  ,0x807, CPU68040, CPU68040);
   AddCtReg("IACR0",0x004, CPU68040, CPU68040);
   AddCtReg("IACR1",0x005, CPU68040, CPU68040);
   AddCtReg("DACR0",0x006, CPU68040, CPU68040);
   AddCtReg("DACR1",0x007, CPU68040, CPU68040);
   AddCtReg("TCR"  ,0x003, CPUCOLD , CPUCOLD );
   AddCtReg("ACR2" ,0x004, CPUCOLD , CPUCOLD );
   AddCtReg("ACR3" ,0x005, CPUCOLD , CPUCOLD );
   AddCtReg("ACR0" ,0x006, CPUCOLD , CPUCOLD );
   AddCtReg("ACR1" ,0x007, CPUCOLD , CPUCOLD );
   AddCtReg("ROMBAR",0xc00,CPUCOLD , CPUCOLD );
   AddCtReg("RAMBAR0",0xc04,CPUCOLD, CPUCOLD );
   AddCtReg("RAMBAR1",0xc05,CPUCOLD, CPUCOLD );
   AddCtReg("MBAR" ,0xc0f, CPUCOLD , CPUCOLD );

   CondNams=(char **) malloc(sizeof(char *)*CondCnt); 
   CondVals=(Byte *) malloc(sizeof(Byte)*CondCnt); InstrZ=0;
   AddCond("T" , 0);  AddCond("F" , 1);  AddCond("HI", 2);  AddCond("LS", 3);
   AddCond("CC", 4);  AddCond("CS", 5);  AddCond("NE", 6);  AddCond("EQ", 7);
   AddCond("VC", 8);  AddCond("VS", 9);  AddCond("PL",10);  AddCond("MI",11);
   AddCond("GE",12);  AddCond("LT",13);  AddCond("GT",14);  AddCond("LE",15);
   AddCond("HS", 4);  AddCond("LO", 5);  AddCond("RA", 0);  AddCond("SR", 1);

   FPUOps=(FPUOp *) malloc(sizeof(FPUOp)*FPUOpCnt); InstrZ=0;
   AddFPUOp("INT"   ,0x01, False, CPU68000);  AddFPUOp("SINH"  ,0x02, False, CPU68000);
   AddFPUOp("INTRZ" ,0x03, False, CPU68000);  AddFPUOp("SQRT"  ,0x04, False, CPU68000);
   AddFPUOp("LOGNP1",0x06, False, CPU68000);  AddFPUOp("ETOXM1",0x08, False, CPU68000);
   AddFPUOp("TANH"  ,0x09, False, CPU68000);  AddFPUOp("ATAN"  ,0x0a, False, CPU68000);
   AddFPUOp("ASIN"  ,0x0c, False, CPU68000);  AddFPUOp("ATANH" ,0x0d, False, CPU68000);
   AddFPUOp("SIN"   ,0x0e, False, CPU68000);  AddFPUOp("TAN"   ,0x0f, False, CPU68000);
   AddFPUOp("ETOX"  ,0x10, False, CPU68000);  AddFPUOp("TWOTOX",0x11, False, CPU68000);
   AddFPUOp("TENTOX",0x12, False, CPU68000);  AddFPUOp("LOGN"  ,0x14, False, CPU68000);
   AddFPUOp("LOG10" ,0x15, False, CPU68000);  AddFPUOp("LOG2"  ,0x16, False, CPU68000);
   AddFPUOp("ABS"   ,0x18, False, CPU68000);  AddFPUOp("COSH"  ,0x19, False, CPU68000);
   AddFPUOp("NEG"   ,0x1a, False, CPU68000);  AddFPUOp("ACOS"  ,0x1c, False, CPU68000);
   AddFPUOp("COS"   ,0x1d, False, CPU68000);  AddFPUOp("GETEXP",0x1e, False, CPU68000);
   AddFPUOp("GETMAN",0x1f, False, CPU68000);  AddFPUOp("DIV"   ,0x20, True , CPU68000);
   AddFPUOp("SDIV"  ,0x60, False, CPU68040);  AddFPUOp("DDIV"  ,0x64, True , CPU68040);
   AddFPUOp("MOD"   ,0x21, True , CPU68000);  AddFPUOp("ADD"   ,0x22, True , CPU68000);
   AddFPUOp("SADD"  ,0x62, True , CPU68040);  AddFPUOp("DADD"  ,0x66, True , CPU68040);
   AddFPUOp("MUL"   ,0x23, True , CPU68000);  AddFPUOp("SMUL"  ,0x63, True , CPU68040);
   AddFPUOp("DMUL"  ,0x67, True , CPU68040);  AddFPUOp("SGLDIV",0x24, True , CPU68000);
   AddFPUOp("REM"   ,0x25, True , CPU68000);  AddFPUOp("SCALE" ,0x26, True , CPU68000);
   AddFPUOp("SGLMUL",0x27, True , CPU68000);  AddFPUOp("SUB"   ,0x28, True , CPU68000);
   AddFPUOp("SSUB"  ,0x68, True , CPU68040);  AddFPUOp("DSUB"  ,0x6c, True , CPU68040);
   AddFPUOp("CMP"   ,0x38, True , CPU68000);

   FPUConds=(FPUCond *) malloc(sizeof(FPUCond)*FPUCondCnt); InstrZ=0;
   AddFPUCond("EQ"  , 0x01); AddFPUCond("NE"  , 0x0e);
   AddFPUCond("GT"  , 0x12); AddFPUCond("NGT" , 0x1d);
   AddFPUCond("GE"  , 0x13); AddFPUCond("NGE" , 0x1c);
   AddFPUCond("LT"  , 0x14); AddFPUCond("NLT" , 0x1b);
   AddFPUCond("LE"  , 0x15); AddFPUCond("NLE" , 0x1a);
   AddFPUCond("GL"  , 0x16); AddFPUCond("NGL" , 0x19);
   AddFPUCond("GLE" , 0x17); AddFPUCond("NGLE", 0x18);
   AddFPUCond("OGT" , 0x02); AddFPUCond("ULE" , 0x0d);
   AddFPUCond("OGE" , 0x03); AddFPUCond("ULT" , 0x0c);
   AddFPUCond("OLT" , 0x04); AddFPUCond("UGE" , 0x0b);
   AddFPUCond("OLE" , 0x05); AddFPUCond("UGT" , 0x0a);
   AddFPUCond("OGL" , 0x06); AddFPUCond("UEQ" , 0x09);
   AddFPUCond("OR"  , 0x07); AddFPUCond("UN"  , 0x08);

   PMMUConds=(char **) malloc(sizeof(char *)*PMMUCondCnt); InstrZ=0;
   AddPMMUCond("BS"); AddPMMUCond("BC"); AddPMMUCond("LS"); AddPMMUCond("LC"); 
   AddPMMUCond("SS"); AddPMMUCond("SC"); AddPMMUCond("AS"); AddPMMUCond("AC"); 
   AddPMMUCond("WS"); AddPMMUCond("WC"); AddPMMUCond("IS"); AddPMMUCond("IC"); 
   AddPMMUCond("GS"); AddPMMUCond("GC"); AddPMMUCond("CS"); AddPMMUCond("CC"); 

   PMMURegNames=(char **) malloc(sizeof(char *)*PMMURegCnt);
   PMMURegSizes=(Byte *) malloc(sizeof(Byte)*PMMURegCnt);
   PMMURegCodes=(Word *) malloc(sizeof(Word)*PMMURegCnt); InstrZ=0;
   AddPMMUReg("TC"   ,2,16); AddPMMUReg("DRP"  ,3,17);
   AddPMMUReg("SRP"  ,3,18); AddPMMUReg("CRP"  ,3,19);
   AddPMMUReg("CAL"  ,0,20); AddPMMUReg("VAL"  ,0,21);
   AddPMMUReg("SCC"  ,0,22); AddPMMUReg("AC"   ,1,23);
   AddPMMUReg("PSR"  ,1,24); AddPMMUReg("PCSR" ,1,25);
   AddPMMUReg("TT0"  ,2, 2); AddPMMUReg("TT1"  ,2, 3);
   AddPMMUReg("MMUSR",1,24); 
END

	static void DeinitFields(void)
BEGIN
   DestroyInstTable(InstTable); DestroyInstTable(FInstTable);
   DestroyInstTable(CInstTable);
   free(FixedOrders);
   free(CtRegs);
   free(CondNams); free(CondVals);
   free(FPUOps);
   free(FPUConds);
   free(PMMUConds);
   free(PMMURegNames); free(PMMURegSizes); free(PMMURegCodes);
END

/*---------------------------------------------------------------------------*/

        static Boolean DecodePseudo(void)
BEGIN
   return False;
END

/*-------------------------------------------------------------------------*/


        static Boolean DecodeOneFPReg(char *Asc, Byte * h)
BEGIN
   if ((strlen(Asc)==3) AND (strncasecmp(Asc,"FP",2)==0) AND ValReg(Asc[2]))
    BEGIN
     *h=Asc[2]-'0'; return True;
    END
   else return False;
END

        static void DecodeFRegList(char *Asc_o, Byte *Typ, Byte *Erg)
BEGIN
   String s,Asc;
   Word hw;
   Byte h2,h3,z;
   char *h1;

   strmaxcpy(Asc,Asc_o,255);
   *Typ=0; if (*Asc=='\0') return;

   if ((strlen(Asc)==2) AND (*Asc=='D') AND ValReg(Asc[1]))
    BEGIN
     *Typ = 1; *Erg = (Asc[1]-'0') << 4; return;
    END;

   hw=0;
   do
    BEGIN
     h1=strchr(Asc,'/');
     if (h1==Nil)
      BEGIN
       strcpy(s,Asc); *Asc='\0';
      END
     else
      BEGIN
       *h1='\0'; strcpy(s,Asc); strcpy(Asc,h1+1);
      END
     if (strcasecmp(s,"FPCR")==0) hw|=0x400;
     else if (strcasecmp(s,"FPSR")==0) hw|=0x200;
     else if (strcasecmp(s,"FPIAR")==0) hw|=0x100;
     else
      BEGIN
       h1=strchr(s,'-');
       if (h1==Nil)
        BEGIN
         if (NOT DecodeOneFPReg(s,&h2)) return;
         hw|=(1 << (7-h2));
        END
       else
        BEGIN
         *h1='\0';
         if (NOT DecodeOneFPReg(s,&h2)) return;
         if (NOT DecodeOneFPReg(h1+1,&h3)) return;
         for (z=h2; z<=h3; z++) hw|=(1 << (7-z));
        END
      END
    END
   while (*Asc!='\0');
   if (Hi(hw)==0)
    BEGIN
     *Typ=2; *Erg=Lo(hw);
    END
   else if (Lo(hw)==0)
    BEGIN
     *Typ=3; *Erg=Hi(hw);
    END
END

        static void GenerateMovem(Byte z1, Byte z2)
BEGIN
   Byte hz2,z;

   if (AdrNum==0) return;
   CodeLen=4+AdrCnt; CopyAdrVals(WAsmCode+2);
   WAsmCode[0]=0xf200 | AdrMode;
   switch (z1)
    BEGIN
     case 1:
     case 2:
      WAsmCode[1]|=0xc000;
      if (z1==1) WAsmCode[1]|=0x800;
      if (AdrNum!=5) WAsmCode[1]|=0x1000;
      if ((AdrNum==5) AND (z1==2))
       BEGIN
        hz2=z2; z2=0;
        for (z=0; z<8; z++)
         BEGIN
          z2=z2 << 1; if ((hz2&1)==1) z2|=1;
          hz2=hz2 >> 1;
         END
       END
      WAsmCode[1]|=z2;
      break;
     case 3:
      WAsmCode[1]|=0x8000 | (((Word)z2) << 10);
    END
END

        static void DecodeFPUOrders(void)
BEGIN
   Byte z,z1,z2;
   char *p;
   String sk;
   LongInt HVal;
   Integer HVal16;
   Boolean ValOK;
   Word Mask;

   if (LookupInstTable(FInstTable,OpPart)) return;

   if (Memo("SAVE"))
    BEGIN
     if (ArgCnt!=1) WrError(1110);
     else if (*AttrPart!='\0') WrError(1130);
     else
      BEGIN
       DecodeAdr(ArgStr[1],Madri+Mpre+Mdadri+Maix+Mabs);
       if (AdrNum!=0)
	BEGIN
	 CodeLen=2+AdrCnt; WAsmCode[0]=0xf300 | AdrMode;
	 CopyAdrVals(WAsmCode+1); CheckSup();
	END
      END
     return;
    END

   if (Memo("RESTORE"))
    BEGIN
     if (ArgCnt!=1) WrError(1110);
     else if (*AttrPart!='\0') WrError(1130);
     else
      BEGIN
       DecodeAdr(ArgStr[1],Madri+Mpost+Mdadri+Maix+Mabs);
       if (AdrNum!=0)
	BEGIN
	 CodeLen=2+AdrCnt; WAsmCode[0]=0xf340 | AdrMode;
	 CopyAdrVals(WAsmCode+1); CheckSup();
	END
      END
     return;
    END

   if (Memo("NOP"))
    BEGIN
     if (ArgCnt!=0) WrError(1110);
     else if (*AttrPart!='\0') WrError(1130);
     else
      BEGIN
       CodeLen=4; WAsmCode[0]=0xf280; WAsmCode[1]=0;
      END
     return;
    END

   if (Memo("MOVE"))
    BEGIN
     if (ArgCnt!=2) WrError(1110);
     else if (OpSize==3) WrError(1130);
     else
      BEGIN
       p=strchr(AttrPart,'{');
       if (p!=0)                               /* k-Faktor abspalten */
        BEGIN
         strcpy(sk,p); *p='\0';
        END
       else *sk='\0';
       DecodeAdr(ArgStr[2],Mdata+Madr+Madri+Mpost+Mpre+Mdadri+Maix+Mabs+Mfpn+Mfpcr);
       if (AdrNum==12)                         /* FMOVE.x <ea>/FPm,FPn ? */
        BEGIN
         WAsmCode[0]=0xf200; WAsmCode[1]=AdrMode << 7;
         RelPos=4;
         if (*AttrPart=='\0') OpSize=6;
         DecodeAdr(ArgStr[1],((OpSize<=2) OR (OpSize==4))?
                             Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm+Mfpn:
                             Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm+Mfpn);
         if (AdrNum==12)                       /* FMOVE.X FPm,FPn ? */
          BEGIN
           WAsmCode[1]|=AdrMode << 10;
           if (OpSize==6) CodeLen=4; else WrError(1130);
          END
         else if (AdrNum!=0)                   /* FMOVE.x <ea>,FPn ? */
          BEGIN
           CodeLen=4+AdrCnt; CopyAdrVals(WAsmCode+2);
           WAsmCode[0]|=AdrMode;
           WAsmCode[1]|=0x4000 | (((Word)FSizeCodes[OpSize]) << 10);
          END
        END
       else if (AdrNum==13)                    /* FMOVE.L <ea>,FPcr ? */
        BEGIN
         if ((OpSize!=2) AND (*AttrPart!='\0')) WrError(1130);
         else
          BEGIN
           RelPos=4;
           WAsmCode[0]=0xf200; WAsmCode[1]=0x8000 | (AdrMode << 10);
           DecodeAdr(ArgStr[1],(AdrMode==1)?
                     Mdata+Madr+Madri+Mpost+Mpre+Mdadri+Mpc+Mpcidx+Mabs+Mimm:
                     Mdata+Madri+Mpost+Mpre+Mdadri+Mpc+Mpcidx+Mabs+Mimm);
           if (AdrNum!=0)
            BEGIN
             WAsmCode[0]|=AdrMode; CodeLen=4+AdrCnt;
             CopyAdrVals(WAsmCode+2);
            END
          END
        END
       else if (AdrNum!=0)                     /* FMOVE.x ????,<ea> ? */
        BEGIN
         WAsmCode[0]=0xf200 | AdrMode;
         CodeLen=4+AdrCnt; CopyAdrVals(WAsmCode+2);
         DecodeAdr(ArgStr[1], (AdrNum == 2) ? Mfpcr : Mfpn + Mfpcr);
         if (AdrNum==12)                       /* FMOVE.x FPn,<ea> ? */
          BEGIN
           if (*AttrPart=='\0') OpSize=6;
           WAsmCode[1]=0x6000 | (((Word)FSizeCodes[OpSize]) << 10) | (AdrMode << 7);
           if (OpSize==7)
            if (strlen(sk)>2)
             BEGIN
              OpSize=0; strcpy(sk,sk+1); sk[strlen(sk)-1]='\0';
              DecodeAdr(sk,Mdata+Mimm);
              if (AdrNum==1) WAsmCode[1]|=(AdrMode << 4) | 0x1000;
              else if (AdrNum==11) WAsmCode[1]|=(AdrVals[0] & 127);
              else CodeLen=0;
             END
            else WAsmCode[1]|=17;
          END
         else if (AdrNum==13)                  /* FMOVE.L FPcr,<ea> ? */
          BEGIN
           if ((*AttrPart!='\0') AND (OpSize!=2))
            BEGIN
             WrError(1130); CodeLen=0;
            END
           else
            BEGIN
             WAsmCode[1]=0xa000 | (AdrMode << 10);
             if ((AdrMode!=1) AND ((WAsmCode[0] & 0x38)==8))
              BEGIN
               WrError(1350); CodeLen=0;
              END
            END
          END
         else CodeLen=0;
        END
      END
     return;
    END

   if (Memo("MOVECR"))
    BEGIN
     if (ArgCnt!=2) WrError(1110);
     else if ((*AttrPart!='\0') AND (OpSize!=6)) WrError(1130);
     else
      BEGIN
       DecodeAdr(ArgStr[2],Mfpn);
       if (AdrNum==12)
        BEGIN
         WAsmCode[0]=0xf200; WAsmCode[1]=0x5c00 | (AdrMode << 7);
         OpSize=0;
         DecodeAdr(ArgStr[1],Mimm);
         if (AdrNum==11)
          if (AdrVals[0]>63) WrError(1700);
          else
           BEGIN
            CodeLen=4;
            WAsmCode[1]|=AdrVals[0];
           END
        END
      END
     return;
    END

   if (Memo("TST"))
    BEGIN
     if (*AttrPart=='\0') OpSize=6;
     else if (OpSize==3) WrError(1130);
     else if (ArgCnt!=1) WrError(1110);
     else
      BEGIN
       RelPos=4;
       DecodeAdr(ArgStr[1],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm+Mfpn);
       if (AdrNum==12)
        BEGIN
         WAsmCode[0]=0xf200; WAsmCode[1]=0x3a | (AdrMode << 10);
         CodeLen=4;
        END
       else if (AdrNum!=0)
        BEGIN
         WAsmCode[0]=0xf200 | AdrMode;
         WAsmCode[1]=0x403a | (((Word)FSizeCodes[OpSize]) << 10);
         CodeLen=4+AdrCnt; CopyAdrVals(WAsmCode+2);
        END
      END
     return;
    END

   if (Memo("SINCOS"))
    BEGIN
     if (*AttrPart=='\0') OpSize=6;
     if (OpSize==3) WrError(1130);
     else if (ArgCnt!=2) WrError(1110);
     else
      BEGIN
       p=strrchr(ArgStr[2],':');
       if (p!=Nil)
        BEGIN
         *p='\0'; strcpy(sk,ArgStr[2]); strcpy(ArgStr[2],p+1);
        END
       else *sk='\0';
       DecodeAdr(sk,Mfpn);
       if (AdrNum==12)
        BEGIN
         WAsmCode[1]=AdrMode | 0x30;
         DecodeAdr(ArgStr[2],Mfpn);
         if (AdrNum==12)
          BEGIN
           WAsmCode[1]|=(AdrMode << 7);
           RelPos=4;
           DecodeAdr(ArgStr[1],((OpSize<=2) OR (OpSize==4))?
                               Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm+Mfpn:
                               Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm+Mfpn);
           if (AdrNum==12)
            BEGIN
             WAsmCode[0]=0xf200; WAsmCode[1]|=(AdrMode << 10);
             CodeLen=4;
            END
           else if (AdrNum!=0)
            BEGIN
             WAsmCode[0]=0xf200 | AdrMode;
             WAsmCode[1]|=0x4000 | (((Word)FSizeCodes[OpSize]) << 10);
             CodeLen=4+AdrCnt; CopyAdrVals(WAsmCode+2);
            END
          END
        END
      END
     return;
    END

   if (*OpPart=='B')
    BEGIN
     for (z=0; z<FPUCondCnt; z++)
      if (strcmp(OpPart+1,FPUConds[z].Name)==0) break;
     if (z>=FPUCondCnt) WrError(1360);
     else
      BEGIN
       if ((OpSize!=1) AND (OpSize!=2) AND (OpSize!=6)) WrError(1130);
       else if (ArgCnt!=1) WrError(1110);
       else
	BEGIN
	 HVal=EvalIntExpression(ArgStr[1],Int32,&ValOK)-(EProgCounter()+2);
	 HVal16=HVal;

	 if (OpSize==1)
	  BEGIN
	   OpSize=(IsDisp16(HVal))?2:6;
	  END

         if (OpSize==2)
          BEGIN
           if ((NOT IsDisp16(HVal)) AND (NOT SymbolQuestionable)) WrError(1370);
           else
            BEGIN
             CodeLen=4; WAsmCode[0]=0xf280 | FPUConds[z].Code;
             WAsmCode[1]=HVal16;
            END
          END
         else
          BEGIN
           CodeLen=6; WAsmCode[0]=0xf2c0 | FPUConds[z].Code;
           WAsmCode[2]=HVal & 0xffff; WAsmCode[1]=HVal >> 16;
	   if ((IsDisp16(HVal)) AND (PassNo>1) AND (*AttrPart=='\0'))
	    BEGIN
	     WrError(20); WAsmCode[0]^=0x40;
             CodeLen-=2; WAsmCode[1]=WAsmCode[2]; StopfZahl++;
            END
          END
        END
      END
     return;
    END

   if (strncmp(OpPart,"DB",2)==0)
    BEGIN
     for (z=0; z<FPUCondCnt; z++)
      if (strcmp(OpPart+2,FPUConds[z].Name)==0) break;
     if (z>=FPUCondCnt) WrError(1360);
     else
      BEGIN
       if ((OpSize!=1) AND (*AttrPart!='\0')) WrError(1130);
       else if (ArgCnt!=2) WrError(1110);
       else
        BEGIN
         DecodeAdr(ArgStr[1],Mdata);
         if (AdrNum!=0)
          BEGIN
           WAsmCode[0]=0xf248 | AdrMode; WAsmCode[1]=FPUConds[z].Code;
           HVal=EvalIntExpression(ArgStr[2],Int32,&ValOK)-(EProgCounter()+4);
           if (ValOK)
            BEGIN
             HVal16=HVal; WAsmCode[2]=HVal16;
             if ((NOT IsDisp16(HVal)) AND (NOT SymbolQuestionable)) WrError(1370); else CodeLen=6;
            END
          END
        END
      END
     return;
    END

   if ((Memo("DMOVE")) OR (Memo("SMOVE")))
    BEGIN
     if (ArgCnt != 2) WrError(1110);
     else if (MomCPU < CPU68040) WrError(1500);
     else
      BEGIN
       DecodeAdr(ArgStr[2], Mfpn);
       if (AdrNum == 12)
        BEGIN
         WAsmCode[0] = 0xf200;
         WAsmCode[1] = 0x0040 | AdrMode << 7;
         if (*OpPart == 'D') WAsmCode[1] |= 4;
         RelPos = 4;
         if (*AttrPart == '\0') OpSize = 6;
         Mask = Mfpn+Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm;
         if ((OpSize <= 2) OR (OpSize == 4))
          Mask |= Mdata;
         DecodeAdr(ArgStr[1], Mask);
         if (AdrNum == 12)
          BEGIN
           CodeLen = 4;
           WAsmCode[1] |= (AdrMode << 10);
          END
         else if (AdrNum != 0)
          BEGIN
           CodeLen = 4 + AdrCnt; CopyAdrVals(WAsmCode + 2);
           WAsmCode[0] |= AdrMode;
           WAsmCode[1] |= 0x4000 | (((Word)FSizeCodes[OpSize]) << 10);
          END
        END
      END
     return;
    END

   if (*OpPart=='S')
    BEGIN
     for (z=0; z<FPUCondCnt; z++)
      if (strcmp(OpPart+1,FPUConds[z].Name)==0) break;
     if (z>=FPUCondCnt) WrError(1360);
     else
      BEGIN
       if ((OpSize!=0) AND (*AttrPart!='\0')) WrError(1130);
       else if (ArgCnt!=1) WrError(1110);
       else
        BEGIN
         DecodeAdr(ArgStr[1],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
         if (AdrNum!=0)
          BEGIN
           CodeLen=4+AdrCnt; WAsmCode[0]=0xf240 | AdrMode;
           WAsmCode[1]=FPUConds[z].Code; CopyAdrVals(WAsmCode+2);
          END
        END
      END
     return;
    END

   if (strncmp(OpPart,"TRAP",4)==0)
    BEGIN
     for (z=0; z<FPUCondCnt; z++)
      if (strcmp(OpPart+4,FPUConds[z].Name)==0) break;
     if (z>=FPUCondCnt) WrError(1360);
     else
      BEGIN
       if (*AttrPart=='\0') OpSize=0;
       if (OpSize>2) WrError(1130);
       else if (((OpSize==0) AND (ArgCnt!=0)) OR ((OpSize!=0) AND (ArgCnt!=1))) WrError(1110);
       else
        BEGIN
         WAsmCode[0]=0xf278; WAsmCode[1]=FPUConds[z].Code;
         if (OpSize==0)
          BEGIN
           WAsmCode[0]|=4; CodeLen=4;
          END
         else
          BEGIN
           DecodeAdr(ArgStr[1],Mimm);
           if (AdrNum!=0)
            BEGIN
             WAsmCode[0]|=(OpSize+1);
             CopyAdrVals(WAsmCode+2); CodeLen=4+AdrCnt;
            END
          END
        END
      END
     return;
    END

   if (Memo("MOVEM"))
    BEGIN
     if (ArgCnt!=2) WrError(1110);
     else
      BEGIN
       DecodeFRegList(ArgStr[2], &z1, &z2);
       if (z1 != 0)
        BEGIN
         if ((*AttrPart != '\0')
         AND (((z1 < 3) AND (OpSize != 6))
           OR ((z1 == 3) AND (OpSize != 2))))
          WrError(1130);
         else
          BEGIN
           RelPos = 4;
           Mask = Madri + Mpost + Mdadri + Maix + Mpc + Mpcidx + Mabs + Mimm;
           if (z1 == 3)   /* Steuerregister auch Predekrement */
            BEGIN
             Mask |= Mpre;
             if ((z2 == 4) | (z2 == 2) | (z2 == 1)) /* nur ein Register */
              Mask |= Mdata;
             if (z2 == 1) /* nur FPIAR */
              Mask |= Madr;
            END
           DecodeAdr(ArgStr[1], Mask);
           WAsmCode[1] = 0; GenerateMovem(z1, z2);
          END
        END
       else
        BEGIN
         DecodeFRegList(ArgStr[1],&z1,&z2);
         if (z1!=0)
          BEGIN
           if ((*AttrPart!='\0') AND (((z1<3) AND (OpSize!=6)) OR ((z1==3) AND (OpSize!=2))))
            WrError(1130);
           else
            BEGIN
             Mask = Madri + Mpost + Mdadri + Maix + Mabs;
             if (z1 == 3)   /* Steuerregister auch Postinkrement */
              BEGIN
               Mask |= Mpre;
               if ((z2 == 4) | (z2 == 2) | (z2 == 1)) /* nur ein Register */
                Mask |= Mdata;
               if (z2 == 1) /* nur FPIAR */
                Mask |= Madr;
              END
             DecodeAdr(ArgStr[2], Mask);
             WAsmCode[1] = 0x2000; GenerateMovem(z1, z2);
            END
          END
         else WrError(1410);
        END
      END
     return;
    END

   WrXError(1200,OpPart);
END

/*-------------------------------------------------------------------------*/


        static Boolean DecodeFC(char *Asc, Word *erg)
BEGIN
   Boolean OK;
   Word Val;
   String Asc_N;

   strmaxcpy(Asc_N,Asc,255); NLS_UpString(Asc_N); Asc=Asc_N;

   if (strcmp(Asc,"SFC")==0)
    BEGIN
     *erg=0; return True;
    END

   if (strcmp(Asc,"DFC")==0)
    BEGIN
     *erg=1; return True;
    END

   if ((strlen(Asc)==2) AND (*Asc=='D') AND ValReg(Asc[1]))
    BEGIN
     *erg=Asc[2]-'0'+8; return True;
    END

   if (*Asc=='#')
    BEGIN
     Val=EvalIntExpression(Asc+1,Int4,&OK);
     if (OK) *erg=Val+16; return OK;
    END

   return False;
END

        static Boolean DecodePMMUReg(char *Asc, Word *erg, Byte *Size)
BEGIN
   Byte z;

   if ((strlen(Asc)==4) AND (strncasecmp(Asc,"BAD",3)==0) AND ValReg(Asc[3]))
    BEGIN
     *Size=1;
     *erg=0x7000+((Asc[3]-'0') << 2); return True;
    END
   if ((strlen(Asc)==4) AND (strncasecmp(Asc,"BAC",3)==0) AND ValReg(Asc[3]))
    BEGIN
     *Size=1;
     *erg=0x7400+((Asc[3]-'0') << 2); return True;
    END

   for (z=0; z<PMMURegCnt; z++)
    if (strcasecmp(Asc,PMMURegNames[z])==0) break;
   if (z<PMMURegCnt)
    BEGIN
     *Size=PMMURegSizes[z];
     *erg=PMMURegCodes[z] << 10;
    END
   return (z<PMMURegCnt);
END

        static void DecodePMMUOrders(void)
BEGIN
   Byte z;
   Word Mask;
   LongInt HVal;
   Integer HVal16;
   Boolean ValOK;

   if (Memo("SAVE"))
    BEGIN
     if (ArgCnt!=1) WrError(1110);
     else if (*AttrPart!='\0') WrError(1130);
     else if (NOT FullPMMU) WrError(1500);
     else
      BEGIN
       DecodeAdr(ArgStr[1],Madri+Mpre+Mdadri+Maix+Mabs);
       if (AdrNum!=0)
	BEGIN
	 CodeLen=2+AdrCnt; WAsmCode[0]=0xf100 | AdrMode;
	 CopyAdrVals(WAsmCode+1); CheckSup();
	END
      END
     return;
    END

   if (Memo("RESTORE"))
    BEGIN
     if (ArgCnt!=1) WrError(1110);
     else if (*AttrPart!='\0') WrError(1130);
     else if (NOT FullPMMU) WrError(1500);
     else
      BEGIN
       DecodeAdr(ArgStr[1],Madri+Mpre+Mdadri+Maix+Mabs);
       if (AdrNum!=0)
	BEGIN
	 CodeLen=2+AdrCnt; WAsmCode[0]=0xf140 | AdrMode;
	 CopyAdrVals(WAsmCode+1); CheckSup();
	END
      END
     return;
    END

   if (Memo("FLUSHA"))
    BEGIN
     if (*AttrPart!='\0') WrError(1130);
     else if (ArgCnt!=0) WrError(1110);
     else
      BEGIN
       if (MomCPU>=CPU68040)
        BEGIN
         CodeLen=2; WAsmCode[0]=0xf518;
        END
       else
        BEGIN
         CodeLen=4; WAsmCode[0]=0xf000; WAsmCode[1]=0x2400;
        END
       CheckSup();
      END
     return;
    END

   if (Memo("FLUSHAN"))
    BEGIN
     if (*AttrPart!='\0') WrError(1130);
     else if (ArgCnt!=0) WrError(1110);
     else
      BEGIN
       CodeLen=2; WAsmCode[0]=0xf510;
       CheckCPU(CPU68040); CheckSup();
      END
     return;
    END

   if ((Memo("FLUSH")) OR (Memo("FLUSHS")))
    BEGIN
     if (*AttrPart!='\0') WrError(1130);
     else if (MomCPU>=CPU68040)
      BEGIN
       if (Memo("FLUSHS")) WrError(1500);
       else if (ArgCnt!=1) WrError(1110);
       else
        BEGIN
         DecodeAdr(ArgStr[1],Madri);
         if (AdrNum!=0)
          BEGIN
           WAsmCode[0]=0xf508+(AdrMode & 7);
           CodeLen=2;
           CheckSup();
          END
        END
      END
     else if ((ArgCnt!=2) AND (ArgCnt!=3)) WrError(1110);
     else if ((Memo("FLUSHS")) AND (NOT FullPMMU)) WrError(1500);
     else if (NOT DecodeFC(ArgStr[1],WAsmCode+1)) WrError(1710);
     else
      BEGIN
       OpSize=0;
       DecodeAdr(ArgStr[2],Mimm);
       if (AdrNum!=0)
        BEGIN
         if (AdrVals[0]>15) WrError(1720);
         else
          BEGIN
           WAsmCode[1]|=(AdrVals[0] << 5) | 0x3000;
           if (Memo("FLUSHS")) WAsmCode[1]|=0x400;
           WAsmCode[0]=0xf000; CodeLen=4; CheckSup();
           if (ArgCnt==3)
            BEGIN
             WAsmCode[1]|=0x800;
             DecodeAdr(ArgStr[3],Madri+Mdadri+Maix+Mabs);
             if (AdrNum==0) CodeLen=0;
             else
              BEGIN
               WAsmCode[0]|=AdrMode; CodeLen+=AdrCnt;
               CopyAdrVals(WAsmCode+2);
              END
            END
          END
        END
      END
     return;
    END

   if (Memo("FLUSHN"))
    BEGIN
     if (*AttrPart!='\0') WrError(1100);
     else if (ArgCnt!=1) WrError(1110);
     else
      BEGIN
       DecodeAdr(ArgStr[1],Madri);
       if (AdrNum!=0)
        BEGIN
         WAsmCode[0]=0xf500+(AdrMode & 7);
         CodeLen=2;
         CheckCPU(CPU68040); CheckSup();
        END
      END
     return;
    END

   if (Memo("FLUSHR"))
    BEGIN
     if (*AttrPart=='\0') OpSize=3;
     if (OpSize!=3) WrError(1130);
     else if (ArgCnt!=1) WrError(1110);
     else if (NOT FullPMMU) WrError(1500);
     else
      BEGIN
       RelPos=4;
       DecodeAdr(ArgStr[1],Madri+Mpre+Mpost+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm);
       if (AdrNum!=0)
        BEGIN
         WAsmCode[0]=0xf000 | AdrMode; WAsmCode[1]=0xa000;
         CopyAdrVals(WAsmCode+2); CodeLen=4+AdrCnt; CheckSup();
        END
      END
     return;
    END

   if ((Memo("LOADR")) OR (Memo("LOADW")))
    BEGIN
     if (*AttrPart!='\0') WrError(1130);
     else if (ArgCnt!=2) WrError(1110);
     else if (NOT DecodeFC(ArgStr[1],WAsmCode+1)) WrError(1710);
     else
      BEGIN
       DecodeAdr(ArgStr[2],Madri+Mdadri+Maix+Mabs);
       if (AdrNum!=0)
        BEGIN
         WAsmCode[0]=0xf000 | AdrMode; WAsmCode[1]|=0x2000;
         if (Memo("LOADR")) WAsmCode[1]|=0x200;
         CodeLen=4+AdrCnt; CopyAdrVals(WAsmCode+2); CheckSup();
        END
      END
     return;
    END

   if ((Memo("MOVE")) OR (Memo("MOVEFD")))
    BEGIN
     if (ArgCnt!=2) WrError(1110);
     else
      BEGIN
       if (DecodePMMUReg(ArgStr[1],WAsmCode+1,&z))
	BEGIN
	 WAsmCode[1]|=0x200;
	 if (*AttrPart=='\0') OpSize=z;
	 if (OpSize!=z) WrError(1130);
	 else
	  BEGIN
           Mask=Madri+Mdadri+Maix+Mabs;
           if (FullPMMU)
	    BEGIN
	     Mask*=Mpost+Mpre;
             if (z!=3) Mask+=Mdata+Madr;
            END
           DecodeAdr(ArgStr[2],Mask);
	   if (AdrNum!=0)
	    BEGIN
	     WAsmCode[0]=0xf000 | AdrMode;
	     CodeLen=4+AdrCnt; CopyAdrVals(WAsmCode+2);
             CheckSup();
	    END
	  END
	END
       else if (DecodePMMUReg(ArgStr[2],WAsmCode+1,&z))
	BEGIN
	 if (*AttrPart=='\0') OpSize=z;
	 if (OpSize!=z) WrError(1130);
	 else
	  BEGIN
           RelPos=4;
           Mask=Madri+Mdadri+Maix+Mabs;
           if (FullPMMU)
	    BEGIN
	     Mask+=Mpost+Mpre+Mpc+Mpcidx+Mimm;
             if (z!=3) Mask+=Mdata+Madr;
            END
           DecodeAdr(ArgStr[1],Mask);
	   if (AdrNum!=0)
	    BEGIN
	     WAsmCode[0]=0xf000 | AdrMode;
	     CodeLen=4+AdrCnt; CopyAdrVals(WAsmCode+2);
             if (Memo("MOVEFD")) WAsmCode[1]+=0x100;
             CheckSup();
	    END
	  END
	END
       else WrError(1730);
      END
     return;
    END

   if ((Memo("TESTR")) OR (Memo("TESTW")))
    BEGIN
     if (*AttrPart!='\0') WrError(1130);
     else if (MomCPU>=CPU68040)
      BEGIN
       if (ArgCnt!=1) WrError(1110);
       else
        BEGIN
         DecodeAdr(ArgStr[1],Madri);
         if (AdrNum!=0)
          BEGIN
           WAsmCode[0]=0xf548+(AdrMode & 7)+(Ord(Memo("TESTR")) << 5);
           CodeLen=2;
           CheckSup();
          END
        END
      END
     else if ((ArgCnt>4) OR (ArgCnt<3)) WrError(1110);
     else
      BEGIN
       if (NOT DecodeFC(ArgStr[1],WAsmCode+1)) WrError(1710);
       else
        BEGIN
         DecodeAdr(ArgStr[2],Madri+Mdadri+Maix+Mabs);
         if (AdrNum!=0)
          BEGIN
           WAsmCode[0]=0xf000 | AdrMode; CodeLen=4+AdrCnt;
           WAsmCode[1]|=0x8000;
           CopyAdrVals(WAsmCode+2);
           if (Memo("TESTR")) WAsmCode[1]|=0x200;
           DecodeAdr(ArgStr[3],Mimm);
           if (AdrNum!=0)
            if (AdrVals[0]>7)
             BEGIN
              WrError(1740); CodeLen=0;
             END
            else
             BEGIN
              WAsmCode[1]|=AdrVals[0] << 10;
              if (ArgCnt==4)
               BEGIN
                DecodeAdr(ArgStr[4],Madr);
                if (AdrNum==0) CodeLen=0; else WAsmCode[1]|=AdrMode << 5; 
                CheckSup();
               END
             END
           else CodeLen=0;
          END
        END
      END
     return;
    END

   if (Memo("VALID"))
    BEGIN
     if (ArgCnt!=2) WrError(1110);
     else if (NOT FullPMMU) WrError(1500);
     else if ((*AttrPart!='\0') AND (OpSize!=2)) WrError(1130);
     else
      BEGIN
       DecodeAdr(ArgStr[2],Madri+Mdadri+Maix+Mabs);
       if (AdrNum!=0)
        BEGIN
         WAsmCode[0]=0xf000 | AdrMode;
         WAsmCode[1]=0x2800; CodeLen=4+AdrCnt;
         CopyAdrVals(WAsmCode+1);
         if (strcasecmp(ArgStr[1],"VAL")==0);
         else
          BEGIN
           DecodeAdr(ArgStr[1],Madr);
           if (AdrNum!=0)
            BEGIN
             WAsmCode[1]|=0x400 | (AdrMode & 7);
            END
           else CodeLen=0;
          END
        END
      END
     return;
    END

   if (*OpPart=='B')
    BEGIN
     for (z=0; z<PMMUCondCnt; z++)
      if (strcmp(OpPart+1,PMMUConds[z])==0) break;
     if (z==PMMUCondCnt) WrError(1360);
     else
      BEGIN
       if ((OpSize!=1) AND (OpSize!=2) AND (OpSize!=6)) WrError(1130);
       else if (ArgCnt!=1) WrError(1110);
       else if (NOT FullPMMU) WrError(1500);
       else
	BEGIN

	 HVal=EvalIntExpression(ArgStr[1],Int32,&ValOK)-(EProgCounter()+2);
	 HVal16=HVal;

	 if (OpSize==1) OpSize=(IsDisp16(HVal))?2:6;

	 if (OpSize==2)
	  BEGIN
           if ((NOT IsDisp16(HVal)) AND (NOT SymbolQuestionable)) WrError(1370);
	   else
	    BEGIN
	     CodeLen=4; WAsmCode[0]=0xf080 | z;
	     WAsmCode[1]=HVal16; CheckSup();
	    END
	  END
	 else
	  BEGIN
	   CodeLen=6; WAsmCode[0]=0xf0c0 | z;
	   WAsmCode[2]=HVal & 0xffff; WAsmCode[1]=HVal >> 16;
	   CheckSup();
	  END
	END
      END
     return;
    END;

   if (strncmp(OpPart,"DB",2)==0)
    BEGIN
     for (z=0; z<PMMUCondCnt; z++)
      if (strcmp(OpPart+2,PMMUConds[z])==0) break;
     if (z==PMMUCondCnt) WrError(1360);  
     else
      BEGIN
       if ((OpSize!=1) AND (*AttrPart!='\0')) WrError(1130);
       else if (ArgCnt!=2) WrError(1110);
       else if (NOT FullPMMU) WrError(1500);
       else
        BEGIN
         DecodeAdr(ArgStr[1],Mdata);
         if (AdrNum!=0)
          BEGIN
           WAsmCode[0]=0xf048 | AdrMode; WAsmCode[1]=z;
           HVal=EvalIntExpression(ArgStr[2],Int32,&ValOK)-(EProgCounter()+4);
           if (ValOK)
            BEGIN
             HVal16=HVal; WAsmCode[2]=HVal16;
             if ((NOT IsDisp16(HVal)) AND (NOT SymbolQuestionable)) WrError(1370); 
             else CodeLen=6; 
             CheckSup();
            END
          END
        END
      END
     return;
    END

   if (*OpPart=='S')
    BEGIN
     for (z=0; z<PMMUCondCnt; z++)
      if (strcmp(OpPart+1,PMMUConds[z])==0) break;
     if (z==PMMUCondCnt) WrError(1360);  
     else
      BEGIN
       if ((OpSize!=0) AND (*AttrPart!='\0')) WrError(1130);
       else if (ArgCnt!=1) WrError(1110);
       else if (NOT FullPMMU) WrError(1500);
       else
        BEGIN
         DecodeAdr(ArgStr[1],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
         if (AdrNum!=0)
          BEGIN
           CodeLen=4+AdrCnt; WAsmCode[0]=0xf040 | AdrMode;
           WAsmCode[1]=z; CopyAdrVals(WAsmCode+2); CheckSup();
          END
        END
      END
     return;
    END

   if (strncmp(OpPart,"TRAP",4)==0)
    BEGIN
     for (z=0; z<PMMUCondCnt; z++)
      if (strcmp(OpPart+4,PMMUConds[z])==0) break;
     if (z==PMMUCondCnt) WrError(1360);  
     else
      BEGIN
       if (*AttrPart=='\0') OpSize=0;
       if (OpSize>2) WrError(1130);
       else if (((OpSize==0) AND (ArgCnt!=0)) OR ((OpSize!=0) AND (ArgCnt!=1))) WrError(1110);
       else if (NOT FullPMMU) WrError(1500);
       else
        BEGIN
         WAsmCode[0]=0xf078; WAsmCode[1]=z;
         if (OpSize==0)
          BEGIN
           WAsmCode[0]|=4; CodeLen=4; CheckSup();
          END
         else
          BEGIN
           DecodeAdr(ArgStr[1],Mimm);
           if (AdrNum!=0)
            BEGIN
             WAsmCode[0]|=(OpSize+1);
             CopyAdrVals(WAsmCode+2); CodeLen=4+AdrCnt; CheckSup();
            END
          END
        END
      END
     return;
    END

   WrError(1200);
END

/*-------------------------------------------------------------------------*/

       	static void MakeCode_68K(void)
BEGIN
   Boolean ValOK;
   LongInt HVal;
   Integer i,HVal16;
   ShortInt HVal8;
   Word w1,w2;

   CodeLen=0;
   OpSize=(MomCPU==CPUCOLD) ? 2 : 1;
   DontPrint=False; RelPos=2;

   if (*AttrPart!='\0')
    switch (toupper(*AttrPart))
     BEGIN
      case 'B': OpSize=0; break;
      case 'W': OpSize=1; break;
      case 'L': OpSize=2; break;
      case 'Q': OpSize=3; break;
      case 'S': OpSize=4; break;
      case 'D': OpSize=5; break;
      case 'X': OpSize=6; break;
      case 'P': OpSize=7; break;
      default: WrError(1107); return;
     END

   /* Nullanweisung */

   if ((*OpPart=='\0') AND (*AttrPart=='\0') AND (ArgCnt==0)) return;

   /* Pseudoanweisungen */

   if (DecodeMoto16Pseudo(OpSize,True)) return;

   if (DecodePseudo()) return;

   /* Befehlszaehler ungerade ? */

   if (Odd(EProgCounter())) WrError(180);

   /* Befehlserweiterungen */

   if ((*OpPart=='F') AND (FPUAvail))
    BEGIN
     strcpy(OpPart,OpPart+1);
     DecodeFPUOrders();
     return;
    END

   if ((*OpPart=='P') AND (NOT Memo("PEA")) AND (PMMUAvail))
    BEGIN
     strcpy(OpPart,OpPart+1);
     DecodePMMUOrders();
     return;
    END

   /* vermischtes */

   if (LookupInstTable(InstTable,OpPart)) return;

   /* Anweisungen mit konstantem Argument */

   /* zwei Operanden */

   if ((strncmp(OpPart,"MUL",3)==0) OR (strncmp(OpPart,"DIV",3)==0)) 
    BEGIN
     if (ArgCnt!=2) WrError(1110);
     else if ((MomCPU==CPUCOLD) AND (*OpPart=='D')) WrError(1500);
     else if (OpSize==1) 
      BEGIN
       DecodeAdr(ArgStr[2],Mdata);
       if (AdrNum!=0)
	BEGIN
	 WAsmCode[0]=0x80c0 | (AdrMode << 9);
	 if (strncmp(OpPart,"MUL",3)==0) WAsmCode[0]|=0x4000;
	 if (OpPart[3]=='S') WAsmCode[0]|=0x100;
	 DecodeAdr(ArgStr[1],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm);
	 if (AdrNum!=0)
	  BEGIN
	   WAsmCode[0]|=AdrMode;
	   CodeLen=2+AdrCnt; CopyAdrVals(WAsmCode+1);
	  END
	END
      END
     else if (OpSize==2)
      BEGIN
       if (strchr(ArgStr[2],':')==Nil)
        BEGIN
         strcpy(ArgStr[3], ArgStr[2]);
         strcat(ArgStr[2], ":");
         strcat(ArgStr[2], ArgStr[3]);
        END
       if (NOT CodeRegPair(ArgStr[2],&w1,&w2)) WrXError(1760, ArgStr[2]);
       else
	BEGIN
	 WAsmCode[1]=w1+(w2 << 12); RelPos=4;
	 if (w1!=w2) WAsmCode[1]|=0x400;
	 if (OpPart[3]=='S') WAsmCode[1]|=0x800;
	 DecodeAdr(ArgStr[1],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mpc+Mpcidx+Mabs+Mimm);
	 if (AdrNum!=0)
	  BEGIN
	   WAsmCode[0]=0x4c00+AdrMode;
	   if (strncmp(OpPart,"DIV",3)==0) WAsmCode[0]|=0x40;
	   CopyAdrVals(WAsmCode+2); CodeLen=4+AdrCnt;
	   CheckCPU((w1!=w2) ? CPU68332 : CPUCOLD);
	  END
	END
      END
     else WrError(1130);
     return;
    END

   /* bedingte Befehle */

   if ((strlen(OpPart)<=3) AND (*OpPart=='B')) 
    BEGIN
     /* .W, .S, .L, .X erlaubt */

     if ((OpSize!=1) AND (OpSize!=2) AND (OpSize!=4) AND (OpSize!=6)) 
      WrError(1130);

     /* nur ein Operand erlaubt */

     else if (ArgCnt!=1) WrError(1110);
     else
      BEGIN

       /* Bedingung finden, evtl. meckern */

       if (NOT LookupInstTable(CInstTable,OpPart+1)) WrError(1360);
       else
	BEGIN

	 /* Zieladresse ermitteln, zum Programmzaehler relativieren */

	 HVal=EvalIntExpression(ArgStr[1],Int32,&ValOK);
	 HVal=HVal-(EProgCounter()+2);

	 /* Bei Automatik Groesse festlegen */

	 if (OpSize==1) 
	  BEGIN
	   if (IsDisp8(HVal)) OpSize=4;
	   else if (IsDisp16(HVal)) OpSize=2;
	   else OpSize=6;
	  END

	 if (ValOK)
	  BEGIN

	   /* 16 Bit ? */

	   if (OpSize==2)
	    BEGIN

	     /* zu weit ? */

	     HVal16=HVal;
             if ((NOT IsDisp16(HVal)) AND (NOT SymbolQuestionable)) WrError(1370);
	     else
	      BEGIN

	       /* Code erzeugen */

	       CodeLen=4; WAsmCode[0]=0x6000 | (CondIndex << 8);
	       WAsmCode[1]=HVal16;
	      END
	    END

	   /* 8 Bit ? */

	   else if (OpSize==4)
	    BEGIN

	     /* zu weit ? */

	     HVal8=HVal;
             if ((NOT IsDisp8(HVal)) AND (NOT SymbolQuestionable)) WrError(1370);

	     /* Code erzeugen */
	     else
	      BEGIN
	       CodeLen=2;
	       if (HVal8!=0)
		BEGIN
		 WAsmCode[0]=0x6000 | (CondIndex << 8) | ((Byte)HVal8);
		END
	       else
		BEGIN
		 WAsmCode[0]=NOPCode;
                 if ((NOT Repass) AND (*AttrPart!='\0')) WrError(60);
		END
	      END
	    END

	   /* 32 Bit ? */

	   else
	    BEGIN
	     CodeLen=6; WAsmCode[0]=0x60ff | (CondIndex << 8);
	     WAsmCode[1]=HVal >> 16; WAsmCode[2]=HVal & 0xffff;
	     CheckCPU(CPU68332);
	    END
	  END
	END
       return;
      END
    END

   if ((strlen(OpPart)<=3) AND (*OpPart=='S')) 
    BEGIN
     if ((*AttrPart!='\0') AND (OpSize!=0)) WrError(1130);
     else if (ArgCnt!=1) WrError(1130);
     else
      BEGIN
       i=FindICondition(OpPart+1);
       if (i>=CondCnt-2) WrError(1360);
       else
	BEGIN
         OpSize=0;
         if (MomCPU==CPUCOLD) DecodeAdr(ArgStr[1],Mdata);
	 else DecodeAdr(ArgStr[1],Mdata+Madri+Mpost+Mpre+Mdadri+Maix+Mabs);
	 if (AdrNum!=0)
	  BEGIN
	   WAsmCode[0]=0x50c0 | (CondVals[i] << 8) | AdrMode;
	   CodeLen=2+AdrCnt; CopyAdrVals(WAsmCode+1);
	  END
	END
      END
     return;
    END

   if ((strlen(OpPart)<=4) AND (strncmp(OpPart,"DB",2)==0)) 
    BEGIN
     if (OpSize!=1) WrError(1130);
     else if (ArgCnt!=2) WrError(1110);
     else if (MomCPU==CPUCOLD) WrError(1500);
     else
      BEGIN
       i=FindICondition(OpPart+2);
       if (i==18) i=1;
       if (i>=CondCnt-1) WrError(1360);
       else
	BEGIN
	 HVal=EvalIntExpression(ArgStr[2],Int32,&ValOK);
	 if (ValOK)
	  BEGIN
	   HVal-=(EProgCounter()+2); HVal16=HVal;
           if ((NOT IsDisp16(HVal)) AND (NOT SymbolQuestionable)) WrError(1370);
	   else
	    BEGIN
	     CodeLen=4; WAsmCode[0]=0x50c8 | (CondVals[i] << 8);
	     WAsmCode[1]=HVal16;
	     DecodeAdr(ArgStr[1],Mdata);
	     if (AdrNum==1) WAsmCode[0]|=AdrMode;
	     else CodeLen=0;
	    END
	  END
	END
       return;
      END
    END

   if ((strlen(OpPart)<=6) AND (strncmp(OpPart,"TRAP",4)==0)) 
    BEGIN
     if (*AttrPart=='\0') OpSize=0;
     i=(OpSize==0) ? 0 : 1;
     if (OpSize>2) WrError(1130);
     else if (ArgCnt!=i) WrError(1110);
     else
      BEGIN
       i=FindICondition(OpPart+4);
       if ((i==18) OR (i>=CondCnt-2)) WrError(1360);
       else if ((MomCPU==CPUCOLD) AND (i!=1)) WrError(1500);
       else
	BEGIN
	 WAsmCode[0]=0x50f8+(i << 8);
	 if (OpSize==0)
	  BEGIN
	   WAsmCode[0]+=4; CodeLen=2;
	  END
	 else
	  BEGIN
	   DecodeAdr(ArgStr[1],Mimm);
	   if (AdrNum!=0)
	    BEGIN
	     WAsmCode[0]+=OpSize+1;
	     CopyAdrVals(WAsmCode+1); CodeLen=2+AdrCnt;
	    END
	  END
	 CheckCPU(CPUCOLD);
	END
      END
     return;
    END

   /* unbekannter Befehl */

   WrXError(1200,OpPart);
END

	static void InitCode_68K(void)
BEGIN
   SaveInitProc();
   SetFlag(&PMMUAvail,PMMUAvailName,False);
   SetFlag(&FullPMMU,FullPMMUName,True);
END

	static Boolean IsDef_68K(void)
BEGIN
   return False;
END

        static void SwitchFrom_68K(void)
BEGIN
   DeinitFields(); ClearONOFF();
END

	static void SwitchTo_68K(void)
BEGIN
   TurnWords=True; ConstMode=ConstModeMoto; SetIsOccupied=False;

   PCSymbol="*"; HeaderID=0x01; NOPCode=0x4e71;
   DivideChars=","; HasAttrs=True; AttrChars=".";

   ValidSegs=(1<<SegCode);
   Grans[SegCode]=1; ListGrans[SegCode]=2; SegInits[SegCode]=0;
#ifdef __STDC__
   SegLimits[SegCode] = 0xfffffffful;
#else
   SegLimits[SegCode] = 0xffffffffl;
#endif

   MakeCode=MakeCode_68K; IsDef=IsDef_68K;

   SwitchFrom=SwitchFrom_68K; InitFields();
   AddONOFF("PMMU"    , &PMMUAvail , PMMUAvailName, False);
   AddONOFF("FULLPMMU", &FullPMMU  , FullPMMUName , False);
   AddONOFF("FPU"     , &FPUAvail  , FPUAvailName , False);
   AddONOFF("SUPMODE" , &SupAllowed, SupAllowedName,False);
   AddMoto16PseudoONOFF();

   SetFlag(&FullPMMU,FullPMMUName,MomCPU<=CPU68020);
   SetFlag(&DoPadding,DoPaddingName,True);
END

#ifdef DEBSTRCNT
	static void wrstrcnt(void)
BEGIN
   printf("\n%d comps\n",strcnt);
END
#endif

	void code68k_init(void)
BEGIN
   CPU68008=AddCPU("68008",SwitchTo_68K);
   CPU68000=AddCPU("68000",SwitchTo_68K);
   CPU68010=AddCPU("68010",SwitchTo_68K);
   CPU68012=AddCPU("68012",SwitchTo_68K);
   CPUCOLD =AddCPU("MCF5200",SwitchTo_68K);
   CPU68332=AddCPU("68332",SwitchTo_68K);
   CPU68340=AddCPU("68340",SwitchTo_68K);
   CPU68360=AddCPU("68360",SwitchTo_68K);
   CPU68020=AddCPU("68020",SwitchTo_68K);
   CPU68030=AddCPU("68030",SwitchTo_68K);
   CPU68040=AddCPU("68040",SwitchTo_68K);

   SaveInitProc=InitPassProc; InitPassProc=InitCode_68K;
#ifdef DEBSTRCNT
   atexit(wrstrcnt);
#endif
END

