dect
/
asl
Archived
13
0
Fork 0
This repository has been archived on 2022-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
asl/code86.c

2601 lines
67 KiB
C

/* 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