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