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/codexa.c

1976 lines
54 KiB
C

/* codexa.c */
/*****************************************************************************/
/* AS-Portierung */
/* */
/* AS-Codegenerator Philips XA */
/* */
/* Historie: 25.10.1996 Grundsteinlegung */
/* 19. 8.1998 autom. Verlaengerung Spruenge */
/* 23. 8.1998 Umbau auf Hash-Tabelle */
/* lange Spruenge fuer JBC */
/* 24. 8.1998 lange Spruenge fuer DJNZ CJNE */
/* 25. 8.1998 nach Hashing ueberfluessige Namensfelder entfernt */
/* 14.10.1998 BRANCHEXT auch fuer BR-Befehle */
/* Padding-Byte auch fuer Sprung auf sich selber */
/* Das $ zu verschieben ist aber noch etwas tricky... */
/* 9. 1.1999 ChkPC jetzt mit Adresse als Parameter */
/* 20. 1.1999 Formate maschinenunabhaengig gemacht */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <string.h>
#include <ctype.h>
#include "nls.h"
#include "strutil.h"
#include "bpemu.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "asmallg.h"
#include "asmitree.h"
#include "codepseudo.h"
#include "codevars.h"
/*-------------------------------------------------------------------------*/
/* Definitionen */
#define ModNone (-1)
#define ModReg 0
#define MModReg (1 << ModReg)
#define ModMem 1
#define MModMem (1 << ModMem)
#define ModImm 2
#define MModImm (1 << ModImm)
#define ModAbs 3
#define MModAbs (1 << ModAbs)
#define FixedOrderCnt 5
#define JBitOrderCnt 3
#define RegOrderCnt 4
#define RotateOrderCount 4
#define RelOrderCount 17
#define StackOrderCount 4
typedef struct
{
Word Code;
} FixedOrder;
typedef struct
{
Byte SizeMask;
Byte Code;
} RegOrder;
typedef struct
{
char *Name;
Byte SizeMask;
Byte Code;
Byte Inversion;
} InvOrder;
static CPUVar CPUXAG1,CPUXAG2,CPUXAG3;
static FixedOrder *FixedOrders;
static InvOrder *JBitOrders;
static FixedOrder *StackOrders;
static RegOrder *RegOrders;
static FixedOrder *RotateOrders;
static InvOrder *RelOrders;
static PInstTable InstTable;
static LongInt Reg_DS;
static SimpProc SaveInitProc;
static ShortInt AdrMode;
static Byte AdrPart,MemPart;
static Byte AdrVals[4];
static ShortInt OpSize;
/*-------------------------------------------------------------------------*/
/* Hilfsroutinen */
static void SetOpSize(ShortInt NSize)
BEGIN
if (OpSize==-1) OpSize=NSize;
else if (OpSize!=NSize)
BEGIN
AdrMode=ModNone; AdrCnt=0; WrError(1131);
END
END
static Boolean DecodeReg(char *Asc, ShortInt *NSize, Byte *Erg)
BEGIN
if (strcasecmp(Asc,"SP")==0)
BEGIN
*Erg=7; *NSize=1; return True;
END
else if ((strlen(Asc)>=2) AND (toupper(*Asc)=='R') AND (Asc[1]>='0') AND (Asc[1]<='7'))
if (strlen(Asc)==2)
BEGIN
*Erg=Asc[1]-'0';
if (OpSize==2)
BEGIN
if ((*Erg&1)==1)
BEGIN
WrError(1760); (*Erg)--;
END
*NSize=2;
return True;
END
else
BEGIN
*NSize=1;
return True;
END
END
else if ((strlen(Asc)==3) AND (toupper(Asc[2])=='L'))
BEGIN
*Erg=(Asc[1]-'0') << 1; *NSize=0; return True;
END
else if ((strlen(Asc)==3) AND (toupper(Asc[2])=='H'))
BEGIN
*Erg=((Asc[1]-'0') << 1)+1; *NSize=0; return True;
END
else return False;
return False;
END
static void ChkAdr(Word Mask)
BEGIN
if ((AdrMode!=ModNone) AND ((Mask & (1 << AdrMode))==0))
BEGIN
WrError(1350); AdrMode=ModNone; AdrCnt=0;
END
END
static void DecodeAdr(char *Asc, Word Mask)
BEGIN
ShortInt NSize;
LongInt DispAcc,DispPart,AdrLong;
Boolean FirstFlag,NegFlag,NextFlag,ErrFlag,OK;
char *PPos,*MPos;
Word AdrInt;
Byte Reg;
String Part;
AdrMode=ModNone; AdrCnt=0; KillBlanks(Asc);
if (DecodeReg(Asc,&NSize,&AdrPart))
BEGIN
if ((Mask & MModReg)!=0)
BEGIN
AdrMode=ModReg; SetOpSize(NSize);
END
else
BEGIN
AdrMode=ModMem; MemPart=1; SetOpSize(NSize);
END
ChkAdr(Mask); return;
END
if (*Asc=='#')
BEGIN
switch (OpSize)
BEGIN
case -4:
AdrVals[0]=EvalIntExpression(Asc+1,UInt5,&OK);
if (OK)
BEGIN
AdrCnt=1; AdrMode=ModImm;
END
break;
case -3:
AdrVals[0]=EvalIntExpression(Asc+1,SInt4,&OK);
if (OK)
BEGIN
AdrCnt=1; AdrMode=ModImm;
END
break;
case -2:
AdrVals[0]=EvalIntExpression(Asc+1,UInt4,&OK);
if (OK)
BEGIN
AdrCnt=1; AdrMode=ModImm;
END
break;
case -1:
WrError(1132);
break;
case 0:
AdrVals[0]=EvalIntExpression(Asc+1,Int8,&OK);
if (OK)
BEGIN
AdrCnt=1; AdrMode=ModImm;
END
break;
case 1:
AdrInt=EvalIntExpression(Asc+1,Int16,&OK);
if (OK)
BEGIN
AdrVals[0]=Hi(AdrInt); AdrVals[1]=Lo(AdrInt);
AdrCnt=2; AdrMode=ModImm;
END
break;
case 2:
AdrLong=EvalIntExpression(Asc+1,Int32,&OK);
if (OK)
BEGIN
AdrVals[0]=(AdrLong >> 24) & 0xff;
AdrVals[1]=(AdrLong >> 16) & 0xff;
AdrVals[2]=(AdrLong >> 8) & 0xff;
AdrVals[3]=AdrLong & 0xff;
AdrCnt=4; AdrMode=ModImm;
END
break;
END
ChkAdr(Mask); return;
END
if ((*Asc=='[') AND (Asc[strlen(Asc)-1]==']'))
BEGIN
strcpy(Asc,Asc+1); Asc[strlen(Asc)-1]='\0';
if (Asc[strlen(Asc)-1]=='+')
BEGIN
Asc[strlen(Asc)-1]='\0';
if (NOT DecodeReg(Asc,&NSize,&AdrPart)) WrXError(1445,Asc);
else if (NSize!=1) WrError(1350);
else
BEGIN
AdrMode=ModMem; MemPart=3;
END
END
else
BEGIN
FirstFlag=False; ErrFlag=False;
DispAcc=0; AdrPart=0xff; NegFlag=False;
while ((*Asc!='\0') AND (NOT ErrFlag))
BEGIN
PPos=QuotPos(Asc,'+'); MPos=QuotPos(Asc,'-');
if (PPos==Nil) PPos=MPos;
else if ((MPos!=Nil) AND (PPos>MPos)) PPos=MPos;
NextFlag=((PPos!=Nil) AND (*PPos=='-'));
if (PPos==Nil)
BEGIN
strmaxcpy(Part,Asc,255); *Asc='\0';
END
else
BEGIN
*PPos='\0'; strmaxcpy(Part,Asc,255); strcpy(Asc,PPos+1);
END
if (DecodeReg(Part,&NSize,&Reg))
if ((NSize!=1) OR (AdrPart!=0xff) OR (NegFlag))
BEGIN
WrError(1350); ErrFlag=True;
END
else AdrPart=Reg;
else
BEGIN
FirstPassUnknown=False;
DispPart=EvalIntExpression(Part,Int32,&ErrFlag);
ErrFlag=NOT ErrFlag;
if (NOT ErrFlag)
BEGIN
FirstFlag=FirstFlag OR FirstPassUnknown;
if (NegFlag) DispAcc-=DispPart;
else DispAcc+=DispPart;
END
END
NegFlag=NextFlag;
END
if (FirstFlag) DispAcc&=0x7fff;
if (AdrPart==0xff) WrError(1350);
else if (DispAcc==0)
BEGIN
AdrMode=ModMem; MemPart=2;
END
else if ((DispAcc>=-128) AND (DispAcc<127))
BEGIN
AdrMode=ModMem; MemPart=4;
AdrVals[0]=DispAcc & 0xff; AdrCnt=1;
END
else if (ChkRange(DispAcc,-0x8000l,0x7fffl))
BEGIN
AdrMode=ModMem; MemPart=5;
AdrVals[0]=(DispAcc >> 8) & 0xff;
AdrVals[1]=DispAcc & 0xff;
AdrCnt=2;
END
END
ChkAdr(Mask); return;
END
FirstPassUnknown=False;
AdrLong=EvalIntExpression(Asc,UInt24,&OK);
if (OK)
BEGIN
if (FirstPassUnknown)
BEGIN
if ((Mask & MModAbs)==0) AdrLong&=0x3ff;
END
if ((AdrLong & 0xffff)>0x7ff) WrError(1925);
else if ((AdrLong & 0xffff)<=0x3ff)
BEGIN
if ((AdrLong >> 16)!=Reg_DS) WrError(110);
ChkSpace(SegData);
AdrMode=ModMem; MemPart=6;
AdrPart=Hi(AdrLong); AdrVals[0]=Lo(AdrLong);
AdrCnt=1;
END
else if (AdrLong>0x7ff) WrError(1925);
else
BEGIN
ChkSpace(SegIO);
AdrMode=ModMem; MemPart=6;
AdrPart=Hi(AdrLong); AdrVals[0]=Lo(AdrLong);
AdrCnt=1;
END
END
ChkAdr(Mask);
END
static Boolean DecodeBitAddr(char *Asc, LongInt *Erg)
BEGIN
char *p;
Byte BPos,Reg;
ShortInt Size,Res;
LongInt AdrLong;
Boolean OK;
p=RQuotPos(Asc,'.'); Res=0;
if (p==Nil)
BEGIN
FirstPassUnknown=False;
AdrLong=EvalIntExpression(Asc,UInt24,&OK);
if (FirstPassUnknown) AdrLong&=0x3ff;
*Erg=AdrLong; Res=1;
END
else
BEGIN
FirstPassUnknown=False; *p='\0';
BPos=EvalIntExpression(p+1,UInt4,&OK);
if (FirstPassUnknown) BPos&=7;
if (OK)
BEGIN
if (DecodeReg(Asc,&Size,&Reg))
if ((Size==0) AND (BPos>7)) WrError(1320);
else
BEGIN
if (Size==0) *Erg=(Reg << 3)+BPos;
else *Erg=(Reg << 4)+BPos;
Res=1;
END
else if (BPos>7) WrError(1320);
else
BEGIN
FirstPassUnknown=False;
AdrLong=EvalIntExpression(Asc,UInt24,&OK);
if ((TypeFlag & (1 << SegIO))!=0)
BEGIN
ChkSpace(SegIO);
if (FirstPassUnknown) AdrLong=(AdrLong & 0x3f) | 0x400;
if (ChkRange(AdrLong,0x400,0x43f))
BEGIN
*Erg=0x200+((AdrLong & 0x3f) << 3)+BPos;
Res=1;
END
else Res=(-1);
END
else
BEGIN
ChkSpace(SegData);
if (FirstPassUnknown) AdrLong=(AdrLong & 0x00ff003f) | 0x20;
if (ChkRange(AdrLong & 0xff,0x20,0x3f))
BEGIN
*Erg=0x100+((AdrLong & 0x1f) << 3)+BPos+(AdrLong & 0xff0000);
Res=1;
END
else Res=(-1);
END
END
END
*p='.';
END
if (Res==0) WrError(1350);
return (Res==1);
END
static void ChkBitPage(LongInt Adr)
BEGIN
if ((Adr >> 16)!=Reg_DS) WrError(110);
END
/*-------------------------------------------------------------------------*/
/* Befehlsdekoder */
static Boolean DecodePseudo(void)
BEGIN
#define ASSUMEXACount 1
static ASSUMERec ASSUMEXAs[ASSUMEXACount]=
{{"DS", &Reg_DS, 0, 0xff, 0x100}};
LongInt BAdr;
if (Memo("PORT"))
BEGIN
CodeEquate(SegIO,0x400,0x7ff);
return True;
END
if (Memo("BIT"))
BEGIN
if (ArgCnt!=1) WrError(1110);
else if (*AttrPart!='\0') WrError(1100);
else if (DecodeBitAddr(ArgStr[1],&BAdr))
BEGIN
EnterIntSymbol(LabPart,BAdr,SegNone,False);
switch ((BAdr & 0x3ff) >> 8)
BEGIN
case 0:
sprintf(ListLine,"=R%d.%d", (int)((BAdr >> 4) & 15),
(int) (BAdr & 15));
break;
case 1:
sprintf(ListLine,"=%x:%x.%d",(int)((BAdr >> 16) & 255),
(int)((BAdr & 0x1f8) >> 3), (int)(BAdr & 7));
break;
default:
sprintf(ListLine, "=S:%x.%d", (int)(((BAdr >> 3) & 0x3f)+0x400),
(int)(BAdr & 7));
break;
END
END
return True;
END
if (Memo("ASSUME"))
BEGIN
CodeASSUME(ASSUMEXAs,ASSUMEXACount);
return True;
END
return False;
END
static void DecodeFixed(Word Index)
BEGIN
FixedOrder *Op=FixedOrders+Index;
if (ArgCnt!=0) WrError(1110);
else
BEGIN
if (Hi(Op->Code)!=0) BAsmCode[CodeLen++]=Hi(Op->Code);
BAsmCode[CodeLen++]=Lo(Op->Code);
if ((Memo("RETI")) AND (NOT SupAllowed)) WrError(50);
END
END
static void DecodeStack(Word Index)
BEGIN
FixedOrder *Op=StackOrders+Index;
Byte HReg;
Boolean OK;
Word Mask;
int i;
if (ArgCnt<1) WrError(1110);
else
BEGIN
HReg=0xff; OK=True; Mask=0;
for (i=1; i<=ArgCnt; i++)
if (OK)
BEGIN
DecodeAdr(ArgStr[i],MModMem);
if (AdrMode==ModNone) OK=False;
else switch (MemPart)
BEGIN
case 1:
if (HReg==0)
BEGIN
WrError(1350); OK=False;
END
else
BEGIN
HReg=1; Mask|=(1 << AdrPart);
END
break;
case 6:
if (HReg!=0xff)
BEGIN
WrError(1350); OK=False;
END
else HReg=0;
break;
default:
WrError(1350); OK=False;
END
END
if (OK)
if (OpSize==-1) WrError(1132);
else if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
else if (HReg==0)
BEGIN
BAsmCode[CodeLen++]=0x87+(OpSize << 3);
BAsmCode[CodeLen++]=Hi(Op->Code)+AdrPart;
BAsmCode[CodeLen++]=AdrVals[0];
END
else if (Index<2) /* POP: obere Register zuerst */
BEGIN
if (Hi(Mask)!=0)
BEGIN
BAsmCode[CodeLen++]=Lo(Op->Code)+(OpSize << 3)+0x40;
BAsmCode[CodeLen++]=Hi(Mask);
END
if (Lo(Mask)!=0)
BEGIN
BAsmCode[CodeLen++]=Lo(Op->Code)+(OpSize << 3);
BAsmCode[CodeLen++]=Lo(Mask);
END
if ((OpSize==1) AND (Memo("POP")) AND ((Mask & 0x80)!=0)) WrError(140);
END
else /* PUSH: untere Register zuerst */
BEGIN
if (Lo(Mask)!=0)
BEGIN
BAsmCode[CodeLen++]=Lo(Op->Code)+(OpSize << 3);
BAsmCode[CodeLen++]=Lo(Mask);
END
if (Hi(Mask)!=0)
BEGIN
BAsmCode[CodeLen++]=Lo(Op->Code)+(OpSize << 3)+0x40;
BAsmCode[CodeLen++]=Hi(Mask);
END
END
END
END
static void DecodeALU(Word Index)
BEGIN
Byte HReg,HCnt,HVals[3],HMem;
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg+MModMem);
switch (AdrMode)
BEGIN
case ModReg:
if (OpSize>=2) WrError(1130);
else if (OpSize==-1) WrError(1132);
else
BEGIN
HReg=AdrPart;
DecodeAdr(ArgStr[2],MModMem+MModImm);
switch (AdrMode)
BEGIN
case ModMem:
BAsmCode[CodeLen++]=(Index << 4)+(OpSize << 3)+MemPart;
BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
CodeLen+=AdrCnt;
if ((MemPart==3) AND ((HReg >> (1-OpSize))==AdrPart)) WrError(140);
break;
case ModImm:
BAsmCode[CodeLen++]=0x91+(OpSize << 3);
BAsmCode[CodeLen++]=(HReg << 4)+Index;
memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
CodeLen+=AdrCnt;
break;
END
END
break;
case ModMem:
HReg=AdrPart; HMem=MemPart; HCnt=AdrCnt;
memcpy(HVals,AdrVals,AdrCnt);
DecodeAdr(ArgStr[2],MModReg+MModImm);
switch (AdrMode)
BEGIN
case ModReg:
if (OpSize==2) WrError(1130);
else if (OpSize==-1) WrError(1132);
else
BEGIN
BAsmCode[CodeLen++]=(Index << 4)+(OpSize << 3)+HMem;
BAsmCode[CodeLen++]=(AdrPart << 4)+8+HReg;
memcpy(BAsmCode+CodeLen,HVals,HCnt);
CodeLen+=HCnt;
if ((HMem==3) AND ((AdrPart >> (1-OpSize))==HReg)) WrError(140);
END
break;
case ModImm:
if (OpSize==2) WrError(1130);
else if (OpSize==-1) WrError(1132);
else
BEGIN
BAsmCode[CodeLen++]=0x90+HMem+(OpSize << 3);
BAsmCode[CodeLen++]=(HReg << 4)+Index;
memcpy(BAsmCode+CodeLen,HVals,HCnt);
memcpy(BAsmCode+CodeLen+HCnt,AdrVals,AdrCnt);
CodeLen+=AdrCnt+HCnt;
END
break;
END
break;
END
END
END
static void DecodeRegO(Word Index)
BEGIN
RegOrder *Op=RegOrders+Index;
if (ArgCnt!=1) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg);
switch (AdrMode)
BEGIN
case ModReg:
if ((Op->SizeMask & (1 << OpSize))==0) WrError(1130);
else
BEGIN
BAsmCode[CodeLen++]=0x90+(OpSize << 3);
BAsmCode[CodeLen++]=(AdrPart << 4)+Op->Code;
END
break;
END
END
END
static void DecodeShift(Word Index)
BEGIN
Byte HReg,HMem;
if (ArgCnt!=2) WrError(1110);
else if (OpSize>2) WrError(1130);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg);
switch (AdrMode)
BEGIN
case ModReg:
HReg=AdrPart; HMem=OpSize;
if (*ArgStr[2]=='#') OpSize=(HMem==2)?-4:-2;
else OpSize=0;
DecodeAdr(ArgStr[2],MModReg+((Index==3)?0:MModImm));
switch (AdrMode)
BEGIN
case ModReg:
BAsmCode[CodeLen++]=0xc0+((HMem & 1) << 3)+Index;
if (HMem==2) BAsmCode[CodeLen-1]+=12;
BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
if (Memo("NORM"))
if (HMem==2)
BEGIN
if ((AdrPart >> 2)==(HReg >> 1)) WrError(140);
END
else if ((AdrPart >> HMem)==HReg) WrError(140);
break;
case ModImm:
BAsmCode[CodeLen++]=0xd0+((HMem & 1) << 3)+Index;
if (HMem==2)
BEGIN
BAsmCode[CodeLen-1]+=12;
BAsmCode[CodeLen++]=((HReg & 14) << 4)+AdrVals[0];
END
else BAsmCode[CodeLen++]=(HReg << 4)+AdrVals[0];
break;
END
break;
END
END
END
static void DecodeRotate(Word Index)
BEGIN
FixedOrder *Op=RotateOrders+Index;
Byte HReg,HMem;
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg);
switch (AdrMode)
BEGIN
case ModReg:
if (OpSize==2) WrError(1130);
else
BEGIN
HReg=AdrPart; HMem=OpSize; OpSize=(-2);
DecodeAdr(ArgStr[2],MModImm);
switch (AdrMode)
BEGIN
case ModImm:
BAsmCode[CodeLen++]=Op->Code+(HMem << 3);
BAsmCode[CodeLen++]=(HReg << 4)+AdrVals[0];
break;
END
END
break;
END
END
END
static void DecodeRel(Word Index)
BEGIN
InvOrder *Op=RelOrders+Index;
Boolean OK;
LongInt SaveLong,AdrLong;
if (ArgCnt!=1) WrError(1110);
else if (*AttrPart!='\0') WrError(1100);
else
BEGIN
FirstPassUnknown=True;
AdrLong=SaveLong=EvalIntExpression(ArgStr[1],UInt24,&OK);
if (OK)
BEGIN
ChkSpace(SegCode);
#ifdef __STDC__
if (FirstPassUnknown) AdrLong&=0xfffffffeu;
#else
if (FirstPassUnknown) AdrLong&=0xfffffffe;
#endif
AdrLong-=(EProgCounter()+CodeLen+2) & 0xfffffe;
if ((AdrLong&1)==1) WrError(1325);
else if ((SymbolQuestionable) OR ((AdrLong<=254) AND (AdrLong>=-256)))
BEGIN
BAsmCode[CodeLen++]=Op->Code;
BAsmCode[CodeLen++]=(AdrLong >> 1) & 0xff;
END
else if (NOT DoBranchExt) WrError(1370);
else if (Op->Inversion==255) /* BR */
BEGIN
AdrLong=SaveLong-((EProgCounter()+CodeLen+3) & 0xfffffe);
if ((NOT SymbolQuestionable) AND ((AdrLong>65534) OR (AdrLong<-65536))) WrError(1370);
else if ((AdrLong&1)==1) WrError(1325);
else
BEGIN
AdrLong>>=1;
BAsmCode[CodeLen++]=0xd5;
BAsmCode[CodeLen++]=(AdrLong >> 8) & 0xff;
BAsmCode[CodeLen++]=AdrLong & 0xff;
END
END
else
BEGIN
AdrLong=SaveLong-((EProgCounter()+CodeLen+5) & 0xfffffe);
if ((AdrLong>65534) OR (AdrLong<-65536)) WrError(1370);
else
BEGIN
BAsmCode[CodeLen++]=RelOrders[Op->Inversion].Code;
BAsmCode[CodeLen++]=2;
BAsmCode[CodeLen++]=0xd5;
BAsmCode[CodeLen++]=(AdrLong>>9)&0xff;
BAsmCode[CodeLen++]=(AdrLong>>1)&0xff;
if (Odd(EProgCounter()+CodeLen)) BAsmCode[CodeLen++]=0;
END
END
END
END
END
static void DecodeJBit(Word Index)
BEGIN
LongInt BitAdr,AdrLong,SaveLong,odd;
Boolean OK;
InvOrder *Op=JBitOrders+Index;
if (ArgCnt!=2) WrError(1110);
else if (*AttrPart!='\0') WrError(1100);
else if (DecodeBitAddr(ArgStr[1],&BitAdr))
BEGIN
FirstPassUnknown=False;
AdrLong=SaveLong=EvalIntExpression(ArgStr[2],UInt24,&OK);
if (OK)
BEGIN
#ifdef __STDC__
if (FirstPassUnknown) AdrLong&=0xfffffffeu;
#else
if (FirstPassUnknown) AdrLong&=0xfffffffe;
#endif
AdrLong-=(EProgCounter()+CodeLen+4) & 0xfffffe;
if ((AdrLong&1)==1) WrError(1325);
else if ((SymbolQuestionable) OR ((AdrLong<=254) AND (AdrLong>=-256)))
BEGIN
BAsmCode[CodeLen++]=0x97;
BAsmCode[CodeLen++]=Op->Code+Hi(BitAdr);
BAsmCode[CodeLen++]=Lo(BitAdr);
BAsmCode[CodeLen++]=(AdrLong >> 1) & 0xff;
END
else if (NOT DoBranchExt) WrError(1370);
else if (Op->Inversion==255)
BEGIN
odd=EProgCounter()&1;
AdrLong=SaveLong-((EProgCounter()+CodeLen+9+odd) & 0xfffffe);
if ((AdrLong>65534) OR (AdrLong<-65536)) WrError(1370);
else
BEGIN
BAsmCode[CodeLen++]=0x97;
BAsmCode[CodeLen++]=Op->Code+Hi(BitAdr);
BAsmCode[CodeLen++]=Lo(BitAdr);
BAsmCode[CodeLen++]=1+odd;
BAsmCode[CodeLen++]=0xfe;
BAsmCode[CodeLen++]=2+odd;
if (odd) BAsmCode[CodeLen++]=0;
BAsmCode[CodeLen++]=0xd5;
BAsmCode[CodeLen++]=(AdrLong>>9)&0xff;
BAsmCode[CodeLen++]=(AdrLong>>1)&0xff;
BAsmCode[CodeLen++]=0;
END
END
else
BEGIN
AdrLong=SaveLong-((EProgCounter()+CodeLen+7) & 0xfffffe);
if ((AdrLong>65534) OR (AdrLong<-65536)) WrError(1370);
else
BEGIN
BAsmCode[CodeLen++]=0x97;
BAsmCode[CodeLen++]=JBitOrders[Op->Inversion].Code+Hi(BitAdr);
BAsmCode[CodeLen++]=Lo(BitAdr);
BAsmCode[CodeLen++]=2;
BAsmCode[CodeLen++]=0xd5;
BAsmCode[CodeLen++]=(AdrLong>>9)&0xff;
BAsmCode[CodeLen++]=(AdrLong>>1)&0xff;
if (Odd(EProgCounter()+CodeLen)) BAsmCode[CodeLen++]=0;
END
END
END
END
END
static void DecodeMOV(Word Index)
BEGIN
LongInt AdrLong;
Byte HVals[3],HReg,HPart,HCnt;
if (ArgCnt!=2) WrError(1110);
else if (strcasecmp(ArgStr[1],"C")==0)
BEGIN
if (DecodeBitAddr(ArgStr[2],&AdrLong))
if (*AttrPart!='\0') WrError(1100);
else
BEGIN
ChkBitPage(AdrLong);
BAsmCode[CodeLen++]=0x08;
BAsmCode[CodeLen++]=0x20+Hi(AdrLong);
BAsmCode[CodeLen++]=Lo(AdrLong);
END
END
else if (strcasecmp(ArgStr[2],"C")==0)
BEGIN
if (DecodeBitAddr(ArgStr[1],&AdrLong))
if (*AttrPart!='\0') WrError(1100);
else
BEGIN
ChkBitPage(AdrLong);
BAsmCode[CodeLen++]=0x08;
BAsmCode[CodeLen++]=0x30+Hi(AdrLong);
BAsmCode[CodeLen++]=Lo(AdrLong);
END
END
else if (strcasecmp(ArgStr[1],"USP")==0)
BEGIN
SetOpSize(1);
DecodeAdr(ArgStr[2],MModReg);
if (AdrMode==ModReg)
BEGIN
BAsmCode[CodeLen++]=0x98;
BAsmCode[CodeLen++]=(AdrPart << 4)+0x0f;
END
END
else if (strcasecmp(ArgStr[2],"USP")==0)
BEGIN
SetOpSize(1);
DecodeAdr(ArgStr[1],MModReg);
if (AdrMode==ModReg)
BEGIN
BAsmCode[CodeLen++]=0x90;
BAsmCode[CodeLen++]=(AdrPart << 4)+0x0f;
END
END
else
BEGIN
DecodeAdr(ArgStr[1],MModReg+MModMem);
switch (AdrMode)
BEGIN
case ModReg:
if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
else
BEGIN
HReg=AdrPart;
DecodeAdr(ArgStr[2],MModMem+MModImm);
switch (AdrMode)
BEGIN
case ModMem:
BAsmCode[CodeLen++]=0x80+(OpSize << 3)+MemPart;
BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
CodeLen+=AdrCnt;
if ((MemPart==3) AND ((HReg >> (1-OpSize))==AdrPart)) WrError(140);
break;
case ModImm:
BAsmCode[CodeLen++]=0x91+(OpSize << 3);
BAsmCode[CodeLen++]=0x08+(HReg << 4);
memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
CodeLen+=AdrCnt;
break;
END
END
break;
case ModMem:
memcpy(HVals,AdrVals,AdrCnt); HCnt=AdrCnt; HPart=MemPart; HReg=AdrPart;
DecodeAdr(ArgStr[2],MModReg+MModMem+MModImm);
switch (AdrMode)
BEGIN
case ModReg:
if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
else
BEGIN
BAsmCode[CodeLen++]=0x80+(OpSize << 3)+HPart;
BAsmCode[CodeLen++]=(AdrPart << 4)+0x08+HReg;
memcpy(BAsmCode+CodeLen,HVals,HCnt);
CodeLen+=HCnt;
if ((HPart==3) AND ((AdrPart >> (1-OpSize))==HReg)) WrError(140);
END
break;
case ModMem:
if (OpSize==-1) WrError(1132);
else if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
else if ((HPart==6) AND (MemPart==6))
BEGIN
BAsmCode[CodeLen++]=0x97+(OpSize << 3);
BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
BAsmCode[CodeLen++]=HVals[0];
BAsmCode[CodeLen++]=AdrVals[0];
END
else if ((HPart==6) AND (MemPart==2))
BEGIN
BAsmCode[CodeLen++]=0xa0+(OpSize << 3);
BAsmCode[CodeLen++]=0x80+(AdrPart << 4)+HReg;
BAsmCode[CodeLen++]=HVals[0];
END
else if ((HPart==2) AND (MemPart==6))
BEGIN
BAsmCode[CodeLen++]=0xa0+(OpSize << 3);
BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
BAsmCode[CodeLen++]=AdrVals[0];
END
else if ((HPart==3) AND (MemPart==3))
BEGIN
BAsmCode[CodeLen++]=0x90+(OpSize << 3);
BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
if (HReg==AdrPart) WrError(140);
END
else WrError(1350);
break;
case ModImm:
if (OpSize==-1) WrError(1132);
else if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
else
BEGIN
BAsmCode[CodeLen++]=0x90+(OpSize << 3)+HPart;
BAsmCode[CodeLen++]=0x08+(HReg << 4);
memcpy(BAsmCode+CodeLen,HVals,HCnt);
memcpy(BAsmCode+CodeLen+HCnt,AdrVals,AdrCnt);
CodeLen+=HCnt+AdrCnt;
END
break;
END
break;
END
END
END
static void DecodeMOVC(Word Index)
BEGIN
Byte HReg;
if (ArgCnt!=2) WrError(1110);
else
BEGIN
if ((*AttrPart=='\0') AND (strcasecmp(ArgStr[1],"A")==0)) OpSize=0;
if (strcasecmp(ArgStr[2],"[A+DPTR]")==0)
if (strcasecmp(ArgStr[1],"A")!=0) WrError(1350);
else if (OpSize!=0) WrError(1130);
else
BEGIN
BAsmCode[CodeLen++]=0x90;
BAsmCode[CodeLen++]=0x4e;
END
else if (strcasecmp(ArgStr[2],"[A+PC]")==0)
if (strcasecmp(ArgStr[1],"A")!=0) WrError(1350);
else if (OpSize!=0) WrError(1130);
else
BEGIN
BAsmCode[CodeLen++]=0x90;
BAsmCode[CodeLen++]=0x4c;
END
else
BEGIN
DecodeAdr(ArgStr[1],MModReg);
if (AdrMode!=ModNone)
if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
else
BEGIN
HReg=AdrPart;
DecodeAdr(ArgStr[2],MModMem);
if (AdrMode!=ModNone)
if (MemPart!=3) WrError(1350);
else
BEGIN
BAsmCode[CodeLen++]=0x80+(OpSize << 3);
BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
if ((MemPart==3) AND ((HReg >> (1-OpSize))==AdrPart)) WrError(140);
END
END
END
END
END
static void DecodeMOVX(Word Index)
BEGIN
Byte HReg;
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModMem);
if (AdrMode==ModMem)
switch (MemPart)
BEGIN
case 1:
if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
else
BEGIN
HReg=AdrPart; DecodeAdr(ArgStr[2],MModMem);
if (AdrMode==ModMem)
if (MemPart!=2) WrError(1350);
else
BEGIN
BAsmCode[CodeLen++]=0xa7+(OpSize << 3);
BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
END
END
break;
case 2:
HReg=AdrPart; DecodeAdr(ArgStr[2],MModReg);
if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
else
BEGIN
BAsmCode[CodeLen++]=0xa7+(OpSize << 3);
BAsmCode[CodeLen++]=0x08+(AdrPart << 4)+HReg;
END
break;
default:
WrError(1350);
END
END
END
static void DecodeXCH(Word Index)
BEGIN
Byte HReg,HPart,HVals[3];
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModMem);
if (AdrMode==ModMem)
switch (MemPart)
BEGIN
case 1:
HReg=AdrPart; DecodeAdr(ArgStr[2],MModMem);
if (AdrMode==ModMem)
if ((OpSize!=1) AND (OpSize!=0)) WrError(1130);
else switch (MemPart)
BEGIN
case 1:
BAsmCode[CodeLen++]=0x60+(OpSize << 3);
BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
if (HReg==AdrPart) WrError(140);
break;
case 2:
BAsmCode[CodeLen++]=0x50+(OpSize << 3);
BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
break;
case 6:
BAsmCode[CodeLen++]=0xa0+(OpSize << 3);
BAsmCode[CodeLen++]=0x08+(HReg << 4)+AdrPart;
BAsmCode[CodeLen++]=AdrVals[0];
break;
default:
WrError(1350);
END
break;
case 2:
HReg=AdrPart;
DecodeAdr(ArgStr[2],MModReg);
if (AdrMode==ModReg)
if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
else
BEGIN
BAsmCode[CodeLen++]=0x50+(OpSize << 3);
BAsmCode[CodeLen++]=(AdrPart << 4)+HReg;
END
break;
case 6:
HPart=AdrPart; HVals[0]=AdrVals[0];
DecodeAdr(ArgStr[2],MModReg);
if (AdrMode==ModReg)
if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
else
BEGIN
BAsmCode[CodeLen++]=0xa0+(OpSize << 3);
BAsmCode[CodeLen++]=0x08+(AdrPart << 4)+HPart;
BAsmCode[CodeLen++]=HVals[0];
END
break;
default:
WrError(1350);
END
END
END
static void DecodeADDSMOVS(Word Index)
BEGIN
Byte HReg,HMem;
if (ArgCnt!=2) WrError(1110);
else
BEGIN
HMem=OpSize; OpSize=(-3);
DecodeAdr(ArgStr[2],MModImm);
switch (AdrMode)
BEGIN
case ModImm:
HReg=AdrVals[0]; OpSize=HMem;
DecodeAdr(ArgStr[1],MModMem);
switch (AdrMode)
BEGIN
case ModMem:
if (OpSize==2) WrError(1130);
else if (OpSize==-1) WrError(1132);
else
BEGIN
BAsmCode[CodeLen++]=0xa0+(Index << 4)+(OpSize << 3)+MemPart;
BAsmCode[CodeLen++]=(AdrPart << 4)+(HReg & 0x0f);
memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
CodeLen+=AdrCnt;
END
break;
END
break;
END
END
END
static void DecodeDIV(Word Index)
BEGIN
Byte HReg;
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg);
if (AdrMode==ModReg)
if ((OpSize!=1) AND (OpSize!=2)) WrError(1130);
else
BEGIN
HReg=AdrPart; OpSize--; DecodeAdr(ArgStr[2],MModReg+MModImm);
switch (AdrMode)
BEGIN
case ModReg:
BAsmCode[CodeLen++]=0xe7+(OpSize << 3);
BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
break;
case ModImm:
BAsmCode[CodeLen++]=0xe8+OpSize;
BAsmCode[CodeLen++]=(HReg << 4)+0x0b-(OpSize << 1);
memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
CodeLen+=AdrCnt;
break;
END
END
END
END
static void DecodeDIVU(Word Index)
BEGIN
Byte HReg;
int z;
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg);
if (AdrMode==ModReg)
if ((OpSize==0) AND ((AdrPart&1)==1)) WrError(1445);
else
BEGIN
HReg=AdrPart; z=OpSize; if (OpSize!=0) OpSize--;
DecodeAdr(ArgStr[2],MModReg+MModImm);
switch (AdrMode)
BEGIN
case ModReg:
BAsmCode[CodeLen++]=0xe1+(z << 2);
if (z==2) BAsmCode[CodeLen-1]+=4;
BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
break;
case ModImm:
BAsmCode[CodeLen++]=0xe8+Ord(z==2);
BAsmCode[CodeLen++]=(HReg << 4)+0x01+(Ord(z==1) << 1);
memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
CodeLen+=AdrCnt;
break;
END
END
END
END
static void DecodeMUL(Word Index)
BEGIN
Byte HReg;
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg);
if (AdrMode==ModReg)
if (OpSize!=1) WrError(1130);
else if ((AdrPart&1)==1) WrError(1445);
else
BEGIN
HReg=AdrPart; DecodeAdr(ArgStr[2],MModReg+MModImm);
switch (AdrMode)
BEGIN
case ModReg:
BAsmCode[CodeLen++]=0xe6;
BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
break;
case ModImm:
BAsmCode[CodeLen++]=0xe9;
BAsmCode[CodeLen++]=(HReg << 4)+0x08;
memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
CodeLen+=AdrCnt;
break;
END
END
END
END
static void DecodeMULU(Word Index)
BEGIN
Byte HReg;
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg);
if (AdrMode==ModReg)
if ((AdrPart&1)==1) WrError(1445);
else
BEGIN
HReg=AdrPart;
DecodeAdr(ArgStr[2],MModReg+MModImm);
switch (AdrMode)
BEGIN
case ModReg:
BAsmCode[CodeLen++]=0xe0+(OpSize << 2);
BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
break;
case ModImm:
BAsmCode[CodeLen++]=0xe8+OpSize;
BAsmCode[CodeLen++]=(HReg << 4);
memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
CodeLen+=AdrCnt;
break;
END
END
END
END
static void DecodeLEA(Word Index)
BEGIN
Byte HReg;
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg);
if (AdrMode==ModReg)
if (OpSize!=1) WrError(1130);
else
BEGIN
HReg=AdrPart;
strmaxprep(ArgStr[2],"[",255); strmaxcat(ArgStr[2],"]",255);
DecodeAdr(ArgStr[2],MModMem);
if (AdrMode==ModMem)
switch (MemPart)
BEGIN
case 4:
case 5:
BAsmCode[CodeLen++]=0x20+(MemPart << 3);
BAsmCode[CodeLen++]=(HReg << 4)+AdrPart;
memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
CodeLen+=AdrCnt;
break;
default:
WrError(1350);
END
END
END
END
static void DecodeANLORL(Word Index)
BEGIN
LongInt AdrLong;
Boolean OK;
if (ArgCnt!=2) WrError(1110);
else if (*AttrPart!='\0') WrError(1100);
else if (strcasecmp(ArgStr[1],"C")!=0) WrError(1350);
else
BEGIN
if (*ArgStr[2]=='/')
BEGIN
OK=True; strcpy(ArgStr[2],ArgStr[2]+1);
END
else OK=False;
if (DecodeBitAddr(ArgStr[2],&AdrLong))
BEGIN
ChkBitPage(AdrLong);
BAsmCode[CodeLen++]=0x08;
BAsmCode[CodeLen++]=0x40+(Index << 5)+(Ord(OK) << 4)+(Hi(AdrLong) & 3);
BAsmCode[CodeLen++]=Lo(AdrLong);
END
END
END
static void DecodeCLRSETB(Word Index)
BEGIN
LongInt AdrLong;
if (ArgCnt!=1) WrError(1110);
else if (*AttrPart!='\0') WrError(1100);
else if (DecodeBitAddr(ArgStr[1],&AdrLong))
BEGIN
ChkBitPage(AdrLong);
BAsmCode[CodeLen++]=0x08;
BAsmCode[CodeLen++]=(Index << 4)+(Hi(AdrLong) & 3);
BAsmCode[CodeLen++]=Lo(AdrLong);
END
END
static void DecodeTRAP(Word Index)
BEGIN
if (ArgCnt!=1) WrError(1110);
else if (*AttrPart!='\0') WrError(1100);
else
BEGIN
OpSize=(-2);
DecodeAdr(ArgStr[1],MModImm);
switch (AdrMode)
BEGIN
case ModImm:
BAsmCode[CodeLen++]=0xd6;
BAsmCode[CodeLen++]=0x30+AdrVals[0];
break;
END
END
END
static void DecodeCALL(Word Index)
BEGIN
LongInt AdrLong;
Boolean OK;
if (ArgCnt!=1) WrError(1110);
else if (*AttrPart!='\0') WrError(1100);
else if (*ArgStr[1]=='[')
BEGIN
DecodeAdr(ArgStr[1],MModMem);
if (AdrMode!=ModNone)
if (MemPart!=2) WrError(1350);
else
BEGIN
BAsmCode[CodeLen++]=0xc6;
BAsmCode[CodeLen++]=AdrPart;
END
END
else
BEGIN
FirstPassUnknown=False;
AdrLong=EvalIntExpression(ArgStr[1],UInt24,&OK);
if (OK)
BEGIN
ChkSpace(SegCode);
#ifdef __STDC__
if (FirstPassUnknown) AdrLong&=0xfffffffeu;
#else
if (FirstPassUnknown) AdrLong&=0xfffffffe;
#endif
AdrLong-=(EProgCounter()+CodeLen+3) & 0xfffffe;
if ((NOT SymbolQuestionable) AND ((AdrLong>65534) OR (AdrLong<-65536))) WrError(1370);
else if ((AdrLong&1)==1) WrError(1325);
else
BEGIN
AdrLong>>=1;
BAsmCode[CodeLen++]=0xc5;
BAsmCode[CodeLen++]=(AdrLong >> 8) & 0xff;
BAsmCode[CodeLen++]=AdrLong & 0xff;
END
END
END
END
static void DecodeJMP(Word Index)
BEGIN
LongInt AdrLong;
Boolean OK;
if (ArgCnt!=1) WrError(1110);
else if (*AttrPart!='\0') WrError(1100);
else if (strcasecmp(ArgStr[1],"[A+DPTR]")==0)
BEGIN
BAsmCode[CodeLen++]=0xd6;
BAsmCode[CodeLen++]=0x46;
END
else if (strncmp(ArgStr[1],"[[",2)==0)
BEGIN
ArgStr[1][strlen(ArgStr[1])-1]='\0';
DecodeAdr(ArgStr[1]+1,MModMem);
if (AdrMode==ModMem)
switch (MemPart)
BEGIN
case 3:
BAsmCode[CodeLen++]=0xd6;
BAsmCode[CodeLen++]=0x60+AdrPart;
break;
default:
WrError(1350);
END
END
else if (*ArgStr[1]=='[')
BEGIN
DecodeAdr(ArgStr[1],MModMem);
if (AdrMode==ModMem)
switch (MemPart)
BEGIN
case 2:
BAsmCode[CodeLen++]=0xd6;
BAsmCode[CodeLen++]=0x70+AdrPart;
break;
default:
WrError(1350);
END
END
else
BEGIN
FirstPassUnknown=False;
AdrLong=EvalIntExpression(ArgStr[1],UInt24,&OK);
if (OK)
BEGIN
ChkSpace(SegCode);
#ifdef __STDC__
if (FirstPassUnknown) AdrLong&=0xfffffffeu;
#else
if (FirstPassUnknown) AdrLong&=0xfffffffe;
#endif
AdrLong-=((EProgCounter()+CodeLen+3) & 0xfffffe);
if ((NOT SymbolQuestionable) AND ((AdrLong>65534) OR (AdrLong<-65536))) WrError(1370);
else if ((AdrLong&1)==1) WrError(1325);
else
BEGIN
AdrLong>>=1;
BAsmCode[CodeLen++]=0xd5;
BAsmCode[CodeLen++]=(AdrLong >> 8) & 0xff;
BAsmCode[CodeLen++]=AdrLong & 0xff;
END
END
END
END
static void DecodeCJNE(Word Index)
BEGIN
LongInt AdrLong,SaveLong,odd;
Boolean OK;
Byte HReg;
if (ArgCnt!=3) WrError(1110);
else
BEGIN
FirstPassUnknown=False;
AdrLong=SaveLong=EvalIntExpression(ArgStr[3],UInt24,&OK);
if (FirstPassUnknown) AdrLong&=0xfffffe;
if (OK)
BEGIN
ChkSpace(SegCode); OK=False; HReg=0;
DecodeAdr(ArgStr[1],MModMem);
if (AdrMode==ModMem)
switch (MemPart)
BEGIN
case 1:
if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
else
BEGIN
HReg=AdrPart; DecodeAdr(ArgStr[2],MModMem+MModImm);
switch (AdrMode)
BEGIN
case ModMem:
if (MemPart!=6) WrError(1350);
else
BEGIN
BAsmCode[CodeLen]=0xe2+(OpSize << 3);
BAsmCode[CodeLen+1]=(HReg << 4)+AdrPart;
BAsmCode[CodeLen+2]=AdrVals[0];
HReg=CodeLen+3;
CodeLen+=4; OK=True;
END
break;
case ModImm:
BAsmCode[CodeLen]=0xe3+(OpSize << 3);
BAsmCode[CodeLen+1]=HReg << 4;
HReg=CodeLen+2;
memcpy(BAsmCode+CodeLen+3,AdrVals,AdrCnt);
CodeLen+=3+AdrCnt; OK=True;
break;
END
END
break;
case 2:
if ((OpSize!=-1) AND (OpSize!=0) AND (OpSize!=1)) WrError(1130);
else
BEGIN
HReg=AdrPart; DecodeAdr(ArgStr[2],MModImm);
if (AdrMode==ModImm)
BEGIN
BAsmCode[CodeLen]=0xe3+(OpSize << 3);
BAsmCode[CodeLen+1]=(HReg << 4)+8;
HReg=CodeLen+2;
memcpy(BAsmCode+CodeLen+3,AdrVals,AdrCnt);
CodeLen+=3+AdrCnt; OK=True;
END
END
break;
default:
WrError(1350);
END
if (OK)
BEGIN
AdrLong-=(EProgCounter()+CodeLen) & 0xfffffe; OK=False;
if ((AdrLong&1)==1) WrError(1325);
else if ((SymbolQuestionable) OR ((AdrLong<=254) AND (AdrLong>=-256)))
BEGIN
BAsmCode[HReg]=(AdrLong >> 1) & 0xff; OK=True;
END
else if (NOT DoBranchExt) WrError(1370);
else
BEGIN
odd=(EProgCounter()+CodeLen) & 1;
AdrLong=SaveLong-((EProgCounter()+CodeLen+5+odd)&0xfffffe);
if ((AdrLong<-65536) OR (AdrLong>65534)) WrError(1370);
else
BEGIN
BAsmCode[HReg]=1+odd;
BAsmCode[CodeLen++]=0xfe;
BAsmCode[CodeLen++]=2+odd;
if (odd) BAsmCode[CodeLen++]=0;
BAsmCode[CodeLen++]=0xd5;
BAsmCode[CodeLen++]=(AdrLong >> 9) & 0xff;
BAsmCode[CodeLen++]=(AdrLong >> 1) & 0xff;
BAsmCode[CodeLen++]=0;
OK=True;
END
END
END
if (NOT OK) CodeLen=0;
END
END
END
static void DecodeDJNZ(Word Index)
BEGIN
LongInt AdrLong,SaveLong,odd;
Boolean OK;
Byte HReg;
if (ArgCnt!=2) WrError(1110);
else
BEGIN
FirstPassUnknown=False;
SaveLong=AdrLong=EvalIntExpression(ArgStr[2],UInt24,&OK);
if (FirstPassUnknown) AdrLong&=0xfffffe;
if (OK)
BEGIN
ChkSpace(SegCode); HReg=0;
DecodeAdr(ArgStr[1],MModMem);
OK=False; DecodeAdr(ArgStr[1],MModMem);
if (AdrMode==ModMem)
switch (MemPart)
BEGIN
case 1:
if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
else
BEGIN
BAsmCode[CodeLen]=0x87+(OpSize << 3);
BAsmCode[CodeLen+1]=(AdrPart << 4)+0x08;
HReg=CodeLen+2;
CodeLen+=3; OK=True;
END
break;
case 6:
if (OpSize==-1) WrError(1132);
else if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
else
BEGIN
BAsmCode[CodeLen]=0xe2+(OpSize << 3);
BAsmCode[CodeLen+1]=0x08+AdrPart;
BAsmCode[CodeLen+2]=AdrVals[0];
HReg=CodeLen+3;
CodeLen+=4; OK=True;
END
break;
default:
WrError(1350);
END
if (OK)
BEGIN
AdrLong-=(EProgCounter()+CodeLen) & 0xfffffe; OK=False;
if ((AdrLong&1)==1) WrError(1325);
else if ((SymbolQuestionable) OR ((AdrLong<=254) AND (AdrLong>=-256)))
BEGIN
BAsmCode[HReg]=(AdrLong >> 1) & 0xff; OK=True;
END
else if (NOT DoBranchExt) WrError(1370);
else
BEGIN
odd=(EProgCounter()+CodeLen) & 1;
AdrLong=SaveLong-((EProgCounter()+CodeLen+5+odd)&0xfffffe);
if ((AdrLong<-65536) OR (AdrLong>65534)) WrError(1370);
else
BEGIN
BAsmCode[HReg]=1+odd;
BAsmCode[CodeLen++]=0xfe;
BAsmCode[CodeLen++]=2+odd;
if (odd) BAsmCode[CodeLen++]=0;
BAsmCode[CodeLen++]=0xd5;
BAsmCode[CodeLen++]=(AdrLong >> 9) & 0xff;
BAsmCode[CodeLen++]=(AdrLong >> 1) & 0xff;
BAsmCode[CodeLen++]=0;
OK=True;
END
END
END
if (NOT OK) CodeLen=0;
END
END
END
static void DecodeFCALLJMP(Word Index)
BEGIN
LongInt AdrLong;
Boolean OK;
if (ArgCnt!=1) WrError(1110);
else if (*AttrPart!='\0') WrError(1100);
else
BEGIN
FirstPassUnknown=False;
AdrLong=EvalIntExpression(ArgStr[1],UInt24,&OK);
if (FirstPassUnknown) AdrLong&=0xfffffe;
if (OK)
if ((AdrLong&1)==1) WrError(1325);
else
BEGIN
BAsmCode[CodeLen++]=0xc4+(Index << 4);
BAsmCode[CodeLen++]=(AdrLong >> 8) & 0xff;
BAsmCode[CodeLen++]=AdrLong & 0xff;
BAsmCode[CodeLen++]=(AdrLong >> 16) & 0xff;
END
END
END
static Boolean IsRealDef(void)
BEGIN
return ((Memo("PORT")) OR (Memo("BIT")));
END
static void ForceAlign(void)
BEGIN
if ((EProgCounter()&1)==1)
BEGIN
BAsmCode[0]=NOPCode; CodeLen=1;
END
END
static void MakeCode_XA(void)
BEGIN
CodeLen=0; DontPrint=False; OpSize=(-1);
/* Operandengroesse */
if (*AttrPart!='\0')
switch (toupper(*AttrPart))
BEGIN
case 'B': SetOpSize(0); break;
case 'W': SetOpSize(1); break;
case 'D': SetOpSize(2); break;
default : WrError(1107); return;
END
/* Pseudoanweisungen */
if (DecodePseudo()) return;
/* Labels muessen auf geraden Adressen liegen */
if ( (ActPC==SegCode) AND (NOT IsRealDef()) AND
((*LabPart!='\0') OR ((ArgCnt == 1) AND (strcmp(ArgStr[1],"$")==0))) )
BEGIN
ForceAlign();
if (*LabPart!='\0')
EnterIntSymbol(LabPart,EProgCounter()+CodeLen,ActPC,False);
END
if (DecodeMoto16Pseudo(OpSize,False)) return;
if (DecodeIntelPseudo(False)) return;
/* zu ignorierendes */
if (Memo("")) return;
/* via Tabelle suchen */
if (NOT LookupInstTable(InstTable,OpPart)) WrXError(1200,OpPart);
END
/*-------------------------------------------------------------------------*/
/* Codetabellenverwaltung */
static void AddFixed(char *NName, Word NCode)
BEGIN
if (InstrZ>=FixedOrderCnt) exit(255);
FixedOrders[InstrZ].Code=NCode;
AddInstTable(InstTable,NName,InstrZ++,DecodeFixed);
END
static void AddJBit(char *NName, Word NCode)
BEGIN
if (InstrZ>=JBitOrderCnt) exit(255);
JBitOrders[InstrZ].Name=NName;
JBitOrders[InstrZ].Inversion=255;
JBitOrders[InstrZ].Code=NCode;
AddInstTable(InstTable,NName,InstrZ++,DecodeJBit);
END
static void AddStack(char *NName, Word NCode)
BEGIN
if (InstrZ>=StackOrderCount) exit(255);
StackOrders[InstrZ].Code=NCode;
AddInstTable(InstTable,NName,InstrZ++,DecodeStack);
END
static void AddReg(char *NName, Byte NMask, Byte NCode)
BEGIN
if (InstrZ>=RegOrderCnt) exit(255);
RegOrders[InstrZ].Code=NCode;
RegOrders[InstrZ].SizeMask=NMask;
AddInstTable(InstTable,NName,InstrZ++,DecodeRegO);
END
static void AddRotate(char *NName, Word NCode)
BEGIN
if (InstrZ>=RotateOrderCount) exit(255);
RotateOrders[InstrZ].Code=NCode;
AddInstTable(InstTable,NName,InstrZ++,DecodeRotate);
END
static void AddRel(char *NName, Word NCode)
BEGIN
if (InstrZ>=RelOrderCount) exit(255);
RelOrders[InstrZ].Name=NName;
RelOrders[InstrZ].Inversion=255;
RelOrders[InstrZ].Code=NCode;
AddInstTable(InstTable,NName,InstrZ++,DecodeRel);
END
static void SetInv(char *Name1, char *Name2, InvOrder *Orders)
BEGIN
InvOrder *Order1,*Order2;
for (Order1=Orders; strcmp(Order1->Name,Name1)!=0; Order1++);
for (Order2=Orders; strcmp(Order2->Name,Name2)!=0; Order2++);
Order1->Inversion=Order2-Orders;
Order2->Inversion=Order1-Orders;
END
static void InitFields(void)
BEGIN
InstTable=CreateInstTable(201);
AddInstTable(InstTable,"MOV" ,0,DecodeMOV);
AddInstTable(InstTable,"MOVC",0,DecodeMOVC);
AddInstTable(InstTable,"MOVX",0,DecodeMOVX);
AddInstTable(InstTable,"XCH" ,0,DecodeXCH);
AddInstTable(InstTable,"ADDS",0,DecodeADDSMOVS);
AddInstTable(InstTable,"MOVS",1,DecodeADDSMOVS);
AddInstTable(InstTable,"DIV" ,0,DecodeDIV);
AddInstTable(InstTable,"DIVU",0,DecodeDIVU);
AddInstTable(InstTable,"MUL" ,0,DecodeMUL);
AddInstTable(InstTable,"DIVU",0,DecodeDIVU);
AddInstTable(InstTable,"MULU",0,DecodeMULU);
AddInstTable(InstTable,"LEA" ,0,DecodeLEA);
AddInstTable(InstTable,"ANL" ,0,DecodeANLORL);
AddInstTable(InstTable,"ORL" ,1,DecodeANLORL);
AddInstTable(InstTable,"CLR" ,0,DecodeCLRSETB);
AddInstTable(InstTable,"SETB",1,DecodeCLRSETB);
AddInstTable(InstTable,"TRAP",0,DecodeTRAP);
AddInstTable(InstTable,"CALL",0,DecodeCALL);
AddInstTable(InstTable,"JMP" ,0,DecodeJMP);
AddInstTable(InstTable,"CJNE",0,DecodeCJNE);
AddInstTable(InstTable,"DJNZ",0,DecodeDJNZ);
AddInstTable(InstTable,"FCALL",0,DecodeFCALLJMP);
AddInstTable(InstTable,"FJMP",1,DecodeFCALLJMP);
FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); InstrZ=0;
AddFixed("NOP" ,0x0000);
AddFixed("RET" ,0xd680);
AddFixed("RETI" ,0xd690);
AddFixed("BKPT" ,0x00ff);
AddFixed("RESET",0xd610);
JBitOrders=(InvOrder *) malloc(sizeof(InvOrder)*JBitOrderCnt); InstrZ=0;
AddJBit("JB" ,0x80);
AddJBit("JBC" ,0xc0);
AddJBit("JNB" ,0xa0);
SetInv("JB","JNB",JBitOrders);
StackOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*StackOrderCount); InstrZ=0;
AddStack("POP" ,0x1027);
AddStack("POPU" ,0x0037);
AddStack("PUSH" ,0x3007);
AddStack("PUSHU",0x2017);
InstrZ=0;
AddInstTable(InstTable,"ADD" ,InstrZ++,DecodeALU);
AddInstTable(InstTable,"ADDC",InstrZ++,DecodeALU);
AddInstTable(InstTable,"SUB" ,InstrZ++,DecodeALU);
AddInstTable(InstTable,"SUBB",InstrZ++,DecodeALU);
AddInstTable(InstTable,"CMP" ,InstrZ++,DecodeALU);
AddInstTable(InstTable,"AND" ,InstrZ++,DecodeALU);
AddInstTable(InstTable,"OR" ,InstrZ++,DecodeALU);
AddInstTable(InstTable,"XOR" ,InstrZ++,DecodeALU);
RegOrders=(RegOrder *) malloc(sizeof(RegOrder)*RegOrderCnt); InstrZ=0;
AddReg("NEG" ,3,0x0b);
AddReg("CPL" ,3,0x0a);
AddReg("SEXT",3,0x09);
AddReg("DA" ,1,0x08);
InstrZ=0;
AddInstTable(InstTable,"LSR" ,InstrZ++,DecodeShift);
AddInstTable(InstTable,"ASL" ,InstrZ++,DecodeShift);
AddInstTable(InstTable,"ASR" ,InstrZ++,DecodeShift);
AddInstTable(InstTable,"NORM",InstrZ++,DecodeShift);
RotateOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*RotateOrderCount); InstrZ=0;
AddRotate("RR" ,0xb0); AddRotate("RL" ,0xd3);
AddRotate("RRC",0xb7); AddRotate("RLC",0xd7);
RelOrders=(InvOrder *) malloc(sizeof(InvOrder)*RelOrderCount); InstrZ=0;
AddRel("BCC",0xf0); AddRel("BCS",0xf1); AddRel("BNE",0xf2);
AddRel("BEQ",0xf3); AddRel("BNV",0xf4); AddRel("BOV",0xf5);
AddRel("BPL",0xf6); AddRel("BMI",0xf7); AddRel("BG" ,0xf8);
AddRel("BL" ,0xf9); AddRel("BGE",0xfa); AddRel("BLT",0xfb);
AddRel("BGT",0xfc); AddRel("BLE",0xfd); AddRel("BR" ,0xfe);
AddRel("JZ" ,0xec); AddRel("JNZ",0xee);
SetInv("BCC","BCS",RelOrders);
SetInv("BNE","BEQ",RelOrders);
SetInv("BNV","BOV",RelOrders);
SetInv("BPL","BMI",RelOrders);
SetInv("BG" ,"BL" ,RelOrders);
SetInv("BGE","BLT",RelOrders);
SetInv("BGT","BLE",RelOrders);
SetInv("JZ" ,"JNZ",RelOrders);
END
static void DeinitFields(void)
BEGIN
free(FixedOrders);
free(JBitOrders);
free(StackOrders);
free(RegOrders);
free(RotateOrders);
free(RelOrders);
DestroyInstTable(InstTable);
END
/*-------------------------------------------------------------------------*/
/* Callbacks */
static void InitCode_XA(void)
BEGIN
SaveInitProc();
Reg_DS=0;
END
static Boolean ChkPC_XA(LargeWord Addr)
BEGIN
switch (ActPC)
BEGIN
case SegCode:
case SegData:
return (Addr<0x1000000);
case SegIO:
return ((Addr>0x3ff) AND (Addr<0x800));
default:
return False;
END
END
static Boolean IsDef_XA(void)
BEGIN
return (ActPC==SegCode);
END
static void SwitchFrom_XA(void)
BEGIN
DeinitFields(); ClearONOFF();
END
static void SwitchTo_XA(void)
BEGIN
TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False;
PCSymbol="$"; HeaderID=0x3c; NOPCode=0x00;
DivideChars=","; HasAttrs=True; AttrChars=".";
ValidSegs=(1<<SegCode)|(1<<SegData)|(1<<SegIO);
Grans[SegCode ]=1; ListGrans[SegCode ]=1; SegInits[SegCode ]=0;
Grans[SegData ]=1; ListGrans[SegData ]=1; SegInits[SegData ]=0;
Grans[SegIO ]=1; ListGrans[SegIO ]=1; SegInits[SegIO ]=0x400;
MakeCode=MakeCode_XA; ChkPC=ChkPC_XA; IsDef=IsDef_XA;
SwitchFrom=SwitchFrom_XA; InitFields();
AddONOFF("SUPMODE", &SupAllowed, SupAllowedName,False);
AddONOFF("BRANCHEXT",&DoBranchExt,BranchExtName ,False);
AddMoto16PseudoONOFF();
SetFlag(&DoPadding,DoPaddingName,False);
END
void codexa_init(void)
BEGIN
CPUXAG1=AddCPU("XAG1",SwitchTo_XA);
CPUXAG2=AddCPU("XAG2",SwitchTo_XA);
CPUXAG3=AddCPU("XAG3",SwitchTo_XA);
SaveInitProc=InitPassProc; InitPassProc=InitCode_XA;
END