aboutsummaryrefslogtreecommitdiffstats
path: root/code86.c
diff options
context:
space:
mode:
Diffstat (limited to 'code86.c')
-rw-r--r--code86.c2600
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