2601 lines
67 KiB
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
|