diff options
Diffstat (limited to 'code86.c')
-rw-r--r-- | code86.c | 2600 |
1 files changed, 2600 insertions, 0 deletions
diff --git a/code86.c b/code86.c new file mode 100644 index 0000000..9c5ffe6 --- /dev/null +++ b/code86.c @@ -0,0 +1,2600 @@ +/* code86.c */ +/*****************************************************************************/ +/* AS-Portierung */ +/* */ +/* Codegenerator 8086/V-Serie */ +/* */ +/* Historie: */ +/* 2. 1.1999 ChkPC-Anpassung */ +/* */ +/*****************************************************************************/ + +#include "stdinc.h" +#include <string.h> + +#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 (MomCPU<CPU80186) WrError(1500); + else if (Index==1) WrError(1350); + else + BEGIN + BAsmCode[CodeLen]=0x68; + BAsmCode[CodeLen+1]=AdrVals[0]; + if (Sgn(AdrVals[0])==AdrVals[1]) + BEGIN + BAsmCode[CodeLen]+=2; CodeLen+=2; + END + else + BEGIN + BAsmCode[CodeLen+2]=AdrVals[1]; CodeLen+=3; + END + END + break; + default: + if (AdrType!=TypeNone) WrError(1350); + END + END + AddPrefixes(); +END + + static void DecodeNOTNEG(Word Index) +BEGIN + if (ArgCnt!=1) WrError(1110); + else + BEGIN + DecodeAdr(ArgStr[1]); + MinOneIs0(); + BAsmCode[CodeLen]=0xf6+OpSize; + BAsmCode[CodeLen+1]=0x10+Index; + switch (AdrType) + BEGIN + case TypeReg8: + case TypeReg16: + BAsmCode[CodeLen+1]+=0xc0+AdrMode; + CodeLen+=2; + break; + case TypeMem: + if (OpSize==-1) WrError(1132); + else + BEGIN + BAsmCode[CodeLen+1]+=AdrMode; + MoveAdr(2); + CodeLen+=2+AdrCnt; + END + break; + default: + if (AdrType!=TypeNone) WrError(1350); + END + END + AddPrefixes(); +END + + static void DecodeRET(Word Index) +BEGIN + Word AdrWord; + Boolean OK; + + if (ArgCnt>1) 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 (MomCPU<CPU80186) WrError(1500); + else + BEGIN + AdrWord=EvalIntExpression(ArgStr[1],Int16,&OK); + if (OK) + BEGIN + BAsmCode[CodeLen+1]=Lo(AdrWord); + BAsmCode[CodeLen+2]=Hi(AdrWord); + BAsmCode[CodeLen+3]=EvalIntExpression(ArgStr[2],Int8,&OK); + if (OK) + BEGIN + BAsmCode[CodeLen]=0xc8; CodeLen+=4; + END + END + END + AddPrefixes(); +END + + static void DecodeFixed(Word Index) +BEGIN + FixedOrder *FixedZ=FixedOrders+Index; + + if (ArgCnt!=0) WrError(1110); + else if (MomCPU<FixedZ->MinCPU) 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 (MomCPU<RelZ->MinCPU) 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; z<FPUFixedOrderCnt; z++) + if (FMemo(FPUFixedOrders[z].Name)) + BEGIN + if (ArgCnt!=0) WrError(1110); + else if (MomCPU<FPUFixedOrders[z].MinCPU) WrError(1500); + else PutCode(FPUFixedOrders[z].Code); + return True; + END + + for (z=0; z<FPUStOrderCnt; z++) + if (FMemo(FPUStOrders[z].Name)) + BEGIN + if (ArgCnt!=1) WrError(1110); + else + BEGIN + DecodeAdr(ArgStr[1]); + if (AdrType==TypeFReg) + BEGIN + PutCode(FPUStOrders[z].Code); BAsmCode[CodeLen-1]+=AdrMode; + END + else if (AdrType!=TypeNone) WrError(1350); + END + return True; + END + + if (FMemo("FLD")) + BEGIN + if (ArgCnt!=1) WrError(1110); + else + BEGIN + DecodeAdr(ArgStr[1]); + switch (AdrType) + BEGIN + case TypeFReg: + BAsmCode[CodeLen]=0xd9; BAsmCode[CodeLen+1]=0xc0+AdrMode; + CodeLen+=2; + break; + case TypeMem: + if ((OpSize==-1) AND (UnknownFlag)) OpSize=2; + if (OpSize==-1) WrError(1132); + else if (OpSize<2) WrError(1130); + else + BEGIN + MoveAdr(2); + BAsmCode[CodeLen+1]=AdrMode; + switch (OpSize) + BEGIN + case 2: BAsmCode[CodeLen]=0xd9; break; + case 3: BAsmCode[CodeLen]=0xdd; break; + case 4: BAsmCode[CodeLen]=0xdb; BAsmCode[CodeLen+1]+=0x28; break; + END + CodeLen+=2+AdrCnt; + END + break; + default: + if (AdrType!=TypeNone) WrError(1350); + END + END + return True; + END + + if (FMemo("FILD")) + 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>3)) 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<FPU16OrderCnt; z++) + if (FMemo(FPU16Orders[z].Name)) + BEGIN + if (ArgCnt!=1) WrError(1110); + else + BEGIN + OpSize=1; + DecodeAdr(ArgStr[1]); + switch (AdrType) + BEGIN + case TypeMem: + PutCode(FPU16Orders[z].Code); + BAsmCode[CodeLen-1]+=AdrMode; + MoveAdr(0); + CodeLen+=AdrCnt; + break; + default: + if (AdrType!=TypeNone) WrError(1350); + END + END + return True; + END + + if ((FMemo("FSAVE")) OR (FMemo("FRSTOR"))) + BEGIN + if (ArgCnt!=1) WrError(1110); + else + BEGIN + DecodeAdr(ArgStr[1]); + switch (AdrType) + BEGIN + case TypeMem: + BAsmCode[CodeLen]=0xdd; BAsmCode[CodeLen+1]=AdrMode+0x20; + if (Memo("FSAVE")) BAsmCode[CodeLen+1]+=0x10; + MoveAdr(2); + CodeLen+=2+AdrCnt; + break; + default: + if (AdrType!=TypeNone) WrError(1350); + END + END + return True; + END + + return False; +END + + static void MakeCode_86(void) +BEGIN + Boolean OK; + Word AdrWord; + Byte AdrByte; + int z,z2; + + CodeLen=0; DontPrint=False; OpSize=(-1); PrefixLen=0; + NoSegCheck=False; UnknownFlag=False; + + /* zu ignorierendes */ + + if (Memo("")) return; + + /* Pseudoanweisungen */ + + if (DecodePseudo()) return; + + if (DecodeIntelPseudo(False)) return; + + /* vermischtes */ + + if (LookupInstTable(InstTable,OpPart)) return; + + /* Koprozessor */ + + if (DecodeFPU()) + BEGIN + AddPrefixes(); return; + END + + /* Stringoperationen */ + + for (z=0; z<StringOrderCnt; z++) + if (Memo(StringOrders[z].Name)) + BEGIN + if (ArgCnt!=0) WrError(1110); + else if (MomCPU<StringOrders[z].MinCPU) WrError(1500); + else PutCode(StringOrders[z].Code); + AddPrefixes(); return; + END + + /* mit Wiederholung */ + + for (z=0; z<ReptOrderCnt; z++) + if (Memo(ReptOrders[z].Name)) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (MomCPU<ReptOrders[z].MinCPU) WrError(1500); + else + BEGIN + for (z2=0; z2<StringOrderCnt; z2++) + if (strcasecmp(StringOrders[z2].Name,ArgStr[1])==0) break; + if (z2>=StringOrderCnt)WrError(1985); + else if (MomCPU<StringOrders[z2].MinCPU) WrError(1500); + else + BEGIN + PutCode(ReptOrders[z].Code); PutCode(StringOrders[z2].Code); + END + END + AddPrefixes(); return; + END + + for (z=0; z<MulOrderCnt; z++) + if Memo(MulOrders[z]) + BEGIN + switch (ArgCnt) + BEGIN + case 1: + DecodeAdr(ArgStr[1]); + switch (AdrType) + BEGIN + case TypeReg8: + case TypeReg16: + BAsmCode[CodeLen]=0xf6+OpSize; + BAsmCode[CodeLen+1]=0xe0+(z << 3)+AdrMode; + CodeLen+=2; + break; + case TypeMem: + MinOneIs0(); + if (OpSize==-1) WrError(1132); + else + BEGIN + BAsmCode[CodeLen]=0xf6+OpSize; + BAsmCode[CodeLen+1]=0x20+(z << 3)+AdrMode; + MoveAdr(2); + CodeLen+=2+AdrCnt; + END + break; + default: + if (AdrType!=TypeNone) WrError(1350); + END + break; + case 2: + case 3: + if (MomCPU<CPU80186) WrError(1500); + else if (NOT Memo("IMUL")) WrError(1110); + else + BEGIN + if (ArgCnt==2) + BEGIN + strcpy(ArgStr[3],ArgStr[2]); strcpy(ArgStr[2],ArgStr[1]); ArgCnt++; + END + BAsmCode[CodeLen]=0x69; + DecodeAdr(ArgStr[1]); + switch (AdrType) + BEGIN + case TypeReg16: + BAsmCode[CodeLen+1]=(AdrMode << 3); + DecodeAdr(ArgStr[2]); + if (AdrType==TypeReg16) + BEGIN + AdrType=TypeMem; AdrMode+=0xc0; + END + switch (AdrType) + BEGIN + case TypeMem: + BAsmCode[CodeLen+1]+=AdrMode; + MoveAdr(2); + AdrWord=EvalIntExpression(ArgStr[3],Int16,&OK); + if (OK) + BEGIN + BAsmCode[CodeLen+2+AdrCnt]=Lo(AdrWord); + BAsmCode[CodeLen+3+AdrCnt]=Hi(AdrWord); + CodeLen+=2+AdrCnt+2; + if ((AdrWord>=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; z<ModRegOrderCnt; z++) + if (Memo(ModRegOrders[z].Name)) + BEGIN + NoSegCheck=Memo("LEA"); + if (ArgCnt!=2) WrError(1110); + else if (MomCPU<ModRegOrders[z].MinCPU) WrError(1500); + else + BEGIN + DecodeAdr(ArgStr[1]); + switch (AdrType) + BEGIN + case TypeReg16: + OpSize=(Memo("LEA")) ? -1 : 2; + AdrByte=(AdrMode << 3); + DecodeAdr(ArgStr[2]); + switch (AdrType) + BEGIN + case TypeMem: + PutCode(ModRegOrders[z].Code); + BAsmCode[CodeLen]=AdrByte+AdrMode; + MoveAdr(1); + CodeLen+=1+AdrCnt; + break; + default: + if (AdrType!=TypeNone) WrError(1350); + END + break; + default: + if (AdrType!=TypeNone) WrError(1350); + END + END + AddPrefixes(); return; + END + + for (z=0; z<ShiftOrderCnt; z++) + if (Memo(ShiftOrders[z].Name)) + BEGIN + if (ArgCnt!=2) WrError(1110); + else + BEGIN + DecodeAdr(ArgStr[1]); + MinOneIs0(); + if (OpSize==-1) WrError(1132); + else switch (AdrType) + BEGIN + case TypeReg8: + case TypeReg16: + case TypeMem: + BAsmCode[CodeLen]=OpSize; + BAsmCode[CodeLen+1]=AdrMode+(ShiftOrders[z].Code << 3); + if (AdrType!=TypeMem) BAsmCode[CodeLen+1]+=0xc0; + MoveAdr(2); + if (strcasecmp(ArgStr[2],"CL")==0) + BEGIN + BAsmCode[CodeLen]+=0xd2; + CodeLen+=2+AdrCnt; + END + else + BEGIN + BAsmCode[CodeLen+2+AdrCnt]=EvalIntExpression(ArgStr[2],Int8,&OK); + if (OK) + if (BAsmCode[CodeLen+2+AdrCnt]==1) + BEGIN + BAsmCode[CodeLen]+=0xd0; + CodeLen+=2+AdrCnt; + END + else if (MomCPU<CPU80186) WrError(1500); + else + BEGIN + BAsmCode[CodeLen]+=0xc0; + CodeLen+=3+AdrCnt; + END + END + break; + default: + if (AdrType!=TypeNone) WrError(1350); + END + END + AddPrefixes(); return; + END + + if ((Memo("ROL4")) OR (Memo("ROR4"))) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (MomCPU<CPUV30) WrError(1500); + else + BEGIN + DecodeAdr(ArgStr[1]); + BAsmCode[CodeLen ]=0x0f; + BAsmCode[CodeLen+1]=(Memo("ROL4")) ? 0x28 : 0x2a; + switch (AdrType) + BEGIN + case TypeReg8: + BAsmCode[CodeLen+2]=0xc0+AdrMode; + CodeLen+=3; + break; + case TypeMem: + BAsmCode[CodeLen+2]=AdrMode; + MoveAdr(3); + CodeLen+=3+AdrCnt; + break; + default: + if (AdrType!=TypeNone) WrError(1350); + END + END + AddPrefixes(); return; + END + + for (z=0; z<Bit1OrderCnt; z++) + if (Memo(Bit1Orders[z])) + BEGIN + if (ArgCnt!=2) WrError(1110); + else if (MomCPU<CPUV30) WrError(1500); + else + BEGIN + DecodeAdr(ArgStr[1]); + if ((AdrType==TypeReg8) OR (AdrType==TypeReg16)) + BEGIN + AdrMode+=0xc0; AdrType=TypeMem; + END + MinOneIs0(); + if (OpSize==-1) WrError(1132); + else switch (AdrType) + BEGIN + case TypeMem: + BAsmCode[CodeLen ]=0x0f; + BAsmCode[CodeLen+1]=0x10+(z << 1)+OpSize; + BAsmCode[CodeLen+2]=AdrMode; + MoveAdr(3); + if (strcasecmp(ArgStr[2],"CL")==0) CodeLen+=3+AdrCnt; + else + BEGIN + BAsmCode[CodeLen+1]+=8; + BAsmCode[CodeLen+3+AdrCnt]=EvalIntExpression(ArgStr[2],Int4,&OK); + if (OK) CodeLen+=4+AdrCnt; + END + break; + default: + if (AdrType!=TypeNone) WrError(1350); + END + END + AddPrefixes(); return; + END + + if ((Memo("INS")) OR (Memo("EXT"))) + BEGIN + if (ArgCnt!=2) WrError(1110); + else if (MomCPU<CPUV30) WrError(1500); + else + BEGIN + DecodeAdr(ArgStr[1]); + if (AdrType!=TypeNone) + if (AdrType!=TypeReg8) WrError(1350); + else + BEGIN + BAsmCode[CodeLen ]=0x0f; + BAsmCode[CodeLen+1]=0x31; + if (Memo("EXT")) BAsmCode[CodeLen+1]+=2; + BAsmCode[CodeLen+2]=0xc0+AdrMode; + DecodeAdr(ArgStr[2]); + switch (AdrType) + BEGIN + case TypeReg8: + BAsmCode[CodeLen+2]+=(AdrMode << 3); + CodeLen+=3; + break; + case TypeImm: + if (AdrVals[0]>15) 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<CPUV30) WrError(1500); + else + BEGIN + AdrByte=EvalIntExpression(ArgStr[1],Int4,&OK); + if (OK) + BEGIN + BAsmCode[CodeLen ]=0x66+(AdrByte >> 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 (MomCPU<CPUV35) WrError(1500); + else + BEGIN + BAsmCode[CodeLen ]=0x0f; + BAsmCode[CodeLen+1]=0x9c; + BAsmCode[CodeLen+2]=EvalIntExpression(ArgStr[1],Int8,&OK); + if (OK) + BEGIN + BAsmCode[CodeLen+3]=EvalIntExpression(ArgStr[2],UInt3,&OK); + if (OK) + BEGIN + AdrWord=EvalIntExpression(ArgStr[3],Int16,&OK)-(EProgCounter()+5); + if (OK) + if ((NOT SymbolQuestionable) AND ((AdrWord>0x7f) 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<Reg16OrderCnt; z++) + if (Memo(Reg16Orders[z].Name)) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (MomCPU<Reg16Orders[z].MinCPU) WrError(1500); + else + BEGIN + DecodeAdr(ArgStr[1]); + switch (AdrType) + BEGIN + case TypeReg16: + PutCode(Reg16Orders[z].Code); + BAsmCode[CodeLen++]=Reg16Orders[z].Add+AdrMode; + break; + default: + if (AdrType!=TypeNone) WrError(1350); + END + END + AddPrefixes(); return; + END + + WrXError(1200,OpPart); return; +END + + static void InitCode_86(void) +BEGIN + SaveInitProc(); + SegAssumes[0]=SegNone; /* ASSUME ES:NOTHING */ + SegAssumes[1]=SegCode; /* ASSUME CS:CODE */ + SegAssumes[2]=SegNone; /* ASSUME SS:NOTHING */ + SegAssumes[3]=SegData; /* ASSUME DS:DATA */ +END + + static Boolean IsDef_86(void) +BEGIN + return (Memo("PORT")); +END + + static void SwitchFrom_86(void) +BEGIN + DeinitFields(); ClearONOFF(); +END + + static void SwitchTo_86(void) +BEGIN + TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False; + + PCSymbol="$"; HeaderID=0x42; NOPCode=0x90; + DivideChars=","; HasAttrs=False; + + ValidSegs=(1<<SegCode)|(1<<SegData)|(1<<SegXData)|(1<<SegIO); + Grans[SegCode ]=1; ListGrans[SegCode ]=1; SegInits[SegCode ]=0; + SegLimits[SegCode ] = 0xffff; + Grans[SegData ]=1; ListGrans[SegData ]=1; SegInits[SegData ]=0; + SegLimits[SegData ] = 0xffff; + Grans[SegXData]=1; ListGrans[SegXData]=1; SegInits[SegXData]=0; + SegLimits[SegXData] = 0xffff; + Grans[SegIO ]=1; ListGrans[SegIO ]=1; SegInits[SegIO ]=0; + SegLimits[SegIO ] = 0xffff; + + MakeCode=MakeCode_86; IsDef=IsDef_86; + SwitchFrom=SwitchFrom_86; InitFields(); + AddONOFF("FPU",&FPUAvail,FPUAvailName,False); +END + + void code86_init(void) +BEGIN + CPU8086 =AddCPU("8086" ,SwitchTo_86); + CPU80186=AddCPU("80186",SwitchTo_86); + CPUV30 =AddCPU("V30" ,SwitchTo_86); + CPUV35 =AddCPU("V35" ,SwitchTo_86); + + SaveInitProc=InitPassProc; InitPassProc=InitCode_86; +END |