diff options
author | fishsoupisgood <github@madingley.org> | 2019-05-27 02:41:51 +0100 |
---|---|---|
committer | fishsoupisgood <github@madingley.org> | 2019-05-27 02:41:51 +0100 |
commit | 333b605b2afd472b823aeda0adf0e8b1ea9843c0 (patch) | |
tree | bc8f581317897e2e53f278f1716b4471fcdccd4f /codexa.c | |
download | asl-master.tar.gz asl-master.tar.bz2 asl-master.zip |
Diffstat (limited to 'codexa.c')
-rw-r--r-- | codexa.c | 1975 |
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 |