From 333b605b2afd472b823aeda0adf0e8b1ea9843c0 Mon Sep 17 00:00:00 2001 From: fishsoupisgood Date: Mon, 27 May 2019 02:41:51 +0100 Subject: initial commit from asl-1.41r8.tar.gz --- code68k.c | 4428 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 4428 insertions(+) create mode 100644 code68k.c (limited to 'code68k.c') diff --git a/code68k.c b/code68k.c new file mode 100644 index 0000000..260c7d3 --- /dev/null +++ b/code68k.c @@ -0,0 +1,4428 @@ +/* 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, 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 +#include + +#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 (MomCPUCPU68360)) + 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; zName,Asc)==0) break; + if (z>=CtRegCnt) return False; + if ((MomCPUFirstCPU) OR (MomCPU>Reg->LastCPU)) return False; + *Erg=Reg->Code; return True; +END + + static int FindICondition(char *Name) +BEGIN + int i; + + for (i=0; iName=='[') 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 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 ,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, ? */ + 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 ,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 ..., */ + BEGIN + DecodeAdr(ArgStr[1],Mdata+Mimm); + if (AdrNum==11) /* AND #.., */ + 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, ? */ + 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 (MomCPU2)) 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 (MomCPU31) + 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=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 /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 ,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 ,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 ????, ? */ + 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, ? */ + 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, ? */ + 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) 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) 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) 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) 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=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> 16; + CheckSup(); + END + END + END + return; + END; + + if (strncmp(OpPart,"DB",2)==0) + BEGIN + for (z=0; z2) 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<