/* code86.c */ /*****************************************************************************/ /* AS-Portierung */ /* */ /* Codegenerator 8086/V-Serie */ /* */ /* Historie: */ /* 2. 1.1999 ChkPC-Anpassung */ /* */ /*****************************************************************************/ #include "stdinc.h" #include #include "bpemu.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 { char *Name; CPUVar MinCPU; Word Code; } FixedOrder; typedef struct { char *Name; CPUVar MinCPU; Word Code; Byte Add; } AddOrder; #define FixedOrderCnt 41 #define FPUFixedOrderCnt 29 #define StringOrderCnt 14 #define ReptOrderCnt 7 #define RelOrderCnt 36 #define ModRegOrderCnt 4 #define ShiftOrderCnt 8 #define Reg16OrderCnt 3 #define FPUStOrderCnt 2 #define FPU16OrderCnt 5 #define MulOrderCnt 4 #define Bit1OrderCnt 4 #define SegRegCnt 3 static char *SegRegNames[SegRegCnt+1]={"ES","CS","SS","DS"}; static Byte SegRegPrefixes[SegRegCnt+1]={0x26,0x2e,0x36,0x3e}; #define TypeNone (-1) #define TypeReg8 0 #define TypeReg16 1 #define TypeRegSeg 2 #define TypeMem 3 #define TypeImm 4 #define TypeFReg 5 static ShortInt AdrType; static Byte AdrMode; static Byte AdrVals[6]; static ShortInt OpSize; static Boolean UnknownFlag; static Boolean NoSegCheck; static Byte Prefixes[6]; static Byte PrefixLen; static Byte SegAssumes[SegRegCnt+1]; static SimpProc SaveInitProc; static CPUVar CPU8086,CPU80186,CPUV30,CPUV35; static FixedOrder *FixedOrders; static FixedOrder *FPUFixedOrders; static FixedOrder *FPUStOrders; static FixedOrder *FPU16Orders; static FixedOrder *StringOrders; static FixedOrder *ReptOrders; static FixedOrder *RelOrders; static FixedOrder *ModRegOrders; static FixedOrder *ShiftOrders; static AddOrder *Reg16Orders; static char **MulOrders; static char **Bit1Orders; static PInstTable InstTable; /*------------------------------------------------------------------------------------*/ static void PutCode(Word Code) BEGIN if (Hi(Code)!=0) BAsmCode[CodeLen++]=Hi(Code); BAsmCode[CodeLen++]=Lo(Code); END static void MoveAdr(int Dest) BEGIN memcpy(BAsmCode+CodeLen+Dest,AdrVals,AdrCnt); END static Byte Sgn(Byte inp) BEGIN return (inp>127) ? 0xff : 0; END static void AddPrefix(Byte Prefix) BEGIN Prefixes[PrefixLen++]=Prefix; END static void AddPrefixes(void) BEGIN if ((CodeLen!=0) AND (PrefixLen!=0)) BEGIN memmove(BAsmCode+PrefixLen,BAsmCode,CodeLen); memcpy(BAsmCode,Prefixes,PrefixLen); CodeLen+=PrefixLen; END END static Boolean AbleToSign(Word Arg) BEGIN return ((Arg<=0x7f) OR (Arg>=0xff80)); END static Boolean MinOneIs0(void) BEGIN if ((UnknownFlag) AND (OpSize==-1)) BEGIN OpSize=0; return True; END else return False; END static void ChkOpSize(ShortInt NewSize) BEGIN if (OpSize==-1) OpSize=NewSize; else if (OpSize!=NewSize) BEGIN AdrType=TypeNone; WrError(1131); END END static void ChkSingleSpace(Byte Seg, Byte EffSeg, Byte MomSegment) BEGIN Byte z; /* liegt Operand im zu pruefenden Segment? nein-->vergessen */ if ((MomSegment & (1 << Seg))==0) return; /* zeigt bish. benutztes Segmentregister auf dieses Segment? ja-->ok */ if (EffSeg==Seg) return; /* falls schon ein Override gesetzt wurde, nur warnen */ if (PrefixLen>0) WrError(70); /* ansonsten ein passendes Segment suchen und warnen, falls keines da */ else BEGIN z=0; while ((z<=SegRegCnt) AND (SegAssumes[z]!=Seg)) z++; if (z>SegRegCnt) WrXError(75,SegNames[Seg]); else AddPrefix(SegRegPrefixes[z]); END END static void ChkSpaces(ShortInt SegBuffer, Byte MomSegment) BEGIN Byte EffSeg; if (NoSegCheck) return; /* in welches Segment geht das benutzte Segmentregister ? */ EffSeg=SegAssumes[SegBuffer]; /* Zieloperand in Code-/Datensegment ? */ ChkSingleSpace(SegCode,EffSeg,MomSegment); ChkSingleSpace(SegXData,EffSeg,MomSegment); ChkSingleSpace(SegData,EffSeg,MomSegment); END static void DecodeAdr(char *Asc) BEGIN #define RegCnt 7 static char *Reg16Names[RegCnt+1]= {"AX","CX","DX","BX","SP","BP","SI","DI"}; static char *Reg8Names[RegCnt+1]= {"AL","CL","DL","BL","AH","CH","DH","BH"}; static Byte RMCodes[8]={11,12,21,22,1,2,20,10}; int RegZ,z; Boolean IsImm; ShortInt IndexBuf,BaseBuf; Byte SumBuf; LongInt DispAcc,DispSum; char *p,*p1,*p2; Boolean HasAdr; Boolean OK,OldNegFlag,NegFlag; String AdrPart,AddPart; ShortInt SegBuffer; Byte MomSegment; ShortInt FoundSize; AdrType=TypeNone; AdrCnt=0; SegBuffer=(-1); MomSegment=0; for (RegZ=0; RegZ<=RegCnt; RegZ++) BEGIN if (strcasecmp(Asc,Reg16Names[RegZ])==0) BEGIN AdrType=TypeReg16; AdrMode=RegZ; ChkOpSize(1); return; END if (strcasecmp(Asc,Reg8Names[RegZ])==0) BEGIN AdrType=TypeReg8; AdrMode=RegZ; ChkOpSize(0); return; END END for (RegZ=0; RegZ<=SegRegCnt; RegZ++) if (strcasecmp(Asc,SegRegNames[RegZ])==0) BEGIN AdrType=TypeRegSeg; AdrMode=RegZ; ChkOpSize(1); return; END if (FPUAvail) BEGIN if (strcasecmp(Asc,"ST")==0) BEGIN AdrType=TypeFReg; AdrMode=0; ChkOpSize(4); return; END if ((strlen(Asc)>4) AND (strncasecmp(Asc,"ST(",3)==0) AND (Asc[strlen(Asc)-1]==')')) BEGIN Asc[strlen(Asc)-1]='\0'; AdrMode=EvalIntExpression(Asc+3,UInt3,&OK); if (OK) BEGIN AdrType=TypeFReg; ChkOpSize(4); END return; END END IsImm=True; IndexBuf=0; BaseBuf=0; DispAcc=0; FoundSize=(-1); if (strncasecmp(Asc,"WORD PTR",8)==0) BEGIN strcpy(Asc,Asc+8); FoundSize=1; IsImm=False; KillBlanks(Asc); END else if (strncasecmp(Asc,"BYTE PTR",8)==0) BEGIN strcpy(Asc,Asc+8); FoundSize=0; IsImm=False; KillBlanks(Asc); END else if (strncasecmp(Asc,"DWORD PTR",9)==0) BEGIN strcpy(Asc,Asc+9); FoundSize=2; IsImm=False; KillBlanks(Asc); END else if (strncasecmp(Asc,"QWORD PTR",9)==0) BEGIN strcpy(Asc,Asc+9); FoundSize=3; IsImm=False; KillBlanks(Asc); END else if (strncasecmp(Asc,"TBYTE PTR",9)==0) BEGIN strcpy(Asc,Asc+9); FoundSize=4; IsImm=False; KillBlanks(Asc); END if ((strlen(Asc)>2) AND (Asc[2]==':')) BEGIN strncpy(AddPart,Asc,2); AddPart[2]='\0'; for (z=0; z<=SegRegCnt; z++) if (strcasecmp(AddPart,SegRegNames[z])==0) BEGIN strcpy(Asc,Asc+3); SegBuffer=z; AddPrefix(SegRegPrefixes[SegBuffer]); END END do BEGIN p=QuotPos(Asc,'['); HasAdr=(p!=Nil); if (p!=Asc) BEGIN FirstPassUnknown=False; if (p!=Nil) *p='\0'; DispAcc+=EvalIntExpression(Asc,Int16,&OK); if (NOT OK) return; UnknownFlag=UnknownFlag OR FirstPassUnknown; MomSegment|=TypeFlag; if (FoundSize==-1) FoundSize=SizeFlag; if (p==Nil) *Asc='\0'; else BEGIN *p='['; strcpy(Asc,p); END END if (HasAdr) BEGIN IsImm=False; p=RQuotPos(Asc,']'); if (p==Nil) BEGIN WrError(1300); return; END *p='\0'; strmaxcpy(AdrPart,Asc+1,255); strcpy(Asc,p+1); OldNegFlag=False; do BEGIN NegFlag=False; p1=QuotPos(AdrPart,'+'); p2=QuotPos(AdrPart,'-'); if (((p1>p2) OR (p1==Nil)) AND (p2!=Nil)) BEGIN p=p2; NegFlag=True; END else p=p1; if (p==Nil) BEGIN strcpy(AddPart,AdrPart); *AdrPart='\0'; END else BEGIN *p='\0'; strcpy(AddPart,AdrPart); strcpy(AdrPart,p+1); END if (strcasecmp(AddPart,"BX")==0) BEGIN if ((OldNegFlag) OR (BaseBuf!=0)) return; else BaseBuf=1; END else if (strcasecmp(AddPart,"BP")==0) BEGIN if ((OldNegFlag) OR (BaseBuf!=0)) return; else BaseBuf=2; END else if (strcasecmp(AddPart,"SI")==0) BEGIN if ((OldNegFlag) OR (IndexBuf!=0)) return; else IndexBuf=1; END else if (strcasecmp(AddPart,"DI")==0) BEGIN if ((OldNegFlag) OR (IndexBuf!=0)) return; else IndexBuf=2; END else BEGIN FirstPassUnknown=False; DispSum=EvalIntExpression(AddPart,Int16,&OK); if (NOT OK) return; UnknownFlag=UnknownFlag OR FirstPassUnknown; if (OldNegFlag) DispAcc-=DispSum; else DispAcc+=DispSum; MomSegment|=TypeFlag; if (FoundSize==-1) FoundSize=SizeFlag; END OldNegFlag=NegFlag; END while (*AdrPart!='\0'); END END while (*Asc!='\0'); SumBuf=BaseBuf*10+IndexBuf; /* welches Segment effektiv benutzt ? */ if (SegBuffer==-1) SegBuffer=(BaseBuf==2) ? 2 : 3; /* nur Displacement */ if (SumBuf==0) /* immediate */ if (IsImm) BEGIN if (((UnknownFlag) AND (OpSize==0)) OR (MinOneIs0())) DispAcc&=0xff; switch (OpSize) BEGIN case -1: WrError(1132); break; case 0: if ((DispAcc<-128) OR (DispAcc>255)) WrError(1320); else BEGIN AdrType=TypeImm; AdrVals[0]=DispAcc & 0xff; AdrCnt=1; END break; case 1: AdrType=TypeImm; AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc); AdrCnt=2; break; END END /* absolut */ else BEGIN AdrType=TypeMem; AdrMode=0x06; AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc); AdrCnt=2; if (FoundSize!=-1) ChkOpSize(FoundSize); ChkSpaces(SegBuffer,MomSegment); END /* kombiniert */ else BEGIN AdrType=TypeMem; for (z=0; z<8; z++) if (SumBuf==RMCodes[z]) AdrMode=z; if (DispAcc==0) BEGIN if (SumBuf==20) BEGIN AdrMode+=0x40; AdrVals[0]=0; AdrCnt=1; END END else if (AbleToSign(DispAcc)) BEGIN AdrMode+=0x40; AdrVals[0]=DispAcc & 0xff; AdrCnt=1; END else BEGIN AdrMode+=0x80; AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc); AdrCnt=2; END ChkSpaces(SegBuffer,MomSegment); if (FoundSize!=-1) ChkOpSize(FoundSize); END END /*---------------------------------------------------------------------------*/ static void DecodeMOV(Word Index) BEGIN Byte AdrByte; if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[1]); switch (AdrType) BEGIN case TypeReg8: case TypeReg16: AdrByte=AdrMode; DecodeAdr(ArgStr[2]); switch (AdrType) BEGIN case TypeReg8: case TypeReg16: BAsmCode[CodeLen++]=0x8a+OpSize; BAsmCode[CodeLen++]=0xc0+(AdrByte << 3)+AdrMode; break; case TypeMem: if ((AdrByte==0) AND (AdrMode==6)) BEGIN BAsmCode[CodeLen]=0xa0+OpSize; MoveAdr(1); CodeLen+=1+AdrCnt; END else BEGIN BAsmCode[CodeLen++]=0x8a+OpSize; BAsmCode[CodeLen++]=AdrMode+(AdrByte << 3); MoveAdr(0); CodeLen+=AdrCnt; END break; case TypeRegSeg: if (OpSize==0) WrError(1131); else BEGIN BAsmCode[CodeLen++]=0x8c; BAsmCode[CodeLen++]=0xc0+(AdrMode << 3)+AdrByte; END break; case TypeImm: BAsmCode[CodeLen++]=0xb0+(OpSize << 3)+AdrByte; MoveAdr(0); CodeLen+=AdrCnt; break; default: if (AdrType!=TypeNone) WrError(1350); END break; case TypeMem: BAsmCode[CodeLen+1]=AdrMode; MoveAdr(2); AdrByte=AdrCnt; DecodeAdr(ArgStr[2]); switch (AdrType) BEGIN case TypeReg8: case TypeReg16: if ((AdrMode==0) AND (BAsmCode[CodeLen+1]==6)) BEGIN BAsmCode[CodeLen]=0xa2+OpSize; memmove(BAsmCode+CodeLen+1,BAsmCode+CodeLen+2,AdrByte); CodeLen+=1+AdrByte; END else BEGIN BAsmCode[CodeLen]=0x88+OpSize; BAsmCode[CodeLen+1]+=AdrMode << 3; CodeLen+=2+AdrByte; END break; case TypeRegSeg: BAsmCode[CodeLen]=0x8c; BAsmCode[CodeLen+1]+=AdrMode << 3; CodeLen+=2+AdrByte; break; case TypeImm: BAsmCode[CodeLen]=0xc6+OpSize; MoveAdr(2+AdrByte); CodeLen+=2+AdrByte+AdrCnt; break; default: if (AdrType!=TypeNone) WrError(1350); END break; case TypeRegSeg: BAsmCode[CodeLen+1]=AdrMode << 3; DecodeAdr(ArgStr[2]); switch (AdrType) BEGIN case TypeReg16: BAsmCode[CodeLen++]=0x8e; BAsmCode[CodeLen++]+=0xc0+AdrMode; break; case TypeMem: BAsmCode[CodeLen]=0x8e; BAsmCode[CodeLen+1]+=AdrMode; MoveAdr(2); CodeLen+=2+AdrCnt; break; default: if (AdrType!=TypeNone) WrError(1350); END break; default: if (AdrType!=TypeNone) WrError(1350); END END AddPrefixes(); END static void DecodeINCDEC(Word Index) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN DecodeAdr(ArgStr[1]); switch (AdrType) BEGIN case TypeReg16: BAsmCode[CodeLen]=0x40+AdrMode+Index; CodeLen++; break; case TypeReg8: BAsmCode[CodeLen]=0xfe; BAsmCode[CodeLen+1]=0xc0+AdrMode+Index; CodeLen+=2; break; case TypeMem: MinOneIs0(); if (OpSize==-1) WrError(1132); else BEGIN BAsmCode[CodeLen]=0xfe + OpSize; /* ANSI :-0 */ BAsmCode[CodeLen+1]=AdrMode+Index; MoveAdr(2); CodeLen+=2+AdrCnt; END break; default: if (AdrType!=TypeNone) WrError(1350); END END AddPrefixes(); END static void DecodeINT(Word Index) BEGIN Boolean OK; if (ArgCnt!=1) WrError(1110); else BEGIN BAsmCode[CodeLen+1]=EvalIntExpression(ArgStr[1],Int8,&OK); if (OK) if (BAsmCode[1]==3) BAsmCode[CodeLen++]=0xcc; else BEGIN BAsmCode[CodeLen]=0xcd; CodeLen+=2; END END AddPrefixes(); END static void DecodeINOUT(Word Index) BEGIN Boolean OK; if (ArgCnt!=2) WrError(1110); else BEGIN if (Index!=0) BEGIN strcpy(ArgStr[3],ArgStr[1]); strcpy(ArgStr[1],ArgStr[2]); strcpy(ArgStr[2],ArgStr[3]); END DecodeAdr(ArgStr[1]); switch (AdrType) BEGIN case TypeReg8: case TypeReg16: if (AdrMode!=0) WrError(1350); else if (strcasecmp(ArgStr[2],"DX")==0) BAsmCode[CodeLen++]=0xec+OpSize+Index; else BEGIN BAsmCode[CodeLen+1]=EvalIntExpression(ArgStr[2],UInt8,&OK); if (OK) BEGIN ChkSpace(SegIO); BAsmCode[CodeLen]=0xe4+OpSize+Index; CodeLen+=2; END END break; default: if (AdrType!=TypeNone) WrError(1350); END END AddPrefixes(); END static void DecodeCALLJMP(Word Index) BEGIN Byte AdrByte; Word AdrWord; Boolean OK; if (ArgCnt!=1) WrError(1110); else BEGIN if (strncmp(ArgStr[1],"SHORT ",6)==0) BEGIN AdrByte=2; strcpy(ArgStr[1],ArgStr[1]+6); KillPrefBlanks(ArgStr[1]); END else if ((strncmp(ArgStr[1],"LONG ",5)==0) OR (strncmp(ArgStr[1],"NEAR ",5)==0)) BEGIN AdrByte=1; strcpy(ArgStr[1],ArgStr[1]+5); KillPrefBlanks(ArgStr[1]); END else AdrByte=0; OK=True; if (Index==0) if (AdrByte==2) BEGIN WrError(1350); OK=False; END else AdrByte=1; if (OK) BEGIN OpSize=1; DecodeAdr(ArgStr[1]); switch (AdrType) BEGIN case TypeReg16: BAsmCode[0]=0xff; BAsmCode[1]=0xd0+AdrMode+(Index<<4); CodeLen=2; break; case TypeMem: BAsmCode[0]=0xff; BAsmCode[1]=AdrMode+0x10+(Index<<4); MoveAdr(2); CodeLen=2+AdrCnt; break; case TypeImm: ChkSpace(SegCode); AdrWord=(((Word) AdrVals[1]) << 8)+AdrVals[0]; if ((AdrByte==2) OR ((AdrByte==0) AND (AbleToSign(AdrWord-EProgCounter()-2)))) BEGIN AdrWord-=EProgCounter()+2; if (NOT AbleToSign(AdrWord)) WrError(1330); else BEGIN BAsmCode[0]=0xeb; BAsmCode[1]=Lo(AdrWord); CodeLen=2; END END else BEGIN AdrWord-=EProgCounter()+3; ChkSpace(SegCode); BAsmCode[0]=0xe8+Index; BAsmCode[1]=Lo(AdrWord); BAsmCode[2]=Hi(AdrWord); CodeLen=3; AdrWord++; END break; default: if (AdrType!=TypeNone) WrError(1350); END END END AddPrefixes(); END static void DecodePUSHPOP(Word Index) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN OpSize=1; DecodeAdr(ArgStr[1]); switch (AdrType) BEGIN case TypeReg16: BAsmCode[CodeLen]=0x50+AdrMode+(Index<<3); CodeLen++; break; case TypeRegSeg: BAsmCode[CodeLen]=0x06+(AdrMode << 3)+Index; CodeLen++; break; case TypeMem: BAsmCode[CodeLen]=0x8f; BAsmCode[CodeLen+1]=AdrMode; if (Index==0) BEGIN BAsmCode[CodeLen]+=0x70; BAsmCode[CodeLen+1]+=0x30; END MoveAdr(2); CodeLen+=2+AdrCnt; break; case TypeImm: if (MomCPU1) WrError(1110); else if (ArgCnt==0) BAsmCode[CodeLen++]=0xc3+Index; else BEGIN AdrWord=EvalIntExpression(ArgStr[1],Int16,&OK); if (OK) BEGIN BAsmCode[CodeLen++]=0xc2+Index; BAsmCode[CodeLen++]=Lo(AdrWord); BAsmCode[CodeLen++]=Hi(AdrWord); END END END static void DecodeTEST(Word Index) BEGIN Byte AdrByte; if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[1]); switch (AdrType) BEGIN case TypeReg8: case TypeReg16: BAsmCode[CodeLen+1]=(AdrMode << 3); DecodeAdr(ArgStr[2]); switch (AdrType) BEGIN case TypeReg8: case TypeReg16: BAsmCode[CodeLen+1]+=0xc0+AdrMode; BAsmCode[CodeLen]=0x84+OpSize; CodeLen+=2; break; case TypeMem: BAsmCode[CodeLen+1]+=AdrMode; BAsmCode[CodeLen]=0x84+OpSize; MoveAdr(2); CodeLen+=2+AdrCnt; break; case TypeImm: if (((BAsmCode[CodeLen+1] >> 3) & 7)==0) BEGIN BAsmCode[CodeLen]=0xa8+OpSize; MoveAdr(1); CodeLen+=1+AdrCnt; END else BEGIN BAsmCode[CodeLen]=OpSize+0xf6; BAsmCode[CodeLen+1]=(BAsmCode[CodeLen+1] >> 3)+0xc0; MoveAdr(2); CodeLen+=2+AdrCnt; END break; default: if (AdrType!=TypeNone) WrError(1350); END break; case TypeMem: BAsmCode[CodeLen+1]=AdrMode; AdrByte=AdrCnt; MoveAdr(2); DecodeAdr(ArgStr[2]); switch (AdrType) BEGIN case TypeReg8: case TypeReg16: BAsmCode[CodeLen]=0x84+OpSize; BAsmCode[CodeLen+1]+=(AdrMode << 3); CodeLen+=2+AdrByte; break; case TypeImm: BAsmCode[CodeLen]=OpSize+0xf6; MoveAdr(2+AdrByte); CodeLen+=2+AdrCnt+AdrByte; break; default: if (AdrType!=TypeNone) WrError(1350); END break; default: if (AdrType!=TypeNone) WrError(1350); END END AddPrefixes(); END static void DecodeXCHG(Word Index) BEGIN Byte AdrByte; if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[1]); switch (AdrType) BEGIN case TypeReg8: case TypeReg16: AdrByte=AdrMode; DecodeAdr(ArgStr[2]); switch (AdrType) BEGIN case TypeReg8: case TypeReg16: if ((OpSize==1) AND ((AdrMode==0) OR (AdrByte==0))) BEGIN BAsmCode[CodeLen]=0x90+AdrMode+AdrByte; CodeLen++; END else BEGIN BAsmCode[CodeLen]=0x86+OpSize; BAsmCode[CodeLen+1]=AdrMode+0xc0+(AdrByte << 3); CodeLen+=2; END break; case TypeMem: BAsmCode[CodeLen]=0x86+OpSize; BAsmCode[CodeLen+1]=AdrMode+(AdrByte << 3); MoveAdr(2); CodeLen+=AdrCnt+2; break; default: if (AdrType!=TypeNone) WrError(1350); END break; case TypeMem: BAsmCode[CodeLen+1]=AdrMode; MoveAdr(2); AdrByte=AdrCnt; DecodeAdr(ArgStr[2]); switch (AdrType) BEGIN case TypeReg8: case TypeReg16: BAsmCode[CodeLen]=0x86+OpSize; BAsmCode[CodeLen+1]+=(AdrMode << 3); CodeLen+=AdrByte+2; break; default: if (AdrType!=TypeNone) WrError(1350); END break; default: if (AdrType!=TypeNone) WrError(1350); END END AddPrefixes(); END static void DecodeCALLJMPF(Word Index) BEGIN char *p; Word AdrWord; Boolean OK; if (ArgCnt!=1) WrError(1110); else BEGIN p=QuotPos(ArgStr[1],':'); if (p==Nil) BEGIN DecodeAdr(ArgStr[1]); switch (AdrType) BEGIN case TypeMem: BAsmCode[CodeLen]=0xff; BAsmCode[CodeLen+1]=AdrMode+0x18+Index; MoveAdr(2); CodeLen+=2+AdrCnt; break; default: if (AdrType!=TypeNone) WrError(1350); END END else BEGIN *p='\0'; AdrWord=EvalIntExpression(ArgStr[1],UInt16,&OK); if (OK) BEGIN BAsmCode[CodeLen+3]=Lo(AdrWord); BAsmCode[CodeLen+4]=Hi(AdrWord); AdrWord=EvalIntExpression(p+1,UInt16,&OK); if (OK) BEGIN BAsmCode[CodeLen+1]=Lo(AdrWord); BAsmCode[CodeLen+2]=Hi(AdrWord); BAsmCode[CodeLen]=0x9a+Index; CodeLen+=5; END END END END AddPrefixes(); END static void DecodeENTER(Word Index) BEGIN Word AdrWord; Boolean OK; if (ArgCnt!=2) WrError(1110); else if (MomCPUMinCPU) WrError(1500); else PutCode(FixedZ->Code); AddPrefixes(); END static void DecodeALU2(Word Index) BEGIN Byte AdrByte; if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[1]); switch (AdrType) BEGIN case TypeReg8: case TypeReg16: BAsmCode[CodeLen+1]=AdrMode << 3; DecodeAdr(ArgStr[2]); switch (AdrType) BEGIN case TypeReg8: case TypeReg16: BAsmCode[CodeLen+1]+=0xc0+AdrMode; BAsmCode[CodeLen]=(Index << 3)+2+OpSize; CodeLen+=2; break; case TypeMem: BAsmCode[CodeLen+1]+=AdrMode; BAsmCode[CodeLen]=(Index << 3)+2+OpSize; MoveAdr(2); CodeLen+=2+AdrCnt; break; case TypeImm: if (((BAsmCode[CodeLen+1] >> 3) & 7)==0) BEGIN BAsmCode[CodeLen]=(Index << 3)+4+OpSize; MoveAdr(1); CodeLen+=1+AdrCnt; END else BEGIN BAsmCode[CodeLen]=OpSize+0x80; if ((OpSize==1) AND (Sgn(AdrVals[0])==AdrVals[1])) BEGIN AdrCnt=1; BAsmCode[CodeLen]+=2; END BAsmCode[CodeLen+1]=(BAsmCode[CodeLen+1] >> 3)+0xc0+(Index << 3); MoveAdr(2); CodeLen+=2+AdrCnt; END break; default: if (AdrType!=TypeNone) WrError(1350); END break; case TypeMem: BAsmCode[CodeLen+1]=AdrMode; AdrByte=AdrCnt; MoveAdr(2); DecodeAdr(ArgStr[2]); switch (AdrType) BEGIN case TypeReg8: case TypeReg16: BAsmCode[CodeLen]=(Index << 3)+OpSize; BAsmCode[CodeLen+1]+=(AdrMode << 3); CodeLen+=2+AdrByte; break; case TypeImm: BAsmCode[CodeLen]=OpSize+0x80; if ((OpSize==1) AND (Sgn(AdrVals[0])==AdrVals[1])) BEGIN AdrCnt=1; BAsmCode[CodeLen]+=2; END BAsmCode[CodeLen+1]+=(Index << 3); MoveAdr(2+AdrByte); CodeLen+=2+AdrCnt+AdrByte; break; default: if (AdrType!=TypeNone) WrError(1350); END break; default: if (AdrType!=TypeNone) WrError(1350); END END AddPrefixes(); END static void DecodeRel(Word Index) BEGIN FixedOrder *RelZ=RelOrders+Index; Word AdrWord; Boolean OK; if (ArgCnt!=1) WrError(1110); else if (MomCPUMinCPU) WrError(1500); else BEGIN AdrWord=EvalIntExpression(ArgStr[1],Int16,&OK); if (OK) BEGIN ChkSpace(SegCode); AdrWord-=EProgCounter()+2; if (Hi(RelZ->Code)!=0) AdrWord--; if ((AdrWord>=0x80) AND (AdrWord<0xff80) AND (NOT SymbolQuestionable)) WrError(1370); else BEGIN PutCode(RelZ->Code); BAsmCode[CodeLen++]=Lo(AdrWord); END END END END /*---------------------------------------------------------------------------*/ static void AddFixed(char *NName, CPUVar NMin, Word NCode) BEGIN if (InstrZ>=FixedOrderCnt) exit(255); FixedOrders[InstrZ].Name=NName; FixedOrders[InstrZ].MinCPU=NMin; FixedOrders[InstrZ].Code=NCode; AddInstTable(InstTable,NName,InstrZ++,DecodeFixed); END static void AddFPUFixed(char *NName, CPUVar NMin, Word NCode) BEGIN if (InstrZ>=FPUFixedOrderCnt) exit(255); FPUFixedOrders[InstrZ].Name=NName; FPUFixedOrders[InstrZ].MinCPU=NMin; FPUFixedOrders[InstrZ++].Code=NCode; END static void AddFPUSt(char *NName, CPUVar NMin, Word NCode) BEGIN if (InstrZ>=FPUStOrderCnt) exit(255); FPUStOrders[InstrZ].Name=NName; FPUStOrders[InstrZ].MinCPU=NMin; FPUStOrders[InstrZ++].Code=NCode; END static void AddFPU16(char *NName, CPUVar NMin, Word NCode) BEGIN if (InstrZ>=FPU16OrderCnt) exit(255); FPU16Orders[InstrZ].Name=NName; FPU16Orders[InstrZ].MinCPU=NMin; FPU16Orders[InstrZ++].Code=NCode; END static void AddString(char *NName, CPUVar NMin, Word NCode) BEGIN if (InstrZ>=StringOrderCnt) exit(255); StringOrders[InstrZ].Name=NName; StringOrders[InstrZ].MinCPU=NMin; StringOrders[InstrZ++].Code=NCode; END static void AddRept(char *NName, CPUVar NMin, Word NCode) BEGIN if (InstrZ>=ReptOrderCnt) exit(255); ReptOrders[InstrZ].Name=NName; ReptOrders[InstrZ].MinCPU=NMin; ReptOrders[InstrZ++].Code=NCode; END static void AddRel(char *NName, CPUVar NMin, Word NCode) BEGIN if (InstrZ>=RelOrderCnt) exit(255); RelOrders[InstrZ].Name=NName; RelOrders[InstrZ].MinCPU=NMin; RelOrders[InstrZ].Code=NCode; AddInstTable(InstTable,NName,InstrZ++,DecodeRel); END static void AddModReg(char *NName, CPUVar NMin, Word NCode) BEGIN if (InstrZ>=ModRegOrderCnt) exit(255); ModRegOrders[InstrZ].Name=NName; ModRegOrders[InstrZ].MinCPU=NMin; ModRegOrders[InstrZ++].Code=NCode; END static void AddShift(char *NName, CPUVar NMin, Word NCode) BEGIN if (InstrZ>=ShiftOrderCnt) exit(255); ShiftOrders[InstrZ].Name=NName; ShiftOrders[InstrZ].MinCPU=NMin; ShiftOrders[InstrZ++].Code=NCode; END static void AddReg16(char *NName, CPUVar NMin, Word NCode, Byte NAdd) BEGIN if (InstrZ>=Reg16OrderCnt) exit(255); Reg16Orders[InstrZ].Name=NName; Reg16Orders[InstrZ].MinCPU=NMin; Reg16Orders[InstrZ].Code=NCode; Reg16Orders[InstrZ++].Add=NAdd; END static void InitFields(void) BEGIN InstTable=CreateInstTable(201); AddInstTable(InstTable,"MOV" ,0,DecodeMOV); AddInstTable(InstTable,"INC" ,0,DecodeINCDEC); AddInstTable(InstTable,"DEC" ,8,DecodeINCDEC); AddInstTable(InstTable,"INT" ,0,DecodeINT); AddInstTable(InstTable,"IN" ,0,DecodeINOUT); AddInstTable(InstTable,"OUT" ,2,DecodeINOUT); AddInstTable(InstTable,"CALL" ,0,DecodeCALLJMP); AddInstTable(InstTable,"JMP" ,1,DecodeCALLJMP); AddInstTable(InstTable,"PUSH" ,0,DecodePUSHPOP); AddInstTable(InstTable,"POP" ,1,DecodePUSHPOP); AddInstTable(InstTable,"NOT" ,0,DecodeNOTNEG); AddInstTable(InstTable,"NEG" ,8,DecodeNOTNEG); AddInstTable(InstTable,"RET" ,0,DecodeRET); AddInstTable(InstTable,"RETF" ,8,DecodeRET); AddInstTable(InstTable,"TEST" ,0,DecodeTEST); AddInstTable(InstTable,"XCHG" ,0,DecodeXCHG); AddInstTable(InstTable,"CALLF",16,DecodeCALLJMPF); AddInstTable(InstTable,"JMPF" ,0,DecodeCALLJMPF); AddInstTable(InstTable,"ENTER",0,DecodeENTER); FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); InstrZ=0; AddFixed("AAA", CPU8086, 0x0037); AddFixed("AAS", CPU8086, 0x003f); AddFixed("AAM", CPU8086, 0xd40a); AddFixed("AAD", CPU8086, 0xd50a); AddFixed("CBW", CPU8086, 0x0098); AddFixed("CLC", CPU8086, 0x00f8); AddFixed("CLD", CPU8086, 0x00fc); AddFixed("CLI", CPU8086, 0x00fa); AddFixed("CMC", CPU8086, 0x00f5); AddFixed("CWD", CPU8086, 0x0099); AddFixed("DAA", CPU8086, 0x0027); AddFixed("DAS", CPU8086, 0x002f); AddFixed("HLT", CPU8086, 0x00f4); AddFixed("INTO", CPU8086, 0x00ce); AddFixed("IRET", CPU8086, 0x00cf); AddFixed("LAHF", CPU8086, 0x009f); AddFixed("LOCK", CPU8086, 0x00f0); AddFixed("NOP", CPU8086, 0x0090); AddFixed("POPF", CPU8086, 0x009d); AddFixed("PUSHF", CPU8086, 0x009c); AddFixed("SAHF", CPU8086, 0x009e); AddFixed("STC", CPU8086, 0x00f9); AddFixed("STD", CPU8086, 0x00fd); AddFixed("STI", CPU8086, 0x00fb); AddFixed("WAIT", CPU8086, 0x009b); AddFixed("XLAT", CPU8086, 0x00d7); AddFixed("LEAVE", CPU80186, 0x00c9); AddFixed("PUSHA", CPU80186, 0x0060); AddFixed("POPA", CPU80186, 0x0061); AddFixed("ADD4S", CPUV30, 0x0f20); AddFixed("SUB4S", CPUV30, 0x0f22); AddFixed("CMP4S", CPUV30, 0x0f26); AddFixed("STOP", CPUV35, 0x0f9e); AddFixed("RETRBI",CPUV35, 0x0f91); AddFixed("FINT", CPUV35, 0x0f92); AddFixed("MOVSPA",CPUV35, 0x0f25); AddFixed("SEGES", CPU8086, 0x0026); AddFixed("SEGCS", CPU8086, 0x002e); AddFixed("SEGSS", CPU8086, 0x0036); AddFixed("SEGDS", CPU8086, 0x003e); AddFixed("FWAIT", CPU8086, 0x009b); FPUFixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FPUFixedOrderCnt); InstrZ=0; AddFPUFixed("FCOMPP", CPU8086, 0xded9); AddFPUFixed("FTST", CPU8086, 0xd9e4); AddFPUFixed("FXAM", CPU8086, 0xd9e5); AddFPUFixed("FLDZ", CPU8086, 0xd9ee); AddFPUFixed("FLD1", CPU8086, 0xd9e8); AddFPUFixed("FLDPI", CPU8086, 0xd9eb); AddFPUFixed("FLDL2T", CPU8086, 0xd9e9); AddFPUFixed("FLDL2E", CPU8086, 0xd9ea); AddFPUFixed("FLDLG2", CPU8086, 0xd9ec); AddFPUFixed("FLDLN2", CPU8086, 0xd9ed); AddFPUFixed("FSQRT", CPU8086, 0xd9fa); AddFPUFixed("FSCALE", CPU8086, 0xd9fd); AddFPUFixed("FPREM", CPU8086, 0xd9f8); AddFPUFixed("FRNDINT",CPU8086, 0xd9fc); AddFPUFixed("FXTRACT",CPU8086, 0xd9f4); AddFPUFixed("FABS", CPU8086, 0xd9e1); AddFPUFixed("FCHS", CPU8086, 0xd9e0); AddFPUFixed("FPTAN", CPU8086, 0xd9f2); AddFPUFixed("FPATAN", CPU8086, 0xd9f3); AddFPUFixed("F2XM1", CPU8086, 0xd9f0); AddFPUFixed("FYL2X", CPU8086, 0xd9f1); AddFPUFixed("FYL2XP1",CPU8086, 0xd9f9); AddFPUFixed("FINIT", CPU8086, 0xdbe3); AddFPUFixed("FENI", CPU8086, 0xdbe0); AddFPUFixed("FDISI", CPU8086, 0xdbe1); AddFPUFixed("FCLEX", CPU8086, 0xdbe2); AddFPUFixed("FINCSTP",CPU8086, 0xd9f7); AddFPUFixed("FDECSTP",CPU8086, 0xd9f6); AddFPUFixed("FNOP", CPU8086, 0xd9d0); FPUStOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FPUStOrderCnt); InstrZ=0; AddFPUSt("FXCH", CPU8086, 0xd9c8); AddFPUSt("FFREE", CPU8086, 0xddc0); FPU16Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*FPU16OrderCnt); InstrZ=0; AddFPU16("FLDCW", CPU8086, 0xd928); AddFPU16("FSTCW", CPU8086, 0xd938); AddFPU16("FSTSW", CPU8086, 0xdd38); AddFPU16("FSTENV", CPU8086, 0xd930); AddFPU16("FLDENV", CPU8086, 0xd920); StringOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*StringOrderCnt); InstrZ=0; AddString("CMPSB", CPU8086, 0x00a6); AddString("CMPSW", CPU8086, 0x00a7); AddString("LODSB", CPU8086, 0x00ac); AddString("LODSW", CPU8086, 0x00ad); AddString("MOVSB", CPU8086, 0x00a4); AddString("MOVSW", CPU8086, 0x00a5); AddString("SCASB", CPU8086, 0x00ae); AddString("SCASW", CPU8086, 0x00af); AddString("STOSB", CPU8086, 0x00aa); AddString("STOSW", CPU8086, 0x00ab); AddString("INSB", CPU80186, 0x006c); AddString("INSW", CPU80186, 0x006d); AddString("OUTSB", CPU80186, 0x006e); AddString("OUTSW", CPU80186, 0x006f); ReptOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*ReptOrderCnt); InstrZ=0; AddRept("REP", CPU8086, 0x00f3); AddRept("REPE", CPU8086, 0x00f3); AddRept("REPZ", CPU8086, 0x00f3); AddRept("REPNE", CPU8086, 0x00f2); AddRept("REPNZ", CPU8086, 0x00f2); AddRept("REPC", CPUV30, 0x0065); AddRept("REPNC", CPUV30, 0x0064); RelOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*RelOrderCnt); InstrZ=0; AddRel("JA", CPU8086, 0x0077); AddRel("JNBE", CPU8086, 0x0077); AddRel("JAE", CPU8086, 0x0073); AddRel("JNB", CPU8086, 0x0073); AddRel("JB", CPU8086, 0x0072); AddRel("JNAE", CPU8086, 0x0072); AddRel("JBE", CPU8086, 0x0076); AddRel("JNA", CPU8086, 0x0076); AddRel("JC", CPU8086, 0x0072); AddRel("JCXZ", CPU8086, 0x00e3); AddRel("JE", CPU8086, 0x0074); AddRel("JZ", CPU8086, 0x0074); AddRel("JG", CPU8086, 0x007f); AddRel("JNLE", CPU8086, 0x007f); AddRel("JGE", CPU8086, 0x007d); AddRel("JNL", CPU8086, 0x007d); AddRel("JL", CPU8086, 0x007c); AddRel("JNGE", CPU8086, 0x007c); AddRel("JLE", CPU8086, 0x007e); AddRel("JNG", CPU8086, 0x007e); AddRel("JNC", CPU8086, 0x0073); AddRel("JNE", CPU8086, 0x0075); AddRel("JNZ", CPU8086, 0x0075); AddRel("JNO", CPU8086, 0x0071); AddRel("JNS", CPU8086, 0x0079); AddRel("JNP", CPU8086, 0x007b); AddRel("JPO", CPU8086, 0x007b); AddRel("JO", CPU8086, 0x0070); AddRel("JP", CPU8086, 0x007a); AddRel("JPE", CPU8086, 0x007a); AddRel("JS", CPU8086, 0x0078); AddRel("LOOP", CPU8086, 0x00e2); AddRel("LOOPE", CPU8086, 0x00e1); AddRel("LOOPZ", CPU8086, 0x00e1); AddRel("LOOPNE",CPU8086, 0x00e0); AddRel("LOOPNZ",CPU8086, 0x00e0); ModRegOrders=(FixedOrder *) malloc (sizeof(FixedOrder)*ModRegOrderCnt); InstrZ=0; AddModReg("LDS", CPU8086, 0x00c5); AddModReg("LEA", CPU8086, 0x008d); AddModReg("LES", CPU8086, 0x00c4); AddModReg("BOUND", CPU80186, 0x0062); ShiftOrders=(FixedOrder *) malloc (sizeof(FixedOrder)*ShiftOrderCnt); InstrZ=0; AddShift("SHL", CPU8086, 4); AddShift("SAL", CPU8086, 4); AddShift("SHR", CPU8086, 5); AddShift("SAR", CPU8086, 7); AddShift("ROL", CPU8086, 0); AddShift("ROR", CPU8086, 1); AddShift("RCL", CPU8086, 2); AddShift("RCR", CPU8086, 3); Reg16Orders=(AddOrder *) malloc(sizeof(AddOrder)*Reg16OrderCnt); InstrZ=0; AddReg16("BRKCS", CPUV35, 0x0f2d, 0xc0); AddReg16("TSKSW", CPUV35, 0x0f94, 0xf8); AddReg16("MOVSPB",CPUV35, 0x0f95, 0xf8); InstrZ=0; AddInstTable(InstTable,"ADD",InstrZ++,DecodeALU2); AddInstTable(InstTable,"OR" ,InstrZ++,DecodeALU2); AddInstTable(InstTable,"ADC",InstrZ++,DecodeALU2); AddInstTable(InstTable,"SBB",InstrZ++,DecodeALU2); AddInstTable(InstTable,"AND",InstrZ++,DecodeALU2); AddInstTable(InstTable,"SUB",InstrZ++,DecodeALU2); AddInstTable(InstTable,"XOR",InstrZ++,DecodeALU2); AddInstTable(InstTable,"CMP",InstrZ++,DecodeALU2); MulOrders=(char **) malloc(sizeof(char *)*MulOrderCnt); InstrZ=0; MulOrders[InstrZ++]="MUL"; MulOrders[InstrZ++]="IMUL"; MulOrders[InstrZ++]="DIV"; MulOrders[InstrZ++]="IDIV"; Bit1Orders=(char **) malloc(sizeof(char *)*Bit1OrderCnt); InstrZ=0; Bit1Orders[InstrZ++]="TEST1"; Bit1Orders[InstrZ++]="CLR1"; Bit1Orders[InstrZ++]="SET1"; Bit1Orders[InstrZ++]="NOT1"; END static void DeinitFields(void) BEGIN DestroyInstTable(InstTable); free(FixedOrders); free(FPUFixedOrders); free(FPUStOrders); free(FPU16Orders); free(StringOrders); free(ReptOrders); free(RelOrders); free(ModRegOrders); free(ShiftOrders); free(Reg16Orders); free(MulOrders); free(Bit1Orders); END static Boolean FMemo(char *Name) BEGIN String tmp; if (Memo(Name)) BEGIN AddPrefix(0x9b); return True; END else BEGIN strmaxcpy(tmp,Name,255); memmove(tmp+2,tmp+1,strlen(tmp)); tmp[1]='N'; return Memo(tmp); END END static Boolean DecodePseudo(void) BEGIN Boolean OK; int z,z2,z3; char *p; String SegPart,ValPart; if (Memo("PORT")) BEGIN CodeEquate(SegIO,0,0xffff); return True; END if (Memo("ASSUME")) BEGIN if (ArgCnt==0) WrError(1110); else BEGIN z=1; OK=True; while ((z<=ArgCnt) AND (OK)) BEGIN OK=False; p=QuotPos(ArgStr[z],':'); if (p!=Nil) BEGIN *p='\0'; strmaxcpy(SegPart,ArgStr[z],255); strmaxcpy(ValPart,p+1,255); END else BEGIN strmaxcpy(SegPart,ArgStr[z],255); *ValPart='\0'; END z2=0; while ((z2<=SegRegCnt) AND (strcasecmp(SegPart,SegRegNames[z2])!=0)) z2++; if (z2>SegRegCnt) WrXError(1962,SegPart); else BEGIN z3=0; while ((z3<=PCMax) AND (strcasecmp(ValPart,SegNames[z3])!=0)) z3++; if (z3>PCMax) WrXError(1961,ValPart); else if ((z3!=SegCode) AND (z3!=SegData) AND (z3!=SegXData) AND (z3!=SegNone)) WrError(1960); else BEGIN SegAssumes[z2]=z3; OK=True; END END z++; END END return True; END return False; END static Boolean DecodeFPU(void) BEGIN int z; Byte OpAdd; if (*OpPart!='F') return False; if (NOT FPUAvail) return False; for (z=0; z3)) WrError(1130); else BEGIN MoveAdr(2); BAsmCode[CodeLen+1]=AdrMode; switch (OpSize) BEGIN case 1: BAsmCode[CodeLen]=0xdf; break; case 2: BAsmCode[CodeLen]=0xdb; break; case 3: BAsmCode[CodeLen]=0xdf; BAsmCode[CodeLen+1]+=0x28; break; END CodeLen+=2+AdrCnt; END break; default: if (AdrType!=TypeNone) WrError(1350); END END return True; END if (FMemo("FBLD")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN DecodeAdr(ArgStr[1]); switch (AdrType) BEGIN case TypeMem: if ((OpSize==-1) AND (UnknownFlag)) OpSize=4; if (OpSize==-1) WrError(1132); else if (OpSize!=4) WrError(1130); else BEGIN BAsmCode[CodeLen]=0xdf; MoveAdr(2); BAsmCode[CodeLen+1]=AdrMode+0x20; CodeLen+=2+AdrCnt; END break; default: if (AdrType!=TypeNone) WrError(1350); END END return True; END if ((FMemo("FST")) OR (FMemo("FSTP"))) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN DecodeAdr(ArgStr[1]); switch (AdrType) BEGIN case TypeFReg: BAsmCode[CodeLen]=0xdd; BAsmCode[CodeLen+1]=0xd0+AdrMode; if (FMemo("FSTP")) BAsmCode[CodeLen+1]+=8; CodeLen+=2; break; case TypeMem: if ((OpSize==-1) AND (UnknownFlag)) OpSize=2; if (OpSize==-1) WrError(1132); else if ((OpSize<2) OR ((OpSize==4) AND (FMemo("FST")))) WrError(1130); else BEGIN MoveAdr(2); BAsmCode[CodeLen+1]=AdrMode+0x10; if (FMemo("FSTP")) BAsmCode[CodeLen+1]+=8; switch (OpSize) BEGIN case 2: BAsmCode[CodeLen]=0xd9; break; case 3: BAsmCode[CodeLen]=0xdd; case 4: BAsmCode[CodeLen]=0xdb; BAsmCode[CodeLen+1]+=0x20; break; END CodeLen+=2+AdrCnt; END break; default: if (AdrType!=TypeNone) WrError(1350); END END return True; END if ((FMemo("FIST")) OR (FMemo("FISTP"))) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN DecodeAdr(ArgStr[1]); switch (AdrType) BEGIN case TypeMem: if ((OpSize==-1) AND (UnknownFlag)) OpSize=1; if (OpSize==-1) WrError(1132); else if ((OpSize<1) OR (OpSize==4) OR ((OpSize==3) AND (FMemo("FIST")))) WrError(1130); else BEGIN MoveAdr(2); BAsmCode[CodeLen+1]=AdrMode+0x10; if (FMemo("FISTP")) BAsmCode[CodeLen+1]+=8; switch (OpSize) BEGIN case 1: BAsmCode[CodeLen]=0xdf; break; case 2: BAsmCode[CodeLen]=0xdb; break; case 3: BAsmCode[CodeLen]=0xdf; BAsmCode[CodeLen+1]=0x20; break; END CodeLen+=2+AdrCnt; END break; default: if (AdrType!=TypeNone) WrError(1350); END END return True; END if (FMemo("FBSTP")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN DecodeAdr(ArgStr[1]); switch (AdrType) BEGIN case TypeMem: if ((OpSize==-1) AND (UnknownFlag)) OpSize=1; if (OpSize==-1) WrError(1132); else if (OpSize!=4) WrError(1130); else BEGIN BAsmCode[CodeLen]=0xdf; BAsmCode[CodeLen+1]=AdrMode+0x30; MoveAdr(2); CodeLen+=2+AdrCnt; END break; default: if (AdrType!=TypeNone) WrError(1350); END END return True; END if ((FMemo("FCOM")) OR (FMemo("FCOMP"))) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN DecodeAdr(ArgStr[1]); switch (AdrType) BEGIN case TypeFReg: BAsmCode[CodeLen]=0xd8; BAsmCode[CodeLen+1]=0xd0+AdrMode; if (FMemo("FCOMP")) BAsmCode[CodeLen+1]+=8; CodeLen+=2; break; case TypeMem: if ((OpSize==-1) AND (UnknownFlag)) OpSize=1; if (OpSize==-1) WrError(1132); else if ((OpSize!=2) AND (OpSize!=3)) WrError(1130); else BEGIN BAsmCode[CodeLen]=(OpSize==2) ? 0xd8 : 0xdc; BAsmCode[CodeLen+1]=AdrMode+0x10; if (FMemo("FCOMP")) BAsmCode[CodeLen+1]+=8; MoveAdr(2); CodeLen+=2+AdrCnt; END; break; default: if (AdrType!=TypeNone) WrError(1350); END END return True; END if ((FMemo("FICOM")) OR (FMemo("FICOMP"))) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN DecodeAdr(ArgStr[1]); switch (AdrType) BEGIN case TypeMem: if ((OpSize==-1) AND (UnknownFlag)) OpSize=1; if (OpSize==-1) WrError(1132); else if ((OpSize!=1) AND (OpSize!=2)) WrError(1130); else BEGIN BAsmCode[CodeLen]=(OpSize==1) ? 0xde : 0xda; BAsmCode[CodeLen+1]=AdrMode+0x10; if (FMemo("FICOMP")) BAsmCode[CodeLen+1]+=8; MoveAdr(2); CodeLen+=2+AdrCnt; END break; default: if (AdrType!=TypeNone) WrError(1350); END END return True; END if ((FMemo("FADD")) OR (FMemo("FMUL"))) BEGIN OpAdd=0; if (FMemo("FMUL")) OpAdd+=8; if (ArgCnt==0) BEGIN BAsmCode[CodeLen]=0xde; BAsmCode[CodeLen+1]=0xc1+OpAdd; CodeLen+=2; return True; END if (ArgCnt==1) BEGIN strcpy (ArgStr[2],ArgStr[1]); strmaxcpy(ArgStr[1],"ST",255); ArgCnt++; END if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[1]); OpSize=(-1); switch (AdrType) BEGIN case TypeFReg: if (AdrMode!=0) /* ST(i) ist Ziel */ BEGIN BAsmCode[CodeLen+1]=AdrMode; DecodeAdr(ArgStr[2]); if ((AdrType!=TypeFReg) OR (AdrMode!=0)) WrError(1350); else BEGIN BAsmCode[CodeLen]=0xdc; BAsmCode[CodeLen+1]+=0xc0+OpAdd; CodeLen+=2; END END else /* ST ist Ziel */ BEGIN DecodeAdr(ArgStr[2]); switch (AdrType) BEGIN case TypeFReg: BAsmCode[CodeLen]=0xd8; BAsmCode[CodeLen+1]=0xc0+AdrMode+OpAdd; CodeLen+=2; break; case TypeMem: if ((OpSize==-1) AND (UnknownFlag)) OpSize=2; if (OpSize==-1) WrError(1132); else if ((OpSize!=2) AND (OpSize!=3)) WrError(1130); else BEGIN BAsmCode[CodeLen]=(OpSize==2) ? 0xd8 : 0xdc; BAsmCode[CodeLen+1]=AdrMode+OpAdd; MoveAdr(2); CodeLen+=AdrCnt+2; END break; default: if (AdrType!=TypeNone) WrError(1350); END END; break; default: if (AdrType!=TypeNone) WrError(1350); END END return True; END if ((FMemo("FIADD")) OR (FMemo("FIMUL"))) BEGIN OpAdd=0; if (FMemo("FIIMUL")) OpAdd+=8; if (ArgCnt==1) BEGIN ArgCnt=2; strcpy(ArgStr[2],ArgStr[1]); strmaxcpy(ArgStr[1],"ST",255); END if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[1]); switch (AdrType) BEGIN case TypeFReg: if (AdrMode!=0) WrError(1350); else BEGIN OpSize=(-1); DecodeAdr(ArgStr[2]); if ((AdrType!=TypeMem) AND (AdrType!=TypeNone)) WrError(1350); else if (AdrType!=TypeNone) BEGIN if ((OpSize==-1) AND (UnknownFlag)) OpSize=1; if (OpSize==-1) WrError(1132); else if ((OpSize!=1) AND (OpSize!=2)) WrError(1130); else BEGIN BAsmCode[CodeLen]=(OpSize==1) ? 0xde : 0xda; BAsmCode[CodeLen+1]=AdrMode+OpAdd; MoveAdr(2); CodeLen+=2+AdrCnt; END END END break; default: if (AdrType!=TypeNone) WrError(1350); END END return True; END if ((FMemo("FADDP")) OR (FMemo("FMULP"))) BEGIN OpAdd=0; if (FMemo("FMULP")) OpAdd+=8; if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[2]); switch (AdrType) BEGIN case TypeFReg: if (AdrMode!=0) WrError(1350); else BEGIN DecodeAdr(ArgStr[1]); if ((AdrType!=TypeFReg) AND (AdrType!=TypeNone)) WrError(1350); else if (AdrType!=TypeNone) BEGIN BAsmCode[CodeLen]=0xde; BAsmCode[CodeLen+1]=0xc0+AdrMode+OpAdd; CodeLen+=2; END END break; default: if (AdrType!=TypeNone) WrError(1350); END END return True; END if ((FMemo("FSUB")) OR (FMemo("FSUBR")) OR (FMemo("FDIV")) OR (FMemo("FDIVR"))) BEGIN OpAdd=0; if ((FMemo("FSUBR")) OR (FMemo("FDIVR"))) OpAdd+=8; if ((FMemo("FDIV")) OR (FMemo("FDIVR"))) OpAdd+=16; if (ArgCnt==0) BEGIN BAsmCode[CodeLen]=0xde; BAsmCode[CodeLen+1]=0xe1+(OpAdd ^ 8); CodeLen+=2; return True; END if (ArgCnt==1) BEGIN strcpy(ArgStr[2],ArgStr[1]); strmaxcpy(ArgStr[1],"ST",255); ArgCnt++; END if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[1]); OpSize=(-1); switch (AdrType) BEGIN case TypeFReg: if (AdrMode!=0) /* ST(i) ist Ziel */ BEGIN BAsmCode[CodeLen+1]=AdrMode; DecodeAdr(ArgStr[2]); switch (AdrType) BEGIN case TypeFReg: if (AdrMode!=0) WrError(1350); else BEGIN BAsmCode[CodeLen]=0xdc; BAsmCode[CodeLen+1]+=0xe0+(OpAdd ^ 8); CodeLen+=2; END break; default: if (AdrType!=TypeNone) WrError(1350); END END else /* ST ist Ziel */ BEGIN DecodeAdr(ArgStr[2]); switch (AdrType) BEGIN case TypeFReg: BAsmCode[CodeLen]=0xd8; BAsmCode[CodeLen+1]=0xe0+AdrMode+OpAdd; CodeLen+=2; break; case TypeMem: if ((OpSize==-1) AND (UnknownFlag)) OpSize=2; if (OpSize==-1) WrError(1132); else if ((OpSize!=2) AND (OpSize!=3)) WrError(1130); else BEGIN BAsmCode[CodeLen]=(OpSize==2) ? 0xd8 : 0xdc; BAsmCode[CodeLen+1]=AdrMode+0x20+OpAdd; MoveAdr(2); CodeLen+=AdrCnt+2; END break; default: if (AdrType!=TypeNone) WrError(1350); END END break; default: if (AdrType!=TypeNone) WrError(1350); END END return True; END if ((FMemo("FISUB")) OR (FMemo("FISUBR")) OR (FMemo("FIDIV")) OR (FMemo("FIDIVR"))) BEGIN OpAdd=0; if ((FMemo("FISUBR")) OR (Memo("FIDIVR"))) OpAdd+=8; if ((FMemo("FIDIV")) OR (Memo("FIDIVR"))) OpAdd+=16; if (ArgCnt==1) BEGIN ArgCnt=2; strcpy(ArgStr[2],ArgStr[1]); strmaxcpy(ArgStr[1],"ST",255); END if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[1]); switch (AdrType) BEGIN case TypeFReg: if (AdrMode!=0) WrError(1350); else BEGIN OpSize=(-1); DecodeAdr(ArgStr[2]); switch (AdrType) BEGIN case TypeMem: if ((OpSize==-1) AND (UnknownFlag)) OpSize=1; if (OpSize==-1) WrError(1132); else if ((OpSize!=1) AND (OpSize!=2)) WrError(1130); else BEGIN BAsmCode[CodeLen]=(OpSize==1) ? 0xde : 0xda; BAsmCode[CodeLen+1]=AdrMode+0x20+OpAdd; MoveAdr(2); CodeLen+=2+AdrCnt; END break; default: if (AdrType!=TypeNone) WrError(1350); END END break; default: if (AdrType!=TypeNone) WrError(1350); END END return True; END if ((FMemo("FSUBP")) OR (FMemo("FSUBRP")) OR (FMemo("FDIVP")) OR (FMemo("FDIVRP"))) BEGIN OpAdd=0; if ((Memo("FSUBRP")) OR (Memo("FDIVRP"))) OpAdd+=8; if ((Memo("FDIVP")) OR (Memo("FDIVRP"))) OpAdd+=16; if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[2]); switch (AdrType) BEGIN case TypeFReg: if (AdrMode!=0) WrError(1350); else BEGIN DecodeAdr(ArgStr[1]); switch (AdrType) BEGIN case TypeFReg: BAsmCode[CodeLen]=0xde; BAsmCode[CodeLen+1]=0xe0+AdrMode+(OpAdd ^ 8); CodeLen+=2; break; default: if (AdrType!=TypeNone) WrError(1350); END END break; default: if (AdrType!=TypeNone) WrError(1350); END END return True; END for (z=0; z=StringOrderCnt)WrError(1985); else if (MomCPU=0xff80) OR (AdrWord<0x80)) BEGIN CodeLen--; BAsmCode[CodeLen-AdrCnt-2-1]+=2; END END break; default: if (AdrType!=TypeNone) WrError(1350); END break; default: if (AdrType!=TypeNone) WrError(1350); END END break; default: WrError(1110); END AddPrefixes(); return; END; for (z=0; z15) WrError(1320); else BEGIN BAsmCode[CodeLen+1]+=8; BAsmCode[CodeLen+3]=AdrVals[1]; CodeLen+=4; END break; default: if (AdrType!=TypeNone) WrError(1350); END END END AddPrefixes(); return; END if (Memo("FPO2")) BEGIN if ((ArgCnt==0) OR (ArgCnt>2)) WrError(1110); else if (MomCPU> 3); BAsmCode[CodeLen+1]=(AdrByte & 7) << 3; if (ArgCnt==1) BEGIN BAsmCode[CodeLen+1]+=0xc0; CodeLen+=2; END else BEGIN DecodeAdr(ArgStr[2]); switch (AdrType) BEGIN case TypeReg8: BAsmCode[CodeLen+1]+=0xc0+AdrMode; CodeLen+=2; break; case TypeMem: BAsmCode[CodeLen+1]+=AdrMode; MoveAdr(2); CodeLen+=2+AdrCnt; break; default: if (AdrType!=TypeNone) WrError(1350); END END END END AddPrefixes(); return; END if (Memo("BTCLR")) BEGIN if (ArgCnt!=3) WrError(1110); else if (MomCPU0x7f) AND (AdrWord<0xff80))) WrError(1330); else BEGIN BAsmCode[CodeLen+4]=Lo(AdrWord); CodeLen+=5; END END END END AddPrefixes(); return; END for (z=0; z