aboutsummaryrefslogtreecommitdiffstats
path: root/codexa.c
diff options
context:
space:
mode:
Diffstat (limited to 'codexa.c')
-rw-r--r--codexa.c1975
1 files changed, 1975 insertions, 0 deletions
diff --git a/codexa.c b/codexa.c
new file mode 100644
index 0000000..871da67
--- /dev/null
+++ b/codexa.c
@@ -0,0 +1,1975 @@
+/* codexa.c */
+/*****************************************************************************/
+/* AS-Portierung */
+/* */
+/* AS-Codegenerator Philips XA */
+/* */
+/* Historie: 25.10.1996 Grundsteinlegung */
+/* 19. 8.1998 autom. Verlaengerung Spruenge */
+/* 23. 8.1998 Umbau auf Hash-Tabelle */
+/* lange Spruenge fuer JBC */
+/* 24. 8.1998 lange Spruenge fuer DJNZ CJNE */
+/* 25. 8.1998 nach Hashing ueberfluessige Namensfelder entfernt */
+/* 14.10.1998 BRANCHEXT auch fuer BR-Befehle */
+/* Padding-Byte auch fuer Sprung auf sich selber */
+/* Das $ zu verschieben ist aber noch etwas tricky... */
+/* 9. 1.1999 ChkPC jetzt mit Adresse als Parameter */
+/* 20. 1.1999 Formate maschinenunabhaengig gemacht */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+#include <string.h>
+#include <ctype.h>
+
+#include "nls.h"
+#include "strutil.h"
+#include "bpemu.h"
+#include "asmdef.h"
+#include "asmsub.h"
+#include "asmpars.h"
+#include "asmallg.h"
+#include "asmitree.h"
+#include "codepseudo.h"
+#include "codevars.h"
+
+/*-------------------------------------------------------------------------*/
+/* Definitionen */
+
+#define ModNone (-1)
+#define ModReg 0
+#define MModReg (1 << ModReg)
+#define ModMem 1
+#define MModMem (1 << ModMem)
+#define ModImm 2
+#define MModImm (1 << ModImm)
+#define ModAbs 3
+#define MModAbs (1 << ModAbs)
+
+#define FixedOrderCnt 5
+#define JBitOrderCnt 3
+#define RegOrderCnt 4
+#define RotateOrderCount 4
+#define RelOrderCount 17
+#define StackOrderCount 4
+
+typedef struct
+ {
+ Word Code;
+ } FixedOrder;
+
+typedef struct
+ {
+ Byte SizeMask;
+ Byte Code;
+ } RegOrder;
+
+typedef struct
+ {
+ char *Name;
+ Byte SizeMask;
+ Byte Code;
+ Byte Inversion;
+ } InvOrder;
+
+static CPUVar CPUXAG1,CPUXAG2,CPUXAG3;
+
+static FixedOrder *FixedOrders;
+static InvOrder *JBitOrders;
+static FixedOrder *StackOrders;
+static RegOrder *RegOrders;
+static FixedOrder *RotateOrders;
+static InvOrder *RelOrders;
+
+static PInstTable InstTable;
+
+static LongInt Reg_DS;
+static SimpProc SaveInitProc;
+
+static ShortInt AdrMode;
+static Byte AdrPart,MemPart;
+static Byte AdrVals[4];
+static ShortInt OpSize;
+
+/*-------------------------------------------------------------------------*/
+/* Hilfsroutinen */
+
+ static void SetOpSize(ShortInt NSize)
+BEGIN
+ if (OpSize==-1) OpSize=NSize;
+ else if (OpSize!=NSize)
+ BEGIN
+ AdrMode=ModNone; AdrCnt=0; WrError(1131);
+ END
+END
+
+ static Boolean DecodeReg(char *Asc, ShortInt *NSize, Byte *Erg)
+BEGIN
+ if (strcasecmp(Asc,"SP")==0)
+ BEGIN
+ *Erg=7; *NSize=1; return True;
+ END
+ else if ((strlen(Asc)>=2) AND (toupper(*Asc)=='R') AND (Asc[1]>='0') AND (Asc[1]<='7'))
+ if (strlen(Asc)==2)
+ BEGIN
+ *Erg=Asc[1]-'0';
+ if (OpSize==2)
+ BEGIN
+ if ((*Erg&1)==1)
+ BEGIN
+ WrError(1760); (*Erg)--;
+ END
+ *NSize=2;
+ return True;
+ END
+ else
+ BEGIN
+ *NSize=1;
+ return True;
+ END
+ END
+ else if ((strlen(Asc)==3) AND (toupper(Asc[2])=='L'))
+ BEGIN
+ *Erg=(Asc[1]-'0') << 1; *NSize=0; return True;
+ END
+ else if ((strlen(Asc)==3) AND (toupper(Asc[2])=='H'))
+ BEGIN
+ *Erg=((Asc[1]-'0') << 1)+1; *NSize=0; return True;
+ END
+ else return False;
+ return False;
+END
+
+ static void ChkAdr(Word Mask)
+BEGIN
+ if ((AdrMode!=ModNone) AND ((Mask & (1 << AdrMode))==0))
+ BEGIN
+ WrError(1350); AdrMode=ModNone; AdrCnt=0;
+ END
+END
+
+ static void DecodeAdr(char *Asc, Word Mask)
+BEGIN
+ ShortInt NSize;
+ LongInt DispAcc,DispPart,AdrLong;
+ Boolean FirstFlag,NegFlag,NextFlag,ErrFlag,OK;
+ char *PPos,*MPos;
+ Word AdrInt;
+ Byte Reg;
+ String Part;
+
+ AdrMode=ModNone; AdrCnt=0; KillBlanks(Asc);
+
+ if (DecodeReg(Asc,&NSize,&AdrPart))
+ BEGIN
+ if ((Mask & MModReg)!=0)
+ BEGIN
+ AdrMode=ModReg; SetOpSize(NSize);
+ END
+ else
+ BEGIN
+ AdrMode=ModMem; MemPart=1; SetOpSize(NSize);
+ END
+ ChkAdr(Mask); return;
+ END
+
+ if (*Asc=='#')
+ BEGIN
+ switch (OpSize)
+ BEGIN
+ case -4:
+ AdrVals[0]=EvalIntExpression(Asc+1,UInt5,&OK);
+ if (OK)
+ BEGIN
+ AdrCnt=1; AdrMode=ModImm;
+ END
+ break;
+ case -3:
+ AdrVals[0]=EvalIntExpression(Asc+1,SInt4,&OK);
+ if (OK)
+ BEGIN
+ AdrCnt=1; AdrMode=ModImm;
+ END
+ break;
+ case -2:
+ AdrVals[0]=EvalIntExpression(Asc+1,UInt4,&OK);
+ if (OK)
+ BEGIN
+ AdrCnt=1; AdrMode=ModImm;
+ END
+ break;
+ case -1:
+ WrError(1132);
+ break;
+ case 0:
+ AdrVals[0]=EvalIntExpression(Asc+1,Int8,&OK);
+ if (OK)
+ BEGIN
+ AdrCnt=1; AdrMode=ModImm;
+ END
+ break;
+ case 1:
+ AdrInt=EvalIntExpression(Asc+1,Int16,&OK);
+ if (OK)
+ BEGIN
+ AdrVals[0]=Hi(AdrInt); AdrVals[1]=Lo(AdrInt);
+ AdrCnt=2; AdrMode=ModImm;
+ END
+ break;
+ case 2:
+ AdrLong=EvalIntExpression(Asc+1,Int32,&OK);
+ if (OK)
+ BEGIN
+ AdrVals[0]=(AdrLong >> 24) & 0xff;
+ AdrVals[1]=(AdrLong >> 16) & 0xff;
+ AdrVals[2]=(AdrLong >> 8) & 0xff;
+ AdrVals[3]=AdrLong & 0xff;
+ AdrCnt=4; AdrMode=ModImm;
+ END
+ break;
+ END
+ ChkAdr(Mask); return;
+ END
+
+ if ((*Asc=='[') AND (Asc[strlen(Asc)-1]==']'))
+ BEGIN
+ strcpy(Asc,Asc+1); Asc[strlen(Asc)-1]='\0';
+ if (Asc[strlen(Asc)-1]=='+')
+ BEGIN
+ Asc[strlen(Asc)-1]='\0';
+ if (NOT DecodeReg(Asc,&NSize,&AdrPart)) WrXError(1445,Asc);
+ else if (NSize!=1) WrError(1350);
+ else
+ BEGIN
+ AdrMode=ModMem; MemPart=3;
+ END
+ END
+ else
+ BEGIN
+ FirstFlag=False; ErrFlag=False;
+ DispAcc=0; AdrPart=0xff; NegFlag=False;
+ while ((*Asc!='\0') AND (NOT ErrFlag))
+ BEGIN
+ PPos=QuotPos(Asc,'+'); MPos=QuotPos(Asc,'-');
+ if (PPos==Nil) PPos=MPos;
+ else if ((MPos!=Nil) AND (PPos>MPos)) PPos=MPos;
+ NextFlag=((PPos!=Nil) AND (*PPos=='-'));
+ if (PPos==Nil)
+ BEGIN
+ strmaxcpy(Part,Asc,255); *Asc='\0';
+ END
+ else
+ BEGIN
+ *PPos='\0'; strmaxcpy(Part,Asc,255); strcpy(Asc,PPos+1);
+ END
+ if (DecodeReg(Part,&NSize,&Reg))
+ if ((NSize!=1) OR (AdrPart!=0xff) OR (NegFlag))
+ BEGIN
+ WrError(1350); ErrFlag=True;
+ END
+ else AdrPart=Reg;
+ else
+ BEGIN
+ FirstPassUnknown=False;
+ DispPart=EvalIntExpression(Part,Int32,&ErrFlag);
+ ErrFlag=NOT ErrFlag;
+ if (NOT ErrFlag)
+ BEGIN
+ FirstFlag=FirstFlag OR FirstPassUnknown;
+ if (NegFlag) DispAcc-=DispPart;
+ else DispAcc+=DispPart;
+ END
+ END
+ NegFlag=NextFlag;
+ END
+ if (FirstFlag) DispAcc&=0x7fff;
+ if (AdrPart==0xff) WrError(1350);
+ else if (DispAcc==0)
+ BEGIN
+ AdrMode=ModMem; MemPart=2;
+ END
+ else if ((DispAcc>=-128) AND (DispAcc<127))
+ BEGIN
+ AdrMode=ModMem; MemPart=4;
+ AdrVals[0]=DispAcc & 0xff; AdrCnt=1;
+ END
+ else if (ChkRange(DispAcc,-0x8000l,0x7fffl))
+ BEGIN
+ AdrMode=ModMem; MemPart=5;
+ AdrVals[0]=(DispAcc >> 8) & 0xff;
+ AdrVals[1]=DispAcc & 0xff;
+ AdrCnt=2;
+ END
+ END
+ ChkAdr(Mask); return;
+ END
+
+ FirstPassUnknown=False;
+ AdrLong=EvalIntExpression(Asc,UInt24,&OK);
+ if (OK)
+ BEGIN
+ if (FirstPassUnknown)
+ BEGIN
+ if ((Mask & MModAbs)==0) AdrLong&=0x3ff;
+ END
+ if ((AdrLong & 0xffff)>0x7ff) WrError(1925);
+ else if ((AdrLong & 0xffff)<=0x3ff)
+ BEGIN
+ if ((AdrLong >> 16)!=Reg_DS) WrError(110);
+ ChkSpace(SegData);
+ AdrMode=ModMem; MemPart=6;
+ AdrPart=Hi(AdrLong); AdrVals[0]=Lo(AdrLong);
+ AdrCnt=1;
+ END
+ else if (AdrLong>0x7ff) WrError(1925);
+ else
+ BEGIN
+ ChkSpace(SegIO);
+ AdrMode=ModMem; MemPart=6;
+ AdrPart=Hi(AdrLong); AdrVals[0]=Lo(AdrLong);
+ AdrCnt=1;
+ END
+ END
+
+ ChkAdr(Mask);
+END
+
+ static Boolean DecodeBitAddr(char *Asc, LongInt *Erg)
+BEGIN
+ char *p;
+ Byte BPos,Reg;
+ ShortInt Size,Res;
+ LongInt AdrLong;
+ Boolean OK;
+
+ p=RQuotPos(Asc,'.'); Res=0;
+ if (p==Nil)
+ BEGIN
+ FirstPassUnknown=False;
+ AdrLong=EvalIntExpression(Asc,UInt24,&OK);
+ if (FirstPassUnknown) AdrLong&=0x3ff;
+ *Erg=AdrLong; Res=1;
+ END
+ else
+ BEGIN
+ FirstPassUnknown=False; *p='\0';
+ BPos=EvalIntExpression(p+1,UInt4,&OK);
+ if (FirstPassUnknown) BPos&=7;
+ if (OK)
+ BEGIN
+ if (DecodeReg(Asc,&Size,&Reg))
+ if ((Size==0) AND (BPos>7)) WrError(1320);
+ else
+ BEGIN
+ if (Size==0) *Erg=(Reg << 3)+BPos;
+ else *Erg=(Reg << 4)+BPos;
+ Res=1;
+ END
+ else if (BPos>7) WrError(1320);
+ else
+ BEGIN
+ FirstPassUnknown=False;
+ AdrLong=EvalIntExpression(Asc,UInt24,&OK);
+ if ((TypeFlag & (1 << SegIO))!=0)
+ BEGIN
+ ChkSpace(SegIO);
+ if (FirstPassUnknown) AdrLong=(AdrLong & 0x3f) | 0x400;
+ if (ChkRange(AdrLong,0x400,0x43f))
+ BEGIN
+ *Erg=0x200+((AdrLong & 0x3f) << 3)+BPos;
+ Res=1;
+ END
+ else Res=(-1);
+ END
+ else
+ BEGIN
+ ChkSpace(SegData);
+ if (FirstPassUnknown) AdrLong=(AdrLong & 0x00ff003f) | 0x20;
+ if (ChkRange(AdrLong & 0xff,0x20,0x3f))
+ BEGIN
+ *Erg=0x100+((AdrLong & 0x1f) << 3)+BPos+(AdrLong & 0xff0000);
+ Res=1;
+ END
+ else Res=(-1);
+ END
+ END
+ END
+ *p='.';
+ END
+ if (Res==0) WrError(1350);
+ return (Res==1);
+END
+
+ static void ChkBitPage(LongInt Adr)
+BEGIN
+ if ((Adr >> 16)!=Reg_DS) WrError(110);
+END
+
+/*-------------------------------------------------------------------------*/
+/* Befehlsdekoder */
+
+ static Boolean DecodePseudo(void)
+BEGIN
+#define ASSUMEXACount 1
+static ASSUMERec ASSUMEXAs[ASSUMEXACount]=
+ {{"DS", &Reg_DS, 0, 0xff, 0x100}};
+ LongInt BAdr;
+
+ if (Memo("PORT"))
+ BEGIN
+ CodeEquate(SegIO,0x400,0x7ff);
+ return True;
+ END
+
+ if (Memo("BIT"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (*AttrPart!='\0') WrError(1100);
+ else if (DecodeBitAddr(ArgStr[1],&BAdr))
+ BEGIN
+ EnterIntSymbol(LabPart,BAdr,SegNone,False);
+ switch ((BAdr & 0x3ff) >> 8)
+ BEGIN
+ case 0:
+ sprintf(ListLine,"=R%d.%d", (int)((BAdr >> 4) & 15),
+ (int) (BAdr & 15));
+ break;
+ case 1:
+ sprintf(ListLine,"=%x:%x.%d",(int)((BAdr >> 16) & 255),
+ (int)((BAdr & 0x1f8) >> 3), (int)(BAdr & 7));
+ break;
+ default:
+ sprintf(ListLine, "=S:%x.%d", (int)(((BAdr >> 3) & 0x3f)+0x400),
+ (int)(BAdr & 7));
+ break;
+ END
+ END
+ return True;
+ END
+
+ if (Memo("ASSUME"))
+ BEGIN
+ CodeASSUME(ASSUMEXAs,ASSUMEXACount);
+ return True;
+ END
+
+ return False;
+END
+
+ static void DecodeFixed(Word Index)
+BEGIN
+ FixedOrder *Op=FixedOrders+Index;
+
+ if (ArgCnt!=0) WrError(1110);
+ else
+ BEGIN
+ if (Hi(Op->Code)!=0) BAsmCode[CodeLen++]=Hi(Op->Code);
+ BAsmCode[CodeLen++]=Lo(Op->Code);
+ if ((Memo("RETI")) AND (NOT SupAllowed)) WrError(50);
+ END
+END
+
+ static void DecodeStack(Word Index)
+BEGIN
+ FixedOrder *Op=StackOrders+Index;
+ Byte HReg;
+ Boolean OK;
+ Word Mask;
+ int i;
+
+ if (ArgCnt<1) WrError(1110);
+ else
+ BEGIN
+ HReg=0xff; OK=True; Mask=0;
+ for (i=1; i<=ArgCnt; i++)
+ if (OK)
+ BEGIN
+ DecodeAdr(ArgStr[i],MModMem);
+ if (AdrMode==ModNone) OK=False;
+ else switch (MemPart)
+ BEGIN
+ case 1:
+ if (HReg==0)
+ BEGIN
+ WrError(1350); OK=False;
+ END
+ else
+ BEGIN
+ HReg=1; Mask|=(1 << AdrPart);
+ END
+ break;
+ case 6:
+ if (HReg!=0xff)
+ BEGIN
+ WrError(1350); OK=False;
+ END
+ else HReg=0;
+ break;
+ default:
+ WrError(1350); OK=False;
+ END
+ END
+ if (OK)
+ if (OpSize==-1) WrError(1132);
+ else if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
+ else if (HReg==0)
+ BEGIN
+ BAsmCode[CodeLen++]=0x87+(OpSize << 3);
+ BAsmCode[CodeLen++]=Hi(Op->Code)+AdrPart;
+ BAsmCode[CodeLen++]=AdrVals[0];
+ END
+ else if (Index<2) /* POP: obere Register zuerst */
+ BEGIN
+ if (Hi(Mask)!=0)
+ BEGIN
+ BAsmCode[CodeLen++]=Lo(Op->Code)+(OpSize << 3)+0x40;
+ BAsmCode[CodeLen++]=Hi(Mask);
+ END
+ if (Lo(Mask)!=0)
+ BEGIN
+ BAsmCode[CodeLen++]=Lo(Op->Code)+(OpSize << 3);
+ BAsmCode[CodeLen++]=Lo(Mask);
+ END
+ if ((OpSize==1) AND (Memo("POP")) AND ((Mask & 0x80)!=0)) WrError(140);
+ END
+ else /* PUSH: untere Register zuerst */
+ BEGIN
+ if (Lo(Mask)!=0)
+ BEGIN
+ BAsmCode[CodeLen++]=Lo(Op->Code)+(OpSize << 3);
+ BAsmCode[CodeLen++]=Lo(Mask);
+ END
+ if (Hi(Mask)!=0)
+ BEGIN
+ BAsmCode[CodeLen++]=Lo(Op->Code)+(OpSize << 3)+0x40;
+ BAsmCode[CodeLen++]=Hi(Mask);
+ END
+ END
+ END
+END
+
+ static void DecodeALU(Word Index)
+BEGIN
+ Byte HReg,HCnt,HVals[3],HMem;
+
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg+MModMem);
+ switch (AdrMode)
+ BEGIN
+ case ModReg:
+ if (OpSize>=2) WrError(1130);
+ else if (OpSize==-1) WrError(1132);
+ else
+ BEGIN
+ HReg=AdrPart;
+ DecodeAdr(ArgStr[2],MModMem+MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModMem:
+ BAsmCode[CodeLen++]=(Index << 4)+(OpSize << 3)+MemPart;
+ BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
+ memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
+ CodeLen+=AdrCnt;
+ if ((MemPart==3) AND ((HReg >> (1-OpSize))==AdrPart)) WrError(140);
+ break;
+ case ModImm:
+ BAsmCode[CodeLen++]=0x91+(OpSize << 3);
+ BAsmCode[CodeLen++]=(HReg << 4)+Index;
+ memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
+ CodeLen+=AdrCnt;
+ break;
+ END
+ END
+ break;
+ case ModMem:
+ HReg=AdrPart; HMem=MemPart; HCnt=AdrCnt;
+ memcpy(HVals,AdrVals,AdrCnt);
+ DecodeAdr(ArgStr[2],MModReg+MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModReg:
+ if (OpSize==2) WrError(1130);
+ else if (OpSize==-1) WrError(1132);
+ else
+ BEGIN
+ BAsmCode[CodeLen++]=(Index << 4)+(OpSize << 3)+HMem;
+ BAsmCode[CodeLen++]=(AdrPart << 4)+8+HReg;
+ memcpy(BAsmCode+CodeLen,HVals,HCnt);
+ CodeLen+=HCnt;
+ if ((HMem==3) AND ((AdrPart >> (1-OpSize))==HReg)) WrError(140);
+ END
+ break;
+ case ModImm:
+ if (OpSize==2) WrError(1130);
+ else if (OpSize==-1) WrError(1132);
+ else
+ BEGIN
+ BAsmCode[CodeLen++]=0x90+HMem+(OpSize << 3);
+ BAsmCode[CodeLen++]=(HReg << 4)+Index;
+ memcpy(BAsmCode+CodeLen,HVals,HCnt);
+ memcpy(BAsmCode+CodeLen+HCnt,AdrVals,AdrCnt);
+ CodeLen+=AdrCnt+HCnt;
+ END
+ break;
+ END
+ break;
+ END
+ END
+END
+
+ static void DecodeRegO(Word Index)
+BEGIN
+ RegOrder *Op=RegOrders+Index;
+
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg);
+ switch (AdrMode)
+ BEGIN
+ case ModReg:
+ if ((Op->SizeMask & (1 << OpSize))==0) WrError(1130);
+ else
+ BEGIN
+ BAsmCode[CodeLen++]=0x90+(OpSize << 3);
+ BAsmCode[CodeLen++]=(AdrPart << 4)+Op->Code;
+ END
+ break;
+ END
+ END
+END
+
+ static void DecodeShift(Word Index)
+BEGIN
+ Byte HReg,HMem;
+
+ if (ArgCnt!=2) WrError(1110);
+ else if (OpSize>2) WrError(1130);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg);
+ switch (AdrMode)
+ BEGIN
+ case ModReg:
+ HReg=AdrPart; HMem=OpSize;
+ if (*ArgStr[2]=='#') OpSize=(HMem==2)?-4:-2;
+ else OpSize=0;
+ DecodeAdr(ArgStr[2],MModReg+((Index==3)?0:MModImm));
+ switch (AdrMode)
+ BEGIN
+ case ModReg:
+ BAsmCode[CodeLen++]=0xc0+((HMem & 1) << 3)+Index;
+ if (HMem==2) BAsmCode[CodeLen-1]+=12;
+ BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
+ if (Memo("NORM"))
+ if (HMem==2)
+ BEGIN
+ if ((AdrPart >> 2)==(HReg >> 1)) WrError(140);
+ END
+ else if ((AdrPart >> HMem)==HReg) WrError(140);
+ break;
+ case ModImm:
+ BAsmCode[CodeLen++]=0xd0+((HMem & 1) << 3)+Index;
+ if (HMem==2)
+ BEGIN
+ BAsmCode[CodeLen-1]+=12;
+ BAsmCode[CodeLen++]=((HReg & 14) << 4)+AdrVals[0];
+ END
+ else BAsmCode[CodeLen++]=(HReg << 4)+AdrVals[0];
+ break;
+ END
+ break;
+ END
+ END
+END
+
+ static void DecodeRotate(Word Index)
+BEGIN
+ FixedOrder *Op=RotateOrders+Index;
+ Byte HReg,HMem;
+
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg);
+ switch (AdrMode)
+ BEGIN
+ case ModReg:
+ if (OpSize==2) WrError(1130);
+ else
+ BEGIN
+ HReg=AdrPart; HMem=OpSize; OpSize=(-2);
+ DecodeAdr(ArgStr[2],MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModImm:
+ BAsmCode[CodeLen++]=Op->Code+(HMem << 3);
+ BAsmCode[CodeLen++]=(HReg << 4)+AdrVals[0];
+ break;
+ END
+ END
+ break;
+ END
+ END
+END
+
+ static void DecodeRel(Word Index)
+BEGIN
+ InvOrder *Op=RelOrders+Index;
+ Boolean OK;
+ LongInt SaveLong,AdrLong;
+
+ if (ArgCnt!=1) WrError(1110);
+ else if (*AttrPart!='\0') WrError(1100);
+ else
+ BEGIN
+ FirstPassUnknown=True;
+ AdrLong=SaveLong=EvalIntExpression(ArgStr[1],UInt24,&OK);
+ if (OK)
+ BEGIN
+ ChkSpace(SegCode);
+#ifdef __STDC__
+ if (FirstPassUnknown) AdrLong&=0xfffffffeu;
+#else
+ if (FirstPassUnknown) AdrLong&=0xfffffffe;
+#endif
+ AdrLong-=(EProgCounter()+CodeLen+2) & 0xfffffe;
+ if ((AdrLong&1)==1) WrError(1325);
+ else if ((SymbolQuestionable) OR ((AdrLong<=254) AND (AdrLong>=-256)))
+ BEGIN
+ BAsmCode[CodeLen++]=Op->Code;
+ BAsmCode[CodeLen++]=(AdrLong >> 1) & 0xff;
+ END
+ else if (NOT DoBranchExt) WrError(1370);
+ else if (Op->Inversion==255) /* BR */
+ BEGIN
+ AdrLong=SaveLong-((EProgCounter()+CodeLen+3) & 0xfffffe);
+ if ((NOT SymbolQuestionable) AND ((AdrLong>65534) OR (AdrLong<-65536))) WrError(1370);
+ else if ((AdrLong&1)==1) WrError(1325);
+ else
+ BEGIN
+ AdrLong>>=1;
+ BAsmCode[CodeLen++]=0xd5;
+ BAsmCode[CodeLen++]=(AdrLong >> 8) & 0xff;
+ BAsmCode[CodeLen++]=AdrLong & 0xff;
+ END
+ END
+ else
+ BEGIN
+ AdrLong=SaveLong-((EProgCounter()+CodeLen+5) & 0xfffffe);
+ if ((AdrLong>65534) OR (AdrLong<-65536)) WrError(1370);
+ else
+ BEGIN
+ BAsmCode[CodeLen++]=RelOrders[Op->Inversion].Code;
+ BAsmCode[CodeLen++]=2;
+ BAsmCode[CodeLen++]=0xd5;
+ BAsmCode[CodeLen++]=(AdrLong>>9)&0xff;
+ BAsmCode[CodeLen++]=(AdrLong>>1)&0xff;
+ if (Odd(EProgCounter()+CodeLen)) BAsmCode[CodeLen++]=0;
+ END
+ END
+ END
+ END
+END
+
+ static void DecodeJBit(Word Index)
+BEGIN
+ LongInt BitAdr,AdrLong,SaveLong,odd;
+ Boolean OK;
+ InvOrder *Op=JBitOrders+Index;
+
+ if (ArgCnt!=2) WrError(1110);
+ else if (*AttrPart!='\0') WrError(1100);
+ else if (DecodeBitAddr(ArgStr[1],&BitAdr))
+ BEGIN
+ FirstPassUnknown=False;
+ AdrLong=SaveLong=EvalIntExpression(ArgStr[2],UInt24,&OK);
+ if (OK)
+ BEGIN
+#ifdef __STDC__
+ if (FirstPassUnknown) AdrLong&=0xfffffffeu;
+#else
+ if (FirstPassUnknown) AdrLong&=0xfffffffe;
+#endif
+ AdrLong-=(EProgCounter()+CodeLen+4) & 0xfffffe;
+ if ((AdrLong&1)==1) WrError(1325);
+ else if ((SymbolQuestionable) OR ((AdrLong<=254) AND (AdrLong>=-256)))
+ BEGIN
+ BAsmCode[CodeLen++]=0x97;
+ BAsmCode[CodeLen++]=Op->Code+Hi(BitAdr);
+ BAsmCode[CodeLen++]=Lo(BitAdr);
+ BAsmCode[CodeLen++]=(AdrLong >> 1) & 0xff;
+ END
+ else if (NOT DoBranchExt) WrError(1370);
+ else if (Op->Inversion==255)
+ BEGIN
+ odd=EProgCounter()&1;
+ AdrLong=SaveLong-((EProgCounter()+CodeLen+9+odd) & 0xfffffe);
+ if ((AdrLong>65534) OR (AdrLong<-65536)) WrError(1370);
+ else
+ BEGIN
+ BAsmCode[CodeLen++]=0x97;
+ BAsmCode[CodeLen++]=Op->Code+Hi(BitAdr);
+ BAsmCode[CodeLen++]=Lo(BitAdr);
+ BAsmCode[CodeLen++]=1+odd;
+ BAsmCode[CodeLen++]=0xfe;
+ BAsmCode[CodeLen++]=2+odd;
+ if (odd) BAsmCode[CodeLen++]=0;
+ BAsmCode[CodeLen++]=0xd5;
+ BAsmCode[CodeLen++]=(AdrLong>>9)&0xff;
+ BAsmCode[CodeLen++]=(AdrLong>>1)&0xff;
+ BAsmCode[CodeLen++]=0;
+ END
+ END
+ else
+ BEGIN
+ AdrLong=SaveLong-((EProgCounter()+CodeLen+7) & 0xfffffe);
+ if ((AdrLong>65534) OR (AdrLong<-65536)) WrError(1370);
+ else
+ BEGIN
+ BAsmCode[CodeLen++]=0x97;
+ BAsmCode[CodeLen++]=JBitOrders[Op->Inversion].Code+Hi(BitAdr);
+ BAsmCode[CodeLen++]=Lo(BitAdr);
+ BAsmCode[CodeLen++]=2;
+ BAsmCode[CodeLen++]=0xd5;
+ BAsmCode[CodeLen++]=(AdrLong>>9)&0xff;
+ BAsmCode[CodeLen++]=(AdrLong>>1)&0xff;
+ if (Odd(EProgCounter()+CodeLen)) BAsmCode[CodeLen++]=0;
+ END
+ END
+ END
+ END
+END
+
+
+ static void DecodeMOV(Word Index)
+BEGIN
+ LongInt AdrLong;
+ Byte HVals[3],HReg,HPart,HCnt;
+
+ if (ArgCnt!=2) WrError(1110);
+ else if (strcasecmp(ArgStr[1],"C")==0)
+ BEGIN
+ if (DecodeBitAddr(ArgStr[2],&AdrLong))
+ if (*AttrPart!='\0') WrError(1100);
+ else
+ BEGIN
+ ChkBitPage(AdrLong);
+ BAsmCode[CodeLen++]=0x08;
+ BAsmCode[CodeLen++]=0x20+Hi(AdrLong);
+ BAsmCode[CodeLen++]=Lo(AdrLong);
+ END
+ END
+ else if (strcasecmp(ArgStr[2],"C")==0)
+ BEGIN
+ if (DecodeBitAddr(ArgStr[1],&AdrLong))
+ if (*AttrPart!='\0') WrError(1100);
+ else
+ BEGIN
+ ChkBitPage(AdrLong);
+ BAsmCode[CodeLen++]=0x08;
+ BAsmCode[CodeLen++]=0x30+Hi(AdrLong);
+ BAsmCode[CodeLen++]=Lo(AdrLong);
+ END
+ END
+ else if (strcasecmp(ArgStr[1],"USP")==0)
+ BEGIN
+ SetOpSize(1);
+ DecodeAdr(ArgStr[2],MModReg);
+ if (AdrMode==ModReg)
+ BEGIN
+ BAsmCode[CodeLen++]=0x98;
+ BAsmCode[CodeLen++]=(AdrPart << 4)+0x0f;
+ END
+ END
+ else if (strcasecmp(ArgStr[2],"USP")==0)
+ BEGIN
+ SetOpSize(1);
+ DecodeAdr(ArgStr[1],MModReg);
+ if (AdrMode==ModReg)
+ BEGIN
+ BAsmCode[CodeLen++]=0x90;
+ BAsmCode[CodeLen++]=(AdrPart << 4)+0x0f;
+ END
+ END
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg+MModMem);
+ switch (AdrMode)
+ BEGIN
+ case ModReg:
+ if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
+ else
+ BEGIN
+ HReg=AdrPart;
+ DecodeAdr(ArgStr[2],MModMem+MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModMem:
+ BAsmCode[CodeLen++]=0x80+(OpSize << 3)+MemPart;
+ BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
+ memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
+ CodeLen+=AdrCnt;
+ if ((MemPart==3) AND ((HReg >> (1-OpSize))==AdrPart)) WrError(140);
+ break;
+ case ModImm:
+ BAsmCode[CodeLen++]=0x91+(OpSize << 3);
+ BAsmCode[CodeLen++]=0x08+(HReg << 4);
+ memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
+ CodeLen+=AdrCnt;
+ break;
+ END
+ END
+ break;
+ case ModMem:
+ memcpy(HVals,AdrVals,AdrCnt); HCnt=AdrCnt; HPart=MemPart; HReg=AdrPart;
+ DecodeAdr(ArgStr[2],MModReg+MModMem+MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModReg:
+ if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
+ else
+ BEGIN
+ BAsmCode[CodeLen++]=0x80+(OpSize << 3)+HPart;
+ BAsmCode[CodeLen++]=(AdrPart << 4)+0x08+HReg;
+ memcpy(BAsmCode+CodeLen,HVals,HCnt);
+ CodeLen+=HCnt;
+ if ((HPart==3) AND ((AdrPart >> (1-OpSize))==HReg)) WrError(140);
+ END
+ break;
+ case ModMem:
+ if (OpSize==-1) WrError(1132);
+ else if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
+ else if ((HPart==6) AND (MemPart==6))
+ BEGIN
+ BAsmCode[CodeLen++]=0x97+(OpSize << 3);
+ BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
+ BAsmCode[CodeLen++]=HVals[0];
+ BAsmCode[CodeLen++]=AdrVals[0];
+ END
+ else if ((HPart==6) AND (MemPart==2))
+ BEGIN
+ BAsmCode[CodeLen++]=0xa0+(OpSize << 3);
+ BAsmCode[CodeLen++]=0x80+(AdrPart << 4)+HReg;
+ BAsmCode[CodeLen++]=HVals[0];
+ END
+ else if ((HPart==2) AND (MemPart==6))
+ BEGIN
+ BAsmCode[CodeLen++]=0xa0+(OpSize << 3);
+ BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
+ BAsmCode[CodeLen++]=AdrVals[0];
+ END
+ else if ((HPart==3) AND (MemPart==3))
+ BEGIN
+ BAsmCode[CodeLen++]=0x90+(OpSize << 3);
+ BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
+ if (HReg==AdrPart) WrError(140);
+ END
+ else WrError(1350);
+ break;
+ case ModImm:
+ if (OpSize==-1) WrError(1132);
+ else if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
+ else
+ BEGIN
+ BAsmCode[CodeLen++]=0x90+(OpSize << 3)+HPart;
+ BAsmCode[CodeLen++]=0x08+(HReg << 4);
+ memcpy(BAsmCode+CodeLen,HVals,HCnt);
+ memcpy(BAsmCode+CodeLen+HCnt,AdrVals,AdrCnt);
+ CodeLen+=HCnt+AdrCnt;
+ END
+ break;
+ END
+ break;
+ END
+ END
+END
+
+ static void DecodeMOVC(Word Index)
+BEGIN
+ Byte HReg;
+
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ if ((*AttrPart=='\0') AND (strcasecmp(ArgStr[1],"A")==0)) OpSize=0;
+ if (strcasecmp(ArgStr[2],"[A+DPTR]")==0)
+ if (strcasecmp(ArgStr[1],"A")!=0) WrError(1350);
+ else if (OpSize!=0) WrError(1130);
+ else
+ BEGIN
+ BAsmCode[CodeLen++]=0x90;
+ BAsmCode[CodeLen++]=0x4e;
+ END
+ else if (strcasecmp(ArgStr[2],"[A+PC]")==0)
+ if (strcasecmp(ArgStr[1],"A")!=0) WrError(1350);
+ else if (OpSize!=0) WrError(1130);
+ else
+ BEGIN
+ BAsmCode[CodeLen++]=0x90;
+ BAsmCode[CodeLen++]=0x4c;
+ END
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg);
+ if (AdrMode!=ModNone)
+ if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
+ else
+ BEGIN
+ HReg=AdrPart;
+ DecodeAdr(ArgStr[2],MModMem);
+ if (AdrMode!=ModNone)
+ if (MemPart!=3) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[CodeLen++]=0x80+(OpSize << 3);
+ BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
+ if ((MemPart==3) AND ((HReg >> (1-OpSize))==AdrPart)) WrError(140);
+ END
+ END
+ END
+ END
+END
+
+ static void DecodeMOVX(Word Index)
+BEGIN
+ Byte HReg;
+
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModMem);
+ if (AdrMode==ModMem)
+ switch (MemPart)
+ BEGIN
+ case 1:
+ if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
+ else
+ BEGIN
+ HReg=AdrPart; DecodeAdr(ArgStr[2],MModMem);
+ if (AdrMode==ModMem)
+ if (MemPart!=2) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[CodeLen++]=0xa7+(OpSize << 3);
+ BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
+ END
+ END
+ break;
+ case 2:
+ HReg=AdrPart; DecodeAdr(ArgStr[2],MModReg);
+ if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
+ else
+ BEGIN
+ BAsmCode[CodeLen++]=0xa7+(OpSize << 3);
+ BAsmCode[CodeLen++]=0x08+(AdrPart << 4)+HReg;
+ END
+ break;
+ default:
+ WrError(1350);
+ END
+ END
+END
+
+ static void DecodeXCH(Word Index)
+BEGIN
+ Byte HReg,HPart,HVals[3];
+
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModMem);
+ if (AdrMode==ModMem)
+ switch (MemPart)
+ BEGIN
+ case 1:
+ HReg=AdrPart; DecodeAdr(ArgStr[2],MModMem);
+ if (AdrMode==ModMem)
+ if ((OpSize!=1) AND (OpSize!=0)) WrError(1130);
+ else switch (MemPart)
+ BEGIN
+ case 1:
+ BAsmCode[CodeLen++]=0x60+(OpSize << 3);
+ BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
+ if (HReg==AdrPart) WrError(140);
+ break;
+ case 2:
+ BAsmCode[CodeLen++]=0x50+(OpSize << 3);
+ BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
+ break;
+ case 6:
+ BAsmCode[CodeLen++]=0xa0+(OpSize << 3);
+ BAsmCode[CodeLen++]=0x08+(HReg << 4)+AdrPart;
+ BAsmCode[CodeLen++]=AdrVals[0];
+ break;
+ default:
+ WrError(1350);
+ END
+ break;
+ case 2:
+ HReg=AdrPart;
+ DecodeAdr(ArgStr[2],MModReg);
+ if (AdrMode==ModReg)
+ if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
+ else
+ BEGIN
+ BAsmCode[CodeLen++]=0x50+(OpSize << 3);
+ BAsmCode[CodeLen++]=(AdrPart << 4)+HReg;
+ END
+ break;
+ case 6:
+ HPart=AdrPart; HVals[0]=AdrVals[0];
+ DecodeAdr(ArgStr[2],MModReg);
+ if (AdrMode==ModReg)
+ if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
+ else
+ BEGIN
+ BAsmCode[CodeLen++]=0xa0+(OpSize << 3);
+ BAsmCode[CodeLen++]=0x08+(AdrPart << 4)+HPart;
+ BAsmCode[CodeLen++]=HVals[0];
+ END
+ break;
+ default:
+ WrError(1350);
+ END
+ END
+END
+
+ static void DecodeADDSMOVS(Word Index)
+BEGIN
+ Byte HReg,HMem;
+
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ HMem=OpSize; OpSize=(-3);
+ DecodeAdr(ArgStr[2],MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModImm:
+ HReg=AdrVals[0]; OpSize=HMem;
+ DecodeAdr(ArgStr[1],MModMem);
+ switch (AdrMode)
+ BEGIN
+ case ModMem:
+ if (OpSize==2) WrError(1130);
+ else if (OpSize==-1) WrError(1132);
+ else
+ BEGIN
+ BAsmCode[CodeLen++]=0xa0+(Index << 4)+(OpSize << 3)+MemPart;
+ BAsmCode[CodeLen++]=(AdrPart << 4)+(HReg & 0x0f);
+ memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
+ CodeLen+=AdrCnt;
+ END
+ break;
+ END
+ break;
+ END
+ END
+END
+
+ static void DecodeDIV(Word Index)
+BEGIN
+ Byte HReg;
+
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg);
+ if (AdrMode==ModReg)
+ if ((OpSize!=1) AND (OpSize!=2)) WrError(1130);
+ else
+ BEGIN
+ HReg=AdrPart; OpSize--; DecodeAdr(ArgStr[2],MModReg+MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModReg:
+ BAsmCode[CodeLen++]=0xe7+(OpSize << 3);
+ BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
+ break;
+ case ModImm:
+ BAsmCode[CodeLen++]=0xe8+OpSize;
+ BAsmCode[CodeLen++]=(HReg << 4)+0x0b-(OpSize << 1);
+ memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
+ CodeLen+=AdrCnt;
+ break;
+ END
+ END
+ END
+END
+
+ static void DecodeDIVU(Word Index)
+BEGIN
+ Byte HReg;
+ int z;
+
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg);
+ if (AdrMode==ModReg)
+ if ((OpSize==0) AND ((AdrPart&1)==1)) WrError(1445);
+ else
+ BEGIN
+ HReg=AdrPart; z=OpSize; if (OpSize!=0) OpSize--;
+ DecodeAdr(ArgStr[2],MModReg+MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModReg:
+ BAsmCode[CodeLen++]=0xe1+(z << 2);
+ if (z==2) BAsmCode[CodeLen-1]+=4;
+ BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
+ break;
+ case ModImm:
+ BAsmCode[CodeLen++]=0xe8+Ord(z==2);
+ BAsmCode[CodeLen++]=(HReg << 4)+0x01+(Ord(z==1) << 1);
+ memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
+ CodeLen+=AdrCnt;
+ break;
+ END
+ END
+ END
+END
+
+ static void DecodeMUL(Word Index)
+BEGIN
+ Byte HReg;
+
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg);
+ if (AdrMode==ModReg)
+ if (OpSize!=1) WrError(1130);
+ else if ((AdrPart&1)==1) WrError(1445);
+ else
+ BEGIN
+ HReg=AdrPart; DecodeAdr(ArgStr[2],MModReg+MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModReg:
+ BAsmCode[CodeLen++]=0xe6;
+ BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
+ break;
+ case ModImm:
+ BAsmCode[CodeLen++]=0xe9;
+ BAsmCode[CodeLen++]=(HReg << 4)+0x08;
+ memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
+ CodeLen+=AdrCnt;
+ break;
+ END
+ END
+ END
+END
+
+ static void DecodeMULU(Word Index)
+BEGIN
+ Byte HReg;
+
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg);
+ if (AdrMode==ModReg)
+ if ((AdrPart&1)==1) WrError(1445);
+ else
+ BEGIN
+ HReg=AdrPart;
+ DecodeAdr(ArgStr[2],MModReg+MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModReg:
+ BAsmCode[CodeLen++]=0xe0+(OpSize << 2);
+ BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
+ break;
+ case ModImm:
+ BAsmCode[CodeLen++]=0xe8+OpSize;
+ BAsmCode[CodeLen++]=(HReg << 4);
+ memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
+ CodeLen+=AdrCnt;
+ break;
+ END
+ END
+ END
+END
+
+ static void DecodeLEA(Word Index)
+BEGIN
+ Byte HReg;
+
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg);
+ if (AdrMode==ModReg)
+ if (OpSize!=1) WrError(1130);
+ else
+ BEGIN
+ HReg=AdrPart;
+ strmaxprep(ArgStr[2],"[",255); strmaxcat(ArgStr[2],"]",255);
+ DecodeAdr(ArgStr[2],MModMem);
+ if (AdrMode==ModMem)
+ switch (MemPart)
+ BEGIN
+ case 4:
+ case 5:
+ BAsmCode[CodeLen++]=0x20+(MemPart << 3);
+ BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
+ memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
+ CodeLen+=AdrCnt;
+ break;
+ default:
+ WrError(1350);
+ END
+ END
+ END
+END
+
+ static void DecodeANLORL(Word Index)
+BEGIN
+ LongInt AdrLong;
+ Boolean OK;
+
+ if (ArgCnt!=2) WrError(1110);
+ else if (*AttrPart!='\0') WrError(1100);
+ else if (strcasecmp(ArgStr[1],"C")!=0) WrError(1350);
+ else
+ BEGIN
+ if (*ArgStr[2]=='/')
+ BEGIN
+ OK=True; strcpy(ArgStr[2],ArgStr[2]+1);
+ END
+ else OK=False;
+ if (DecodeBitAddr(ArgStr[2],&AdrLong))
+ BEGIN
+ ChkBitPage(AdrLong);
+ BAsmCode[CodeLen++]=0x08;
+ BAsmCode[CodeLen++]=0x40+(Index << 5)+(Ord(OK) << 4)+(Hi(AdrLong) & 3);
+ BAsmCode[CodeLen++]=Lo(AdrLong);
+ END
+ END
+END
+
+ static void DecodeCLRSETB(Word Index)
+BEGIN
+ LongInt AdrLong;
+
+ if (ArgCnt!=1) WrError(1110);
+ else if (*AttrPart!='\0') WrError(1100);
+ else if (DecodeBitAddr(ArgStr[1],&AdrLong))
+ BEGIN
+ ChkBitPage(AdrLong);
+ BAsmCode[CodeLen++]=0x08;
+ BAsmCode[CodeLen++]=(Index << 4)+(Hi(AdrLong) & 3);
+ BAsmCode[CodeLen++]=Lo(AdrLong);
+ END
+END
+
+ static void DecodeTRAP(Word Index)
+BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (*AttrPart!='\0') WrError(1100);
+ else
+ BEGIN
+ OpSize=(-2);
+ DecodeAdr(ArgStr[1],MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModImm:
+ BAsmCode[CodeLen++]=0xd6;
+ BAsmCode[CodeLen++]=0x30+AdrVals[0];
+ break;
+ END
+ END
+END
+
+ static void DecodeCALL(Word Index)
+BEGIN
+ LongInt AdrLong;
+ Boolean OK;
+
+ if (ArgCnt!=1) WrError(1110);
+ else if (*AttrPart!='\0') WrError(1100);
+ else if (*ArgStr[1]=='[')
+ BEGIN
+ DecodeAdr(ArgStr[1],MModMem);
+ if (AdrMode!=ModNone)
+ if (MemPart!=2) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[CodeLen++]=0xc6;
+ BAsmCode[CodeLen++]=AdrPart;
+ END
+ END
+ else
+ BEGIN
+ FirstPassUnknown=False;
+ AdrLong=EvalIntExpression(ArgStr[1],UInt24,&OK);
+ if (OK)
+ BEGIN
+ ChkSpace(SegCode);
+#ifdef __STDC__
+ if (FirstPassUnknown) AdrLong&=0xfffffffeu;
+#else
+ if (FirstPassUnknown) AdrLong&=0xfffffffe;
+#endif
+ AdrLong-=(EProgCounter()+CodeLen+3) & 0xfffffe;
+ if ((NOT SymbolQuestionable) AND ((AdrLong>65534) OR (AdrLong<-65536))) WrError(1370);
+ else if ((AdrLong&1)==1) WrError(1325);
+ else
+ BEGIN
+ AdrLong>>=1;
+ BAsmCode[CodeLen++]=0xc5;
+ BAsmCode[CodeLen++]=(AdrLong >> 8) & 0xff;
+ BAsmCode[CodeLen++]=AdrLong & 0xff;
+ END
+ END
+ END
+END
+
+ static void DecodeJMP(Word Index)
+BEGIN
+ LongInt AdrLong;
+ Boolean OK;
+
+ if (ArgCnt!=1) WrError(1110);
+ else if (*AttrPart!='\0') WrError(1100);
+ else if (strcasecmp(ArgStr[1],"[A+DPTR]")==0)
+ BEGIN
+ BAsmCode[CodeLen++]=0xd6;
+ BAsmCode[CodeLen++]=0x46;
+ END
+ else if (strncmp(ArgStr[1],"[[",2)==0)
+ BEGIN
+ ArgStr[1][strlen(ArgStr[1])-1]='\0';
+ DecodeAdr(ArgStr[1]+1,MModMem);
+ if (AdrMode==ModMem)
+ switch (MemPart)
+ BEGIN
+ case 3:
+ BAsmCode[CodeLen++]=0xd6;
+ BAsmCode[CodeLen++]=0x60+AdrPart;
+ break;
+ default:
+ WrError(1350);
+ END
+ END
+ else if (*ArgStr[1]=='[')
+ BEGIN
+ DecodeAdr(ArgStr[1],MModMem);
+ if (AdrMode==ModMem)
+ switch (MemPart)
+ BEGIN
+ case 2:
+ BAsmCode[CodeLen++]=0xd6;
+ BAsmCode[CodeLen++]=0x70+AdrPart;
+ break;
+ default:
+ WrError(1350);
+ END
+ END
+ else
+ BEGIN
+ FirstPassUnknown=False;
+ AdrLong=EvalIntExpression(ArgStr[1],UInt24,&OK);
+ if (OK)
+ BEGIN
+ ChkSpace(SegCode);
+#ifdef __STDC__
+ if (FirstPassUnknown) AdrLong&=0xfffffffeu;
+#else
+ if (FirstPassUnknown) AdrLong&=0xfffffffe;
+#endif
+ AdrLong-=((EProgCounter()+CodeLen+3) & 0xfffffe);
+ if ((NOT SymbolQuestionable) AND ((AdrLong>65534) OR (AdrLong<-65536))) WrError(1370);
+ else if ((AdrLong&1)==1) WrError(1325);
+ else
+ BEGIN
+ AdrLong>>=1;
+ BAsmCode[CodeLen++]=0xd5;
+ BAsmCode[CodeLen++]=(AdrLong >> 8) & 0xff;
+ BAsmCode[CodeLen++]=AdrLong & 0xff;
+ END
+ END
+ END
+END
+
+ static void DecodeCJNE(Word Index)
+BEGIN
+ LongInt AdrLong,SaveLong,odd;
+ Boolean OK;
+ Byte HReg;
+
+ if (ArgCnt!=3) WrError(1110);
+ else
+ BEGIN
+ FirstPassUnknown=False;
+ AdrLong=SaveLong=EvalIntExpression(ArgStr[3],UInt24,&OK);
+ if (FirstPassUnknown) AdrLong&=0xfffffe;
+ if (OK)
+ BEGIN
+ ChkSpace(SegCode); OK=False; HReg=0;
+ DecodeAdr(ArgStr[1],MModMem);
+ if (AdrMode==ModMem)
+ switch (MemPart)
+ BEGIN
+ case 1:
+ if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
+ else
+ BEGIN
+ HReg=AdrPart; DecodeAdr(ArgStr[2],MModMem+MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModMem:
+ if (MemPart!=6) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[CodeLen]=0xe2+(OpSize << 3);
+ BAsmCode[CodeLen+1]=(HReg << 4)+AdrPart;
+ BAsmCode[CodeLen+2]=AdrVals[0];
+ HReg=CodeLen+3;
+ CodeLen+=4; OK=True;
+ END
+ break;
+ case ModImm:
+ BAsmCode[CodeLen]=0xe3+(OpSize << 3);
+ BAsmCode[CodeLen+1]=HReg << 4;
+ HReg=CodeLen+2;
+ memcpy(BAsmCode+CodeLen+3,AdrVals,AdrCnt);
+ CodeLen+=3+AdrCnt; OK=True;
+ break;
+ END
+ END
+ break;
+ case 2:
+ if ((OpSize!=-1) AND (OpSize!=0) AND (OpSize!=1)) WrError(1130);
+ else
+ BEGIN
+ HReg=AdrPart; DecodeAdr(ArgStr[2],MModImm);
+ if (AdrMode==ModImm)
+ BEGIN
+ BAsmCode[CodeLen]=0xe3+(OpSize << 3);
+ BAsmCode[CodeLen+1]=(HReg << 4)+8;
+ HReg=CodeLen+2;
+ memcpy(BAsmCode+CodeLen+3,AdrVals,AdrCnt);
+ CodeLen+=3+AdrCnt; OK=True;
+ END
+ END
+ break;
+ default:
+ WrError(1350);
+ END
+ if (OK)
+ BEGIN
+ AdrLong-=(EProgCounter()+CodeLen) & 0xfffffe; OK=False;
+ if ((AdrLong&1)==1) WrError(1325);
+ else if ((SymbolQuestionable) OR ((AdrLong<=254) AND (AdrLong>=-256)))
+ BEGIN
+ BAsmCode[HReg]=(AdrLong >> 1) & 0xff; OK=True;
+ END
+ else if (NOT DoBranchExt) WrError(1370);
+ else
+ BEGIN
+ odd=(EProgCounter()+CodeLen) & 1;
+ AdrLong=SaveLong-((EProgCounter()+CodeLen+5+odd)&0xfffffe);
+ if ((AdrLong<-65536) OR (AdrLong>65534)) WrError(1370);
+ else
+ BEGIN
+ BAsmCode[HReg]=1+odd;
+ BAsmCode[CodeLen++]=0xfe;
+ BAsmCode[CodeLen++]=2+odd;
+ if (odd) BAsmCode[CodeLen++]=0;
+ BAsmCode[CodeLen++]=0xd5;
+ BAsmCode[CodeLen++]=(AdrLong >> 9) & 0xff;
+ BAsmCode[CodeLen++]=(AdrLong >> 1) & 0xff;
+ BAsmCode[CodeLen++]=0;
+ OK=True;
+ END
+ END
+ END
+ if (NOT OK) CodeLen=0;
+ END
+ END
+END
+
+ static void DecodeDJNZ(Word Index)
+BEGIN
+ LongInt AdrLong,SaveLong,odd;
+ Boolean OK;
+ Byte HReg;
+
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ FirstPassUnknown=False;
+ SaveLong=AdrLong=EvalIntExpression(ArgStr[2],UInt24,&OK);
+ if (FirstPassUnknown) AdrLong&=0xfffffe;
+ if (OK)
+ BEGIN
+ ChkSpace(SegCode); HReg=0;
+ DecodeAdr(ArgStr[1],MModMem);
+ OK=False; DecodeAdr(ArgStr[1],MModMem);
+ if (AdrMode==ModMem)
+ switch (MemPart)
+ BEGIN
+ case 1:
+ if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
+ else
+ BEGIN
+ BAsmCode[CodeLen]=0x87+(OpSize << 3);
+ BAsmCode[CodeLen+1]=(AdrPart << 4)+0x08;
+ HReg=CodeLen+2;
+ CodeLen+=3; OK=True;
+ END
+ break;
+ case 6:
+ if (OpSize==-1) WrError(1132);
+ else if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
+ else
+ BEGIN
+ BAsmCode[CodeLen]=0xe2+(OpSize << 3);
+ BAsmCode[CodeLen+1]=0x08+AdrPart;
+ BAsmCode[CodeLen+2]=AdrVals[0];
+ HReg=CodeLen+3;
+ CodeLen+=4; OK=True;
+ END
+ break;
+ default:
+ WrError(1350);
+ END
+ if (OK)
+ BEGIN
+ AdrLong-=(EProgCounter()+CodeLen) & 0xfffffe; OK=False;
+ if ((AdrLong&1)==1) WrError(1325);
+ else if ((SymbolQuestionable) OR ((AdrLong<=254) AND (AdrLong>=-256)))
+ BEGIN
+ BAsmCode[HReg]=(AdrLong >> 1) & 0xff; OK=True;
+ END
+ else if (NOT DoBranchExt) WrError(1370);
+ else
+ BEGIN
+ odd=(EProgCounter()+CodeLen) & 1;
+ AdrLong=SaveLong-((EProgCounter()+CodeLen+5+odd)&0xfffffe);
+ if ((AdrLong<-65536) OR (AdrLong>65534)) WrError(1370);
+ else
+ BEGIN
+ BAsmCode[HReg]=1+odd;
+ BAsmCode[CodeLen++]=0xfe;
+ BAsmCode[CodeLen++]=2+odd;
+ if (odd) BAsmCode[CodeLen++]=0;
+ BAsmCode[CodeLen++]=0xd5;
+ BAsmCode[CodeLen++]=(AdrLong >> 9) & 0xff;
+ BAsmCode[CodeLen++]=(AdrLong >> 1) & 0xff;
+ BAsmCode[CodeLen++]=0;
+ OK=True;
+ END
+ END
+ END
+ if (NOT OK) CodeLen=0;
+ END
+ END
+END
+
+ static void DecodeFCALLJMP(Word Index)
+BEGIN
+ LongInt AdrLong;
+ Boolean OK;
+
+ if (ArgCnt!=1) WrError(1110);
+ else if (*AttrPart!='\0') WrError(1100);
+ else
+ BEGIN
+ FirstPassUnknown=False;
+ AdrLong=EvalIntExpression(ArgStr[1],UInt24,&OK);
+ if (FirstPassUnknown) AdrLong&=0xfffffe;
+ if (OK)
+ if ((AdrLong&1)==1) WrError(1325);
+ else
+ BEGIN
+ BAsmCode[CodeLen++]=0xc4+(Index << 4);
+ BAsmCode[CodeLen++]=(AdrLong >> 8) & 0xff;
+ BAsmCode[CodeLen++]=AdrLong & 0xff;
+ BAsmCode[CodeLen++]=(AdrLong >> 16) & 0xff;
+ END
+ END
+END
+
+ static Boolean IsRealDef(void)
+BEGIN
+ return ((Memo("PORT")) OR (Memo("BIT")));
+END
+
+ static void ForceAlign(void)
+BEGIN
+ if ((EProgCounter()&1)==1)
+ BEGIN
+ BAsmCode[0]=NOPCode; CodeLen=1;
+ END
+END
+
+ static void MakeCode_XA(void)
+BEGIN
+ CodeLen=0; DontPrint=False; OpSize=(-1);
+
+ /* Operandengroesse */
+
+ if (*AttrPart!='\0')
+ switch (toupper(*AttrPart))
+ BEGIN
+ case 'B': SetOpSize(0); break;
+ case 'W': SetOpSize(1); break;
+ case 'D': SetOpSize(2); break;
+ default : WrError(1107); return;
+ END
+
+ /* Pseudoanweisungen */
+
+ if (DecodePseudo()) return;
+
+ /* Labels muessen auf geraden Adressen liegen */
+
+ if ( (ActPC==SegCode) AND (NOT IsRealDef()) AND
+ ((*LabPart!='\0') OR ((ArgCnt == 1) AND (strcmp(ArgStr[1],"$")==0))) )
+ BEGIN
+ ForceAlign();
+ if (*LabPart!='\0')
+ EnterIntSymbol(LabPart,EProgCounter()+CodeLen,ActPC,False);
+ END
+
+ if (DecodeMoto16Pseudo(OpSize,False)) return;
+ if (DecodeIntelPseudo(False)) return;
+
+ /* zu ignorierendes */
+
+ if (Memo("")) return;
+
+ /* via Tabelle suchen */
+
+ if (NOT LookupInstTable(InstTable,OpPart)) WrXError(1200,OpPart);
+END
+
+/*-------------------------------------------------------------------------*/
+/* Codetabellenverwaltung */
+
+ static void AddFixed(char *NName, Word NCode)
+BEGIN
+ if (InstrZ>=FixedOrderCnt) exit(255);
+ FixedOrders[InstrZ].Code=NCode;
+ AddInstTable(InstTable,NName,InstrZ++,DecodeFixed);
+END
+
+ static void AddJBit(char *NName, Word NCode)
+BEGIN
+ if (InstrZ>=JBitOrderCnt) exit(255);
+ JBitOrders[InstrZ].Name=NName;
+ JBitOrders[InstrZ].Inversion=255;
+ JBitOrders[InstrZ].Code=NCode;
+ AddInstTable(InstTable,NName,InstrZ++,DecodeJBit);
+END
+
+ static void AddStack(char *NName, Word NCode)
+BEGIN
+ if (InstrZ>=StackOrderCount) exit(255);
+ StackOrders[InstrZ].Code=NCode;
+ AddInstTable(InstTable,NName,InstrZ++,DecodeStack);
+END
+
+ static void AddReg(char *NName, Byte NMask, Byte NCode)
+BEGIN
+ if (InstrZ>=RegOrderCnt) exit(255);
+ RegOrders[InstrZ].Code=NCode;
+ RegOrders[InstrZ].SizeMask=NMask;
+ AddInstTable(InstTable,NName,InstrZ++,DecodeRegO);
+END
+
+ static void AddRotate(char *NName, Word NCode)
+BEGIN
+ if (InstrZ>=RotateOrderCount) exit(255);
+ RotateOrders[InstrZ].Code=NCode;
+ AddInstTable(InstTable,NName,InstrZ++,DecodeRotate);
+END
+
+ static void AddRel(char *NName, Word NCode)
+BEGIN
+ if (InstrZ>=RelOrderCount) exit(255);
+ RelOrders[InstrZ].Name=NName;
+ RelOrders[InstrZ].Inversion=255;
+ RelOrders[InstrZ].Code=NCode;
+ AddInstTable(InstTable,NName,InstrZ++,DecodeRel);
+END
+
+ static void SetInv(char *Name1, char *Name2, InvOrder *Orders)
+BEGIN
+ InvOrder *Order1,*Order2;
+
+ for (Order1=Orders; strcmp(Order1->Name,Name1)!=0; Order1++);
+ for (Order2=Orders; strcmp(Order2->Name,Name2)!=0; Order2++);
+ Order1->Inversion=Order2-Orders;
+ Order2->Inversion=Order1-Orders;
+END
+
+ static void InitFields(void)
+BEGIN
+ InstTable=CreateInstTable(201);
+ AddInstTable(InstTable,"MOV" ,0,DecodeMOV);
+ AddInstTable(InstTable,"MOVC",0,DecodeMOVC);
+ AddInstTable(InstTable,"MOVX",0,DecodeMOVX);
+ AddInstTable(InstTable,"XCH" ,0,DecodeXCH);
+ AddInstTable(InstTable,"ADDS",0,DecodeADDSMOVS);
+ AddInstTable(InstTable,"MOVS",1,DecodeADDSMOVS);
+ AddInstTable(InstTable,"DIV" ,0,DecodeDIV);
+ AddInstTable(InstTable,"DIVU",0,DecodeDIVU);
+ AddInstTable(InstTable,"MUL" ,0,DecodeMUL);
+ AddInstTable(InstTable,"DIVU",0,DecodeDIVU);
+ AddInstTable(InstTable,"MULU",0,DecodeMULU);
+ AddInstTable(InstTable,"LEA" ,0,DecodeLEA);
+ AddInstTable(InstTable,"ANL" ,0,DecodeANLORL);
+ AddInstTable(InstTable,"ORL" ,1,DecodeANLORL);
+ AddInstTable(InstTable,"CLR" ,0,DecodeCLRSETB);
+ AddInstTable(InstTable,"SETB",1,DecodeCLRSETB);
+ AddInstTable(InstTable,"TRAP",0,DecodeTRAP);
+ AddInstTable(InstTable,"CALL",0,DecodeCALL);
+ AddInstTable(InstTable,"JMP" ,0,DecodeJMP);
+ AddInstTable(InstTable,"CJNE",0,DecodeCJNE);
+ AddInstTable(InstTable,"DJNZ",0,DecodeDJNZ);
+ AddInstTable(InstTable,"FCALL",0,DecodeFCALLJMP);
+ AddInstTable(InstTable,"FJMP",1,DecodeFCALLJMP);
+
+ FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); InstrZ=0;
+ AddFixed("NOP" ,0x0000);
+ AddFixed("RET" ,0xd680);
+ AddFixed("RETI" ,0xd690);
+ AddFixed("BKPT" ,0x00ff);
+ AddFixed("RESET",0xd610);
+
+ JBitOrders=(InvOrder *) malloc(sizeof(InvOrder)*JBitOrderCnt); InstrZ=0;
+ AddJBit("JB" ,0x80);
+ AddJBit("JBC" ,0xc0);
+ AddJBit("JNB" ,0xa0);
+ SetInv("JB","JNB",JBitOrders);
+
+ StackOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*StackOrderCount); InstrZ=0;
+ AddStack("POP" ,0x1027);
+ AddStack("POPU" ,0x0037);
+ AddStack("PUSH" ,0x3007);
+ AddStack("PUSHU",0x2017);
+
+ InstrZ=0;
+ AddInstTable(InstTable,"ADD" ,InstrZ++,DecodeALU);
+ AddInstTable(InstTable,"ADDC",InstrZ++,DecodeALU);
+ AddInstTable(InstTable,"SUB" ,InstrZ++,DecodeALU);
+ AddInstTable(InstTable,"SUBB",InstrZ++,DecodeALU);
+ AddInstTable(InstTable,"CMP" ,InstrZ++,DecodeALU);
+ AddInstTable(InstTable,"AND" ,InstrZ++,DecodeALU);
+ AddInstTable(InstTable,"OR" ,InstrZ++,DecodeALU);
+ AddInstTable(InstTable,"XOR" ,InstrZ++,DecodeALU);
+
+ RegOrders=(RegOrder *) malloc(sizeof(RegOrder)*RegOrderCnt); InstrZ=0;
+ AddReg("NEG" ,3,0x0b);
+ AddReg("CPL" ,3,0x0a);
+ AddReg("SEXT",3,0x09);
+ AddReg("DA" ,1,0x08);
+
+ InstrZ=0;
+ AddInstTable(InstTable,"LSR" ,InstrZ++,DecodeShift);
+ AddInstTable(InstTable,"ASL" ,InstrZ++,DecodeShift);
+ AddInstTable(InstTable,"ASR" ,InstrZ++,DecodeShift);
+ AddInstTable(InstTable,"NORM",InstrZ++,DecodeShift);
+
+ RotateOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*RotateOrderCount); InstrZ=0;
+ AddRotate("RR" ,0xb0); AddRotate("RL" ,0xd3);
+ AddRotate("RRC",0xb7); AddRotate("RLC",0xd7);
+
+ RelOrders=(InvOrder *) malloc(sizeof(InvOrder)*RelOrderCount); InstrZ=0;
+ AddRel("BCC",0xf0); AddRel("BCS",0xf1); AddRel("BNE",0xf2);
+ AddRel("BEQ",0xf3); AddRel("BNV",0xf4); AddRel("BOV",0xf5);
+ AddRel("BPL",0xf6); AddRel("BMI",0xf7); AddRel("BG" ,0xf8);
+ AddRel("BL" ,0xf9); AddRel("BGE",0xfa); AddRel("BLT",0xfb);
+ AddRel("BGT",0xfc); AddRel("BLE",0xfd); AddRel("BR" ,0xfe);
+ AddRel("JZ" ,0xec); AddRel("JNZ",0xee);
+ SetInv("BCC","BCS",RelOrders);
+ SetInv("BNE","BEQ",RelOrders);
+ SetInv("BNV","BOV",RelOrders);
+ SetInv("BPL","BMI",RelOrders);
+ SetInv("BG" ,"BL" ,RelOrders);
+ SetInv("BGE","BLT",RelOrders);
+ SetInv("BGT","BLE",RelOrders);
+ SetInv("JZ" ,"JNZ",RelOrders);
+END
+
+ static void DeinitFields(void)
+BEGIN
+ free(FixedOrders);
+ free(JBitOrders);
+ free(StackOrders);
+ free(RegOrders);
+ free(RotateOrders);
+ free(RelOrders);
+
+ DestroyInstTable(InstTable);
+END
+
+/*-------------------------------------------------------------------------*/
+/* Callbacks */
+
+ static void InitCode_XA(void)
+BEGIN
+ SaveInitProc();
+ Reg_DS=0;
+END
+
+ static Boolean ChkPC_XA(LargeWord Addr)
+BEGIN
+ switch (ActPC)
+ BEGIN
+ case SegCode:
+ case SegData:
+ return (Addr<0x1000000);
+ case SegIO:
+ return ((Addr>0x3ff) AND (Addr<0x800));
+ default:
+ return False;
+ END
+END
+
+ static Boolean IsDef_XA(void)
+BEGIN
+ return (ActPC==SegCode);
+END
+
+ static void SwitchFrom_XA(void)
+BEGIN
+ DeinitFields(); ClearONOFF();
+END
+
+ static void SwitchTo_XA(void)
+BEGIN
+ TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False;
+
+ PCSymbol="$"; HeaderID=0x3c; NOPCode=0x00;
+ DivideChars=","; HasAttrs=True; AttrChars=".";
+
+ ValidSegs=(1<<SegCode)|(1<<SegData)|(1<<SegIO);
+ Grans[SegCode ]=1; ListGrans[SegCode ]=1; SegInits[SegCode ]=0;
+ Grans[SegData ]=1; ListGrans[SegData ]=1; SegInits[SegData ]=0;
+ Grans[SegIO ]=1; ListGrans[SegIO ]=1; SegInits[SegIO ]=0x400;
+
+ MakeCode=MakeCode_XA; ChkPC=ChkPC_XA; IsDef=IsDef_XA;
+ SwitchFrom=SwitchFrom_XA; InitFields();
+ AddONOFF("SUPMODE", &SupAllowed, SupAllowedName,False);
+ AddONOFF("BRANCHEXT",&DoBranchExt,BranchExtName ,False);
+ AddMoto16PseudoONOFF();
+
+ SetFlag(&DoPadding,DoPaddingName,False);
+END
+
+ void codexa_init(void)
+BEGIN
+ CPUXAG1=AddCPU("XAG1",SwitchTo_XA);
+ CPUXAG2=AddCPU("XAG2",SwitchTo_XA);
+ CPUXAG3=AddCPU("XAG3",SwitchTo_XA);
+
+ SaveInitProc=InitPassProc; InitPassProc=InitCode_XA;
+END