1698 lines
42 KiB
C
1698 lines
42 KiB
C
/* code166.c */
|
|
/*****************************************************************************/
|
|
/* AS-Portierung */
|
|
/* */
|
|
/* AS-Codegenerator Siemens 80C16x */
|
|
/* */
|
|
/* Historie: 11.11.1996 (alaaf) Grundsteinlegung */
|
|
/* 9. 5.1998 Registersymbole */
|
|
/* 3. 1.1999 ChkPC angepasst */
|
|
/* */
|
|
/*****************************************************************************/
|
|
|
|
#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 "codepseudo.h"
|
|
#include "codevars.h"
|
|
|
|
typedef struct
|
|
{
|
|
char *Name;
|
|
CPUVar MinCPU;
|
|
Word Code1,Code2;
|
|
} BaseOrder;
|
|
|
|
typedef struct
|
|
{
|
|
char *Name;
|
|
Byte Code;
|
|
} SimpOrder;
|
|
|
|
typedef struct
|
|
{
|
|
char *Name;
|
|
Byte Code;
|
|
} Condition;
|
|
|
|
|
|
#define FixedOrderCount 10
|
|
#define ConditionCount 20
|
|
#define ALU2OrderCount 8
|
|
#define ShiftOrderCount 5
|
|
#define Bit2OrderCount 6
|
|
#define LoopOrderCount 4
|
|
#define DivOrderCount 4
|
|
#define BJmpOrderCount 4
|
|
#define MulOrderCount 3
|
|
|
|
#define DPPCount 4
|
|
static char *RegNames[6]={"DPP0","DPP1","DPP2","DPP3","CP","SP"};
|
|
|
|
static CPUVar CPU80C166,CPU80C167;
|
|
|
|
static BaseOrder *FixedOrders;
|
|
static Condition *Conditions;
|
|
static int TrueCond;
|
|
static char **ALU2Orders;
|
|
static SimpOrder *ShiftOrders;
|
|
static SimpOrder *Bit2Orders;
|
|
static SimpOrder *LoopOrders;
|
|
static char **DivOrders;
|
|
static char **BJmpOrders;
|
|
static char **MulOrders;
|
|
|
|
static SimpProc SaveInitProc;
|
|
static LongInt DPPAssumes[DPPCount];
|
|
static IntType MemInt,MemInt2;
|
|
static Byte OpSize;
|
|
|
|
static Boolean DPPChanged[DPPCount],N_DPPChanged[DPPCount];
|
|
static Boolean SPChanged,CPChanged,N_SPChanged,N_CPChanged;
|
|
|
|
static ShortInt ExtCounter;
|
|
static enum {MemModeStd,MemModeNoCheck,MemModeZeroPage,MemModeFixedBank,MemModeFixedPage} MemMode;
|
|
/* normal EXTS Rn EXTP Rn EXTS nn EXTP nn */
|
|
static Word MemPage;
|
|
static Boolean ExtSFRs;
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
static void AddFixed(char *NName, CPUVar NMin, Word NCode1, Word NCode2)
|
|
BEGIN
|
|
if (InstrZ>=FixedOrderCount) exit(255);
|
|
FixedOrders[InstrZ].Name=NName;
|
|
FixedOrders[InstrZ].MinCPU=NMin;
|
|
FixedOrders[InstrZ].Code1=NCode1;
|
|
FixedOrders[InstrZ++].Code2=NCode2;
|
|
END
|
|
|
|
static void AddShift(char *NName, Byte NCode)
|
|
BEGIN
|
|
if (InstrZ>=ShiftOrderCount) exit(255);
|
|
ShiftOrders[InstrZ].Name=NName;
|
|
ShiftOrders[InstrZ++].Code=NCode;
|
|
END
|
|
|
|
static void AddBit2(char *NName, Byte NCode)
|
|
BEGIN
|
|
if (InstrZ>=Bit2OrderCount) exit(255);
|
|
Bit2Orders[InstrZ].Name=NName;
|
|
Bit2Orders[InstrZ++].Code=NCode;
|
|
END
|
|
|
|
static void AddLoop(char *NName, Byte NCode)
|
|
BEGIN
|
|
if (InstrZ>=LoopOrderCount) exit(255);
|
|
LoopOrders[InstrZ].Name=NName;
|
|
LoopOrders[InstrZ++].Code=NCode;
|
|
END
|
|
|
|
static void AddCondition(char *NName, Byte NCode)
|
|
BEGIN
|
|
if (InstrZ>=ConditionCount) exit(255);
|
|
Conditions[InstrZ].Name=NName;
|
|
Conditions[InstrZ++].Code=NCode;
|
|
END
|
|
|
|
static void InitFields(void)
|
|
BEGIN
|
|
FixedOrders=(BaseOrder *) malloc(FixedOrderCount*sizeof(BaseOrder)); InstrZ=0;
|
|
AddFixed("DISWDT",CPU80C166,0x5aa5,0xa5a5);
|
|
AddFixed("EINIT" ,CPU80C166,0x4ab5,0xb5b5);
|
|
AddFixed("IDLE" ,CPU80C166,0x7887,0x8787);
|
|
AddFixed("NOP" ,CPU80C166,0x00cc,0x0000);
|
|
AddFixed("PWRDN" ,CPU80C166,0x6897,0x9797);
|
|
AddFixed("RET" ,CPU80C166,0x00cb,0x0000);
|
|
AddFixed("RETI" ,CPU80C166,0x88fb,0x0000);
|
|
AddFixed("RETS" ,CPU80C166,0x00db,0x0000);
|
|
AddFixed("SRST" ,CPU80C166,0x48b7,0xb7b7);
|
|
AddFixed("SRVWDT",CPU80C166,0x58a7,0xa7a7);
|
|
|
|
Conditions=(Condition *) malloc(sizeof(Condition)*ConditionCount); InstrZ=0;
|
|
TrueCond=InstrZ; AddCondition("UC" ,0x0); AddCondition("Z" ,0x2);
|
|
AddCondition("NZ" ,0x3); AddCondition("V" ,0x4);
|
|
AddCondition("NV" ,0x5); AddCondition("N" ,0x6);
|
|
AddCondition("NN" ,0x7); AddCondition("C" ,0x8);
|
|
AddCondition("NC" ,0x9); AddCondition("EQ" ,0x2);
|
|
AddCondition("NE" ,0x3); AddCondition("ULT",0x8);
|
|
AddCondition("ULE",0xf); AddCondition("UGE",0x9);
|
|
AddCondition("UGT",0xe); AddCondition("SLT",0xc);
|
|
AddCondition("SLE",0xb); AddCondition("SGE",0xd);
|
|
AddCondition("SGT",0xa); AddCondition("NET",0x1);
|
|
|
|
ALU2Orders=(char **) malloc(sizeof(char *)*ALU2OrderCount); InstrZ=0;
|
|
ALU2Orders[InstrZ++]="ADD" ; ALU2Orders[InstrZ++]="ADDC";
|
|
ALU2Orders[InstrZ++]="SUB" ; ALU2Orders[InstrZ++]="SUBC";
|
|
ALU2Orders[InstrZ++]="CMP" ; ALU2Orders[InstrZ++]="XOR" ;
|
|
ALU2Orders[InstrZ++]="AND" ; ALU2Orders[InstrZ++]="OR" ;
|
|
|
|
ShiftOrders=(SimpOrder *) malloc(sizeof(SimpOrder)*ShiftOrderCount); InstrZ=0;
|
|
AddShift("ASHR",0xac); AddShift("ROL" ,0x0c);
|
|
AddShift("ROR" ,0x2c); AddShift("SHL" ,0x4c);
|
|
AddShift("SHR" ,0x6c);
|
|
|
|
Bit2Orders=(SimpOrder *) malloc(sizeof(SimpOrder)*Bit2OrderCount); InstrZ=0;
|
|
AddBit2("BAND",0x6a); AddBit2("BCMP" ,0x2a);
|
|
AddBit2("BMOV",0x4a); AddBit2("BMOVN",0x3a);
|
|
AddBit2("BOR" ,0x5a); AddBit2("BXOR" ,0x7a);
|
|
|
|
LoopOrders=(SimpOrder *) malloc(sizeof(SimpOrder)*LoopOrderCount); InstrZ=0;
|
|
AddLoop("CMPD1",0xa0); AddLoop("CMPD2",0xb0);
|
|
AddLoop("CMPI1",0x80); AddLoop("CMPI2",0x90);
|
|
|
|
DivOrders=(char **) malloc(sizeof(char *)*DivOrderCount); InstrZ=0;
|
|
DivOrders[InstrZ++]="DIV"; DivOrders[InstrZ++]="DIVU";
|
|
DivOrders[InstrZ++]="DIVL"; DivOrders[InstrZ++]="DIVLU";
|
|
|
|
BJmpOrders=(char **) malloc(sizeof(char *)*BJmpOrderCount); InstrZ=0;
|
|
BJmpOrders[InstrZ++]="JB"; BJmpOrders[InstrZ++]="JNB";
|
|
BJmpOrders[InstrZ++]="JBC"; BJmpOrders[InstrZ++]="JNBS";
|
|
|
|
MulOrders=(char **) malloc(sizeof(char *)*MulOrderCount); InstrZ=0;
|
|
MulOrders[InstrZ++]="MUL"; MulOrders[InstrZ++]="MULU";
|
|
MulOrders[InstrZ++]="PRIOR";
|
|
END
|
|
|
|
static void DeinitFields(void)
|
|
BEGIN
|
|
free(FixedOrders);
|
|
free(Conditions);
|
|
free(ALU2Orders);
|
|
free(ShiftOrders);
|
|
free(Bit2Orders);
|
|
free(LoopOrders);
|
|
free(DivOrders);
|
|
free(BJmpOrders);
|
|
free(MulOrders);
|
|
END
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
#define ModNone (-1)
|
|
#define ModReg 0
|
|
#define MModReg (1 << ModReg)
|
|
#define ModImm 1
|
|
#define MModImm (1 << ModImm)
|
|
#define ModIReg 2
|
|
#define MModIReg (1 << ModIReg)
|
|
#define ModPreDec 3
|
|
#define MModPreDec (1 << ModPreDec)
|
|
#define ModPostInc 4
|
|
#define MModPostInc (1 << ModPostInc)
|
|
#define ModIndex 5
|
|
#define MModIndex (1 << ModIndex)
|
|
#define ModAbs 6
|
|
#define MModAbs (1 << ModAbs)
|
|
#define ModMReg 7
|
|
#define MModMReg (1 << ModMReg)
|
|
#define ModLAbs 8
|
|
#define MModLAbs (1 << ModLAbs)
|
|
|
|
static Byte AdrMode;
|
|
static Byte AdrVals[2];
|
|
static ShortInt AdrType;
|
|
|
|
static Boolean IsReg(char *Asc, Byte *Erg, Boolean WordWise)
|
|
BEGIN
|
|
Boolean err;
|
|
char *s;
|
|
|
|
if (FindRegDef(Asc,&s)) Asc=s;
|
|
|
|
if ((strlen(Asc)<2) OR (toupper(*Asc)!='R')) return False;
|
|
else if ((strlen(Asc)>2) AND (toupper(Asc[1])=='L') AND (NOT WordWise))
|
|
BEGIN
|
|
*Erg=ConstLongInt(Asc+2,&err); *Erg<<=1;
|
|
return ((err) AND (*Erg<=15));
|
|
END
|
|
else if ((strlen(Asc)>2) AND (toupper(Asc[1])=='H') AND (NOT WordWise))
|
|
BEGIN
|
|
*Erg=ConstLongInt(Asc+2,&err); *Erg<<=1; (*Erg)++;
|
|
return ((err) AND (*Erg<=15));
|
|
END
|
|
else
|
|
BEGIN
|
|
*Erg=ConstLongInt(Asc+1,&err);
|
|
return ((err) AND (*Erg<=15));
|
|
END
|
|
END
|
|
|
|
static Boolean IsRegM1(char *Asc, Byte *Erg, Boolean WordWise)
|
|
BEGIN
|
|
char tmp;
|
|
int l;
|
|
Boolean b;
|
|
|
|
if (*Asc!='\0')
|
|
BEGIN
|
|
tmp=Asc[l=(strlen(Asc)-1)]; Asc[l]='\0';
|
|
b=IsReg(Asc,Erg,WordWise);
|
|
Asc[l]=tmp;
|
|
return b;
|
|
END
|
|
else return False;
|
|
END
|
|
|
|
static LongInt SFRStart(void)
|
|
BEGIN
|
|
return (ExtSFRs) ? 0xf000 : 0xfe00;
|
|
END
|
|
|
|
static LongInt SFREnd(void)
|
|
BEGIN
|
|
return (ExtSFRs) ? 0xf1de : 0xffde;
|
|
END
|
|
|
|
static Boolean CalcPage(LongInt *Adr, Boolean DoAnyway)
|
|
BEGIN
|
|
int z;
|
|
Word Bank;
|
|
|
|
switch (MemMode)
|
|
BEGIN
|
|
case MemModeStd:
|
|
z=0;
|
|
while ((z<=3) AND (((*Adr) >> 14)!=DPPAssumes[z])) z++;
|
|
if (z>3)
|
|
BEGIN
|
|
WrError(110); (*Adr)&=0xffff; return (DoAnyway);
|
|
END
|
|
else
|
|
BEGIN
|
|
*Adr=((*Adr) & 0x3fff)+(z << 14);
|
|
if (DPPChanged[z]) WrXError(200,RegNames[z]);
|
|
return True;
|
|
END
|
|
case MemModeZeroPage:
|
|
(*Adr)&=0x3fff;
|
|
return True;
|
|
case MemModeFixedPage:
|
|
Bank=(*Adr) >> 14; (*Adr)&=0x3fff;
|
|
if (Bank!=MemPage)
|
|
BEGIN
|
|
WrError(110); return (DoAnyway);
|
|
END
|
|
else return True;
|
|
case MemModeNoCheck:
|
|
(*Adr)&=0xffff;
|
|
return True;
|
|
case MemModeFixedBank:
|
|
Bank=(*Adr) >> 16; (*Adr)&=0xffff;
|
|
if (Bank!=MemPage)
|
|
BEGIN
|
|
WrError(110); return (DoAnyway);
|
|
END
|
|
else return True;
|
|
default:
|
|
return False;
|
|
END
|
|
END
|
|
|
|
static void DecideAbsolute(Boolean InCode, LongInt DispAcc, Word Mask, Boolean Dest)
|
|
BEGIN
|
|
#define DPPAdr 0xfe00
|
|
#define SPAdr 0xfe12
|
|
#define CPAdr 0xfe10
|
|
|
|
int z;
|
|
|
|
if (InCode)
|
|
if (((EProgCounter() >> 16)==(DispAcc >> 16)) AND ((Mask & MModAbs)!=0))
|
|
BEGIN
|
|
AdrType=ModAbs; AdrCnt=2;
|
|
AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc);
|
|
END
|
|
else
|
|
BEGIN
|
|
AdrType=ModLAbs; AdrCnt=2; AdrMode=DispAcc >> 16;
|
|
AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc);
|
|
END
|
|
else if (((Mask & MModMReg)!=0) AND (DispAcc>=SFRStart()) AND (DispAcc<=SFREnd()) AND ((DispAcc&1)==0))
|
|
BEGIN
|
|
AdrType=ModMReg; AdrCnt=1; AdrVals[0]=(DispAcc-SFRStart()) >> 1;
|
|
END
|
|
else switch (MemMode)
|
|
BEGIN
|
|
case MemModeStd:
|
|
z=0;
|
|
while ((z<=3) AND ((DispAcc >> 14)!=DPPAssumes[z])) z++;
|
|
if (z>3)
|
|
BEGIN
|
|
WrError(110); z=(DispAcc >> 14) & 3;
|
|
END
|
|
AdrType=ModAbs; AdrCnt=2;
|
|
AdrVals[0]=Lo(DispAcc); AdrVals[1]=(Hi(DispAcc) & 0x3f)+(z << 6);
|
|
if (DPPChanged[z]) WrXError(200,RegNames[z]);
|
|
break;
|
|
case MemModeZeroPage:
|
|
AdrType=ModAbs; AdrCnt=2;
|
|
AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc) & 0x3f;
|
|
break;
|
|
case MemModeFixedPage:
|
|
if ((DispAcc >> 14)!=MemPage) WrError(110);
|
|
AdrType=ModAbs; AdrCnt=2;
|
|
AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc) & 0x3f;
|
|
break;
|
|
case MemModeNoCheck:
|
|
AdrType=ModAbs; AdrCnt=2;
|
|
AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc);
|
|
break;
|
|
case MemModeFixedBank:
|
|
if ((DispAcc >> 16)!=MemPage) WrError(110);
|
|
AdrType=ModAbs; AdrCnt=2;
|
|
AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc);
|
|
break;
|
|
END
|
|
|
|
if ((AdrType!=ModNone) AND (Dest))
|
|
switch ((Word)DispAcc)
|
|
BEGIN
|
|
case SPAdr : N_SPChanged=True; break;
|
|
case CPAdr : N_CPChanged=True; break;
|
|
case DPPAdr :
|
|
case DPPAdr+1 : N_DPPChanged[0]=True; break;
|
|
case DPPAdr+2 :
|
|
case DPPAdr+3 : N_DPPChanged[1]=True; break;
|
|
case DPPAdr+4 :
|
|
case DPPAdr+5 : N_DPPChanged[2]=True; break;
|
|
case DPPAdr+6 :
|
|
case DPPAdr+7 : N_DPPChanged[3]=True; break;
|
|
END
|
|
END
|
|
|
|
static void DecodeAdr(char *Asc, Word Mask, Boolean InCode, Boolean Dest)
|
|
BEGIN
|
|
LongInt HDisp,DispAcc;
|
|
char *PPos,*MPos;
|
|
String Part;
|
|
Boolean OK,NegFlag,NNegFlag;
|
|
Byte HReg;
|
|
|
|
AdrType=ModNone; AdrCnt=0;
|
|
|
|
/* immediate ? */
|
|
|
|
if (*Asc=='#')
|
|
BEGIN
|
|
switch (OpSize)
|
|
BEGIN
|
|
case 0:
|
|
AdrVals[0]=EvalIntExpression(Asc+1,Int8,&OK);
|
|
AdrVals[1]=0;
|
|
break;
|
|
case 1:
|
|
HDisp=EvalIntExpression(Asc+1,Int16,&OK);
|
|
AdrVals[0]=Lo(HDisp); AdrVals[1]=Hi(HDisp);
|
|
break;
|
|
END
|
|
if (OK)
|
|
BEGIN
|
|
AdrType=ModImm; AdrCnt=OpSize+1;
|
|
END
|
|
END
|
|
|
|
/* Register ? */
|
|
|
|
else if (IsReg(Asc,&AdrMode,OpSize==1))
|
|
BEGIN
|
|
if ((Mask & MModReg)!=0) AdrType=ModReg;
|
|
else
|
|
BEGIN
|
|
AdrType=ModMReg; AdrVals[0]=0xf0+AdrMode; AdrCnt=1;
|
|
END
|
|
if (CPChanged) WrXError(200,RegNames[4]);
|
|
END
|
|
|
|
/* indirekt ? */
|
|
|
|
else if ((*Asc=='[') AND (Asc[strlen(Asc)-1]==']'))
|
|
BEGIN
|
|
strcpy(Asc,Asc+1); Asc[strlen(Asc)-1]='\0';
|
|
|
|
/* Predekrement ? */
|
|
|
|
if ((strlen(Asc)>2) AND (*Asc=='-') AND (IsReg(Asc+1,&AdrMode,True)))
|
|
AdrType=ModPreDec;
|
|
|
|
/* Postinkrement ? */
|
|
|
|
else if ((strlen(Asc)>2) AND (Asc[strlen(Asc)-1]=='+') AND (IsRegM1(Asc,&AdrMode,True)))
|
|
AdrType=ModPostInc;
|
|
|
|
/* indiziert ? */
|
|
|
|
else
|
|
BEGIN
|
|
NegFlag=False; DispAcc=0; AdrMode=0xff;
|
|
while (*Asc!='\0')
|
|
BEGIN
|
|
MPos=QuotPos(Asc,'-'); PPos=QuotPos(Asc,'+');
|
|
if (((MPos<PPos) OR (PPos==Nil)) AND (MPos!=Nil))
|
|
BEGIN
|
|
PPos=MPos; NNegFlag=True;
|
|
END
|
|
else NNegFlag=False;
|
|
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 (IsReg(Part,&HReg,True))
|
|
if ((NegFlag) OR (AdrMode!=0xff)) WrError(1350); else AdrMode=HReg;
|
|
else
|
|
BEGIN
|
|
if (*Part=='#') strcpy(Part,Part+1);
|
|
HDisp=EvalIntExpression(Part,Int32,&OK);
|
|
if (OK)
|
|
if (NegFlag) DispAcc-=HDisp; else DispAcc+=HDisp;
|
|
END
|
|
NegFlag=NNegFlag;
|
|
END
|
|
if (AdrMode==0xff) DecideAbsolute(InCode,DispAcc,Mask,Dest);
|
|
else if (DispAcc==0) AdrType=ModIReg;
|
|
else if (DispAcc>0xffff) WrError(1320);
|
|
else if (DispAcc<-0x8000l) WrError(1315);
|
|
else
|
|
BEGIN
|
|
AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc);
|
|
AdrType=ModIndex; AdrCnt=2;
|
|
END
|
|
END
|
|
END
|
|
else
|
|
BEGIN
|
|
DispAcc=EvalIntExpression(Asc,MemInt,&OK);
|
|
if (OK) DecideAbsolute(InCode,DispAcc,Mask,Dest);
|
|
END
|
|
|
|
if ((AdrType!=ModNone) AND (((1 << AdrType) & Mask)==0))
|
|
BEGIN
|
|
WrError(1350); AdrType=ModNone; AdrCnt=0;
|
|
END
|
|
END
|
|
|
|
static int DecodeCondition(char *Name)
|
|
BEGIN
|
|
int z;
|
|
|
|
NLS_UpString(Name);
|
|
for (z=0; z<ConditionCount; z++)
|
|
if (strcmp(Conditions[z].Name,Name)==0) break;
|
|
return z;
|
|
END
|
|
|
|
static Boolean DecodeBitAddr(char *Asc, Word *Adr, Byte *Bit, Boolean MayBeOut)
|
|
BEGIN
|
|
char *p;
|
|
Word LAdr;
|
|
Byte Reg;
|
|
Boolean OK;
|
|
|
|
p=QuotPos(Asc,'.');
|
|
if (p==Nil)
|
|
BEGIN
|
|
LAdr=EvalIntExpression(Asc,UInt16,&OK) & 0x1fff;
|
|
if (OK)
|
|
BEGIN
|
|
if ((NOT MayBeOut) AND ((LAdr >> 12)!=Ord(ExtSFRs)))
|
|
BEGIN
|
|
WrError(1335); return False;
|
|
END
|
|
*Adr=LAdr >> 4; *Bit=LAdr & 15;
|
|
if (NOT MayBeOut) *Adr=Lo(*Adr);
|
|
return True;
|
|
END
|
|
else return False;
|
|
END
|
|
else if (p==Asc)
|
|
BEGIN
|
|
WrError(1350); return False;
|
|
END
|
|
else
|
|
BEGIN
|
|
*p='\0';
|
|
if (IsReg(Asc,&Reg,True)) *Adr=0xf0+Reg;
|
|
else
|
|
BEGIN
|
|
FirstPassUnknown=False;
|
|
LAdr=EvalIntExpression(Asc,UInt16,&OK); if (NOT OK) return False;
|
|
if (FirstPassUnknown) LAdr=0xfd00;
|
|
if ((LAdr&1)==1)
|
|
BEGIN
|
|
WrError(1325); return False;
|
|
END
|
|
if ((LAdr>=0xfd00) AND (LAdr<=0xfdfe)) *Adr=(LAdr-0xfd00)/2;
|
|
else if ((LAdr>=0xff00) AND (LAdr<=0xffde))
|
|
BEGIN
|
|
if ((ExtSFRs) AND (NOT MayBeOut))
|
|
BEGIN
|
|
WrError(1335); return False;
|
|
END
|
|
*Adr=0x80+((LAdr-0xff00)/2);
|
|
END
|
|
else if ((LAdr>=0xf100) AND (LAdr<=0xf1de))
|
|
BEGIN
|
|
if ((NOT ExtSFRs) AND (NOT MayBeOut))
|
|
BEGIN
|
|
WrError(1335); return False;
|
|
END
|
|
*Adr=0x80+((LAdr-0xf100)/2);
|
|
if (MayBeOut) (*Adr)+=0x100;
|
|
END
|
|
else
|
|
BEGIN
|
|
WrError(1320); return False;
|
|
END
|
|
END
|
|
|
|
*Bit=EvalIntExpression(p+1,UInt4,&OK);
|
|
return OK;
|
|
END
|
|
END
|
|
|
|
static Word WordVal(void)
|
|
BEGIN
|
|
return AdrVals[0]+(((Word)AdrVals[1]) << 8);
|
|
END
|
|
|
|
static Boolean DecodePref(char *Asc, Byte *Erg)
|
|
BEGIN
|
|
Boolean OK;
|
|
|
|
if (*Asc!='#')
|
|
BEGIN
|
|
WrError(1350); return False;
|
|
END
|
|
strcpy(Asc,Asc+1);
|
|
FirstPassUnknown=False;
|
|
*Erg=EvalIntExpression(Asc,UInt3,&OK);
|
|
if (FirstPassUnknown) *Erg=1;
|
|
if (NOT OK) return False;
|
|
if (*Erg<1) WrError(1315);
|
|
else if (*Erg>4) WrError(1320);
|
|
else
|
|
BEGIN
|
|
(*Erg)--; return True;
|
|
END
|
|
return False;
|
|
END
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
#define ASSUME166Count 4
|
|
static ASSUMERec ASSUME166s[ASSUME166Count]=
|
|
{{"DPP0", DPPAssumes+0, 0, 15, -1},
|
|
{"DPP1", DPPAssumes+1, 0, 15, -1},
|
|
{"DPP2", DPPAssumes+2, 0, 15, -1},
|
|
{"DPP3", DPPAssumes+3, 0, 15, -1}};
|
|
|
|
static Boolean DecodePseudo(void)
|
|
BEGIN
|
|
Word Adr;
|
|
Byte Bit;
|
|
|
|
if (Memo("ASSUME"))
|
|
BEGIN
|
|
CodeASSUME(ASSUME166s,ASSUME166Count);
|
|
return True;
|
|
END
|
|
|
|
if (Memo("BIT"))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else if (DecodeBitAddr(ArgStr[1],&Adr,&Bit,True))
|
|
BEGIN
|
|
PushLocHandle(-1);
|
|
EnterIntSymbol(LabPart,(Adr << 4)+Bit,SegNone,False);
|
|
PopLocHandle();
|
|
sprintf(ListLine,"=%02xH.%1x",Adr,Bit);
|
|
END
|
|
return True;
|
|
END
|
|
|
|
if (Memo("REG"))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else AddRegDef(LabPart,ArgStr[1]);
|
|
return True;
|
|
END
|
|
|
|
return False;
|
|
END
|
|
|
|
static Boolean BMemo(char *Name)
|
|
BEGIN
|
|
int l;
|
|
|
|
if (strncmp(OpPart,Name,l=strlen(Name))!=0) return False;
|
|
switch (OpPart[l])
|
|
BEGIN
|
|
case '\0':
|
|
OpSize=1; return True;
|
|
case 'B':
|
|
if (OpPart[l+1]=='\0')
|
|
BEGIN
|
|
OpSize=0; return True;
|
|
END
|
|
else return False;
|
|
default:
|
|
return False;
|
|
END
|
|
END
|
|
|
|
static void MakeCode_166(void)
|
|
BEGIN
|
|
int z,Cond;
|
|
Word AdrWord;
|
|
Byte AdrBank,HReg;
|
|
Byte BOfs1,BOfs2;
|
|
Word BAdr1,BAdr2;
|
|
LongInt AdrLong;
|
|
Boolean OK;
|
|
|
|
CodeLen=0; DontPrint=False; OpSize=1;
|
|
|
|
/* zu ignorierendes */
|
|
|
|
if (Memo("")) return;
|
|
|
|
/* Pseudoanweisungen */
|
|
|
|
if (DecodePseudo()) return;
|
|
|
|
if (DecodeIntelPseudo(False)) return;
|
|
|
|
/* Pipeline-Flags weiterschalten */
|
|
|
|
SPChanged=N_SPChanged; N_SPChanged=False;
|
|
CPChanged=N_CPChanged; N_CPChanged=False;
|
|
for (z=0; z<DPPCount; z++)
|
|
BEGIN
|
|
DPPChanged[z]=N_DPPChanged[z];
|
|
N_DPPChanged[z]=False;
|
|
END
|
|
|
|
/* Praefixe herunterzaehlen */
|
|
|
|
if (ExtCounter>=0)
|
|
if (--ExtCounter<0)
|
|
BEGIN
|
|
MemMode=MemModeStd;
|
|
ExtSFRs=False;
|
|
END
|
|
|
|
/* ohne Argument */
|
|
|
|
for (z=0; z<FixedOrderCount; z++)
|
|
if (Memo(FixedOrders[z].Name))
|
|
BEGIN
|
|
if (ArgCnt!=0) WrError(1110);
|
|
else
|
|
BEGIN
|
|
CodeLen=2;
|
|
BAsmCode[0]=Lo(FixedOrders[z].Code1);
|
|
BAsmCode[1]=Hi(FixedOrders[z].Code1);
|
|
if (FixedOrders[z].Code2!=0)
|
|
BEGIN
|
|
CodeLen=4;
|
|
BAsmCode[2]=Lo(FixedOrders[z].Code2);
|
|
BAsmCode[3]=Hi(FixedOrders[z].Code2);
|
|
if ((strncmp(OpPart,"RET",3)==0) AND (SPChanged)) WrXError(200,RegNames[5]);
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
/* Datentransfer */
|
|
|
|
if (BMemo("MOV"))
|
|
BEGIN
|
|
Cond=1-OpSize;
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1],MModReg+MModMReg+MModIReg+MModPreDec+MModPostInc+MModIndex+MModAbs,False,True);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
HReg=AdrMode;
|
|
DecodeAdr(ArgStr[2],MModReg+MModImm+MModIReg+MModPostInc+MModIndex+MModAbs,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
CodeLen=2; BAsmCode[0]=0xf0+Cond;
|
|
BAsmCode[1]=(HReg << 4)+AdrMode;
|
|
break;
|
|
case ModImm:
|
|
if (WordVal()<=15)
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=0xe0+Cond;
|
|
BAsmCode[1]=(WordVal() << 4)+HReg;
|
|
END
|
|
else
|
|
BEGIN
|
|
CodeLen=4; BAsmCode[0]=0xe6+Cond; BAsmCode[1]=HReg+0xf0;
|
|
memcpy(BAsmCode+2,AdrVals,2);
|
|
END
|
|
break;
|
|
case ModIReg:
|
|
CodeLen=2; BAsmCode[0]=0xa8+Cond;
|
|
BAsmCode[1]=(HReg << 4)+AdrMode;
|
|
break;
|
|
case ModPostInc:
|
|
CodeLen=2; BAsmCode[0]=0x98+Cond;
|
|
BAsmCode[1]=(HReg << 4)+AdrMode;
|
|
break;
|
|
case ModIndex:
|
|
CodeLen=2+AdrCnt; BAsmCode[0]=0xd4+(Cond << 5);
|
|
BAsmCode[1]=(HReg << 4)+AdrMode; memcpy(BAsmCode+2,AdrVals,AdrCnt);
|
|
break;
|
|
case ModAbs:
|
|
CodeLen=2+AdrCnt; BAsmCode[0]=0xf2+Cond;
|
|
BAsmCode[1]=0xf0+HReg; memcpy(BAsmCode+2,AdrVals,AdrCnt);
|
|
break;
|
|
END
|
|
break;
|
|
case ModMReg:
|
|
BAsmCode[1]=AdrVals[0];
|
|
DecodeAdr(ArgStr[2],MModImm+MModMReg+((DPPAssumes[3]==3)?MModIReg:0)+MModAbs,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModImm:
|
|
CodeLen=4; BAsmCode[0]=0xe6+Cond;
|
|
memcpy(BAsmCode+2,AdrVals,2);
|
|
break;
|
|
case ModMReg: /* BAsmCode[1] sicher absolut darstellbar, da Rn vorher */
|
|
/* abgefangen wird! */
|
|
BAsmCode[0]=0xf6+Cond;
|
|
AdrLong=0xfe00+(((Word)BAsmCode[1]) << 1);
|
|
CalcPage(&AdrLong,True);
|
|
BAsmCode[2]=Lo(AdrLong);
|
|
BAsmCode[3]=Hi(AdrLong);
|
|
BAsmCode[1]=AdrVals[0];
|
|
CodeLen=4;
|
|
break;
|
|
case ModIReg:
|
|
CodeLen=4; BAsmCode[0]=0x94+(Cond << 5);
|
|
BAsmCode[2]=BAsmCode[1] << 1;
|
|
BAsmCode[3]=0xfe + (BAsmCode[1] >> 7); /* ANSI :-0 */
|
|
BAsmCode[1]=AdrMode;
|
|
break;
|
|
case ModAbs:
|
|
CodeLen=2+AdrCnt; BAsmCode[0]=0xf2+Cond;
|
|
memcpy(BAsmCode+2,AdrVals,AdrCnt);
|
|
break;
|
|
END
|
|
break;
|
|
case ModIReg:
|
|
HReg=AdrMode;
|
|
DecodeAdr(ArgStr[2],MModReg+MModIReg+MModPostInc+MModAbs,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
CodeLen=2; BAsmCode[0]=0xb8+Cond;
|
|
BAsmCode[1]=HReg+(AdrMode << 4);
|
|
break;
|
|
case ModIReg:
|
|
CodeLen=2; BAsmCode[0]=0xc8+Cond;
|
|
BAsmCode[1]=(HReg << 4)+AdrMode;
|
|
break;
|
|
case ModPostInc:
|
|
CodeLen=2; BAsmCode[0]=0xe8+Cond;
|
|
BAsmCode[1]=(HReg << 4)+AdrMode;
|
|
break;
|
|
case ModAbs:
|
|
CodeLen=2+AdrCnt; BAsmCode[0]=0x84+(Cond << 5);
|
|
BAsmCode[1]=HReg; memcpy(BAsmCode+2,AdrVals,AdrCnt);
|
|
break;
|
|
END
|
|
break;
|
|
case ModPreDec:
|
|
HReg=AdrMode;
|
|
DecodeAdr(ArgStr[2],MModReg,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
CodeLen=2; BAsmCode[0]=0x88+Cond;
|
|
BAsmCode[1]=HReg+(AdrMode << 4);
|
|
break;
|
|
END
|
|
break;
|
|
case ModPostInc:
|
|
HReg=AdrMode;
|
|
DecodeAdr(ArgStr[2],MModIReg,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModIReg:
|
|
CodeLen=2; BAsmCode[0]=0xd8+Cond;
|
|
BAsmCode[1]=(HReg << 4)+AdrMode;
|
|
break;
|
|
END
|
|
break;
|
|
case ModIndex:
|
|
BAsmCode[1]=AdrMode; memcpy(BAsmCode+2,AdrVals,AdrCnt);
|
|
DecodeAdr(ArgStr[2],MModReg,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
BAsmCode[0]=0xc4+(Cond << 5);
|
|
CodeLen=4; BAsmCode[1]+=AdrMode << 4;
|
|
break;
|
|
END
|
|
break;
|
|
case ModAbs:
|
|
memcpy(BAsmCode+2,AdrVals,AdrCnt);
|
|
DecodeAdr(ArgStr[2],MModIReg+MModMReg,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModIReg:
|
|
CodeLen=4; BAsmCode[0]=0x94+(Cond << 5);
|
|
BAsmCode[1]=AdrMode;
|
|
break;
|
|
case ModMReg:
|
|
CodeLen=4; BAsmCode[0]=0xf6+Cond;
|
|
BAsmCode[1]=AdrVals[0];
|
|
break;
|
|
END
|
|
break;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if ((Memo("MOVBS")) OR (Memo("MOVBZ")))
|
|
BEGIN
|
|
Cond=Ord(Memo("MOVBS")) << 4;
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
OpSize=1;
|
|
DecodeAdr(ArgStr[1],MModReg+MModMReg+MModAbs,False,True);
|
|
OpSize=0;
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
HReg=AdrMode; DecodeAdr(ArgStr[2],MModReg+MModAbs,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
CodeLen=2; BAsmCode[0]=0xc0+Cond;
|
|
BAsmCode[1]=HReg+(AdrMode << 4);
|
|
break;
|
|
case ModAbs:
|
|
CodeLen=4; BAsmCode[0]=0xc2+Cond;
|
|
BAsmCode[1]=0xf0+HReg;
|
|
memcpy(BAsmCode+2,AdrVals,2);
|
|
break;
|
|
END
|
|
break;
|
|
case ModMReg:
|
|
BAsmCode[1]=AdrVals[0];
|
|
DecodeAdr(ArgStr[2],MModAbs+MModMReg,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModMReg: /* BAsmCode[1] sicher absolut darstellbar, da Rn vorher */
|
|
/* abgefangen wird! */
|
|
BAsmCode[0]=0xc5+Cond;
|
|
AdrLong=0xfe00+(((Word)BAsmCode[1]) << 1);
|
|
CalcPage(&AdrLong,True);
|
|
BAsmCode[2]=Lo(AdrLong);
|
|
BAsmCode[3]=Hi(AdrLong);
|
|
BAsmCode[1]=AdrVals[0];
|
|
CodeLen=4;
|
|
break;
|
|
case ModAbs:
|
|
CodeLen=2+AdrCnt; BAsmCode[0]=0xc2+Cond;
|
|
memcpy(BAsmCode+2,AdrVals,AdrCnt);
|
|
break;
|
|
END
|
|
break;
|
|
case ModAbs:
|
|
memcpy(BAsmCode+2,AdrVals,AdrCnt);
|
|
DecodeAdr(ArgStr[2],MModMReg,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModMReg:
|
|
CodeLen=4; BAsmCode[0]=0xc5+Cond;
|
|
BAsmCode[1]=AdrVals[0];
|
|
break;
|
|
END
|
|
break;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if ((Memo("PUSH")) OR (Memo("POP")))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1],MModMReg,False,Memo("POP"));
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModMReg:
|
|
CodeLen=2; BAsmCode[0]=0xec+(Ord(Memo("POP")) << 4);
|
|
BAsmCode[1]=AdrVals[0];
|
|
if (SPChanged) WrXError(200,RegNames[5]);
|
|
break;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("SCXT"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1],MModMReg,False,True);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModMReg:
|
|
BAsmCode[1]=AdrVals[0];
|
|
DecodeAdr(ArgStr[2],MModAbs+MModImm,False,False);
|
|
if (AdrType!=ModNone)
|
|
BEGIN
|
|
CodeLen=4; BAsmCode[0]=0xc6+(Ord(AdrType==ModAbs) << 4);
|
|
memcpy(BAsmCode+2,AdrVals,2);
|
|
END
|
|
break;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
/* Arithmetik */
|
|
|
|
for (z=0; z<ALU2OrderCount; z++)
|
|
if (BMemo(ALU2Orders[z]))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
Cond=(1-OpSize)+(z << 4);
|
|
DecodeAdr(ArgStr[1],MModReg+MModMReg+MModAbs,False,True);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
HReg=AdrMode;
|
|
DecodeAdr(ArgStr[2],MModReg+MModIReg+MModPostInc+MModAbs+MModImm,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
CodeLen=2; BAsmCode[0]=Cond;
|
|
BAsmCode[1]=(HReg << 4)+AdrMode;
|
|
break;
|
|
case ModIReg:
|
|
if (AdrMode>3) WrError(1350);
|
|
else
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=0x08+Cond;
|
|
BAsmCode[1]=(HReg << 4)+8+AdrMode;
|
|
END
|
|
break;
|
|
case ModPostInc:
|
|
if (AdrMode>3) WrError(1350);
|
|
else
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=0x08+Cond;
|
|
BAsmCode[1]=(HReg << 4)+12+AdrMode;
|
|
END
|
|
break;
|
|
case ModAbs:
|
|
CodeLen=4; BAsmCode[0]=0x02+Cond; BAsmCode[1]=0xf0+HReg;
|
|
memcpy(BAsmCode+2,AdrVals,AdrCnt);
|
|
break;
|
|
case ModImm:
|
|
if (WordVal()<=7)
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=0x08+Cond;
|
|
BAsmCode[1]=(HReg << 4)+AdrVals[0];
|
|
END
|
|
else
|
|
BEGIN
|
|
CodeLen=4; BAsmCode[0]=0x06+Cond; BAsmCode[1]=0xf0+HReg;
|
|
memcpy(BAsmCode+2,AdrVals,2);
|
|
END
|
|
break;
|
|
END
|
|
break;
|
|
case ModMReg:
|
|
BAsmCode[1]=AdrVals[0];
|
|
DecodeAdr(ArgStr[2],MModAbs+MModMReg+MModImm,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModAbs:
|
|
CodeLen=4; BAsmCode[0]=0x02+Cond;
|
|
memcpy(BAsmCode+2,AdrVals,AdrCnt);
|
|
break;
|
|
case ModMReg: /* BAsmCode[1] sicher absolut darstellbar, da Rn vorher */
|
|
/* abgefangen wird! */
|
|
BAsmCode[0]=0x04+Cond;
|
|
AdrLong=0xfe00+(((Word)BAsmCode[1]) << 1);
|
|
CalcPage(&AdrLong,True);
|
|
BAsmCode[2]=Lo(AdrLong);
|
|
BAsmCode[3]=Hi(AdrLong);
|
|
BAsmCode[1]=AdrVals[0];
|
|
CodeLen=4;
|
|
break;
|
|
case ModImm:
|
|
CodeLen=4; BAsmCode[0]=0x06+Cond;
|
|
memcpy(BAsmCode+2,AdrVals,2);
|
|
break;
|
|
END
|
|
break;
|
|
case ModAbs:
|
|
memcpy(BAsmCode+2,AdrVals,AdrCnt);
|
|
DecodeAdr(ArgStr[2],MModMReg,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModMReg:
|
|
CodeLen=4; BAsmCode[0]=0x04+Cond; BAsmCode[1]=AdrVals[0];
|
|
break;
|
|
END
|
|
break;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if ((BMemo("CPL")) OR (BMemo("NEG")))
|
|
BEGIN
|
|
Cond=0x81+((1-OpSize) << 5);
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1],MModReg,False,True);
|
|
if (AdrType==ModReg)
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=Cond+(Ord(BMemo("CPL")) << 4);
|
|
BAsmCode[1]=AdrMode << 4;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
for (z=0; z<DivOrderCount; z++)
|
|
if (Memo(DivOrders[z]))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1],MModReg,False,False);
|
|
if (AdrType==ModReg)
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=0x4b+(z << 4);
|
|
BAsmCode[1]=AdrMode*0x11;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
for (z=0; z<LoopOrderCount; z++)
|
|
if (Memo(LoopOrders[z].Name))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1],MModReg,False,True);
|
|
if (AdrType==ModReg)
|
|
BEGIN
|
|
BAsmCode[1]=AdrMode;
|
|
DecodeAdr(ArgStr[2],MModAbs+MModImm,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModAbs:
|
|
CodeLen=4; BAsmCode[0]=LoopOrders[z].Code+2; BAsmCode[1]+=0xf0;
|
|
memcpy(BAsmCode+2,AdrVals,2);
|
|
break;
|
|
case ModImm:
|
|
if (WordVal()<16)
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=LoopOrders[z].Code;
|
|
BAsmCode[1]+=(WordVal() << 4);
|
|
END
|
|
else
|
|
BEGIN
|
|
CodeLen=4; BAsmCode[0]=LoopOrders[z].Code+6; BAsmCode[1]+=0xf0;
|
|
memcpy(BAsmCode+2,AdrVals,2);
|
|
END
|
|
break;
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
for (z=0; z<MulOrderCount; z++)
|
|
if (Memo(MulOrders[z]))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1],MModReg,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
HReg=AdrMode;
|
|
DecodeAdr(ArgStr[2],MModReg,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
CodeLen=2; BAsmCode[0]=0x0b+(z << 4);
|
|
BAsmCode[1]=(HReg << 4)+AdrMode;
|
|
break;
|
|
END
|
|
break;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
/* Logik */
|
|
|
|
for (z=0; z<ShiftOrderCount; z++)
|
|
if (Memo(ShiftOrders[z].Name))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
OpSize=1;
|
|
DecodeAdr(ArgStr[1],MModReg,False,True);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
HReg=AdrMode;
|
|
DecodeAdr(ArgStr[2],MModReg+MModImm,False,True);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
BAsmCode[0]=ShiftOrders[z].Code; BAsmCode[1]=AdrMode+(HReg << 4);
|
|
CodeLen=2;
|
|
break;
|
|
case ModImm:
|
|
if (WordVal()>15) WrError(1320);
|
|
else
|
|
BEGIN
|
|
BAsmCode[0]=ShiftOrders[z].Code+0x10;
|
|
BAsmCode[1]=(WordVal() << 4)+HReg;
|
|
CodeLen=2;
|
|
END
|
|
break;
|
|
END
|
|
break;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
for (z=0; z<Bit2OrderCount; z++)
|
|
if (Memo(Bit2Orders[z].Name))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
if (DecodeBitAddr(ArgStr[1],&BAdr1,&BOfs1,False))
|
|
if (DecodeBitAddr(ArgStr[2],&BAdr2,&BOfs2,False))
|
|
BEGIN
|
|
CodeLen=4; BAsmCode[0]=Bit2Orders[z].Code;
|
|
BAsmCode[1]=BAdr2; BAsmCode[2]=BAdr1;
|
|
BAsmCode[3]=(BOfs2 << 4)+BOfs1;
|
|
END
|
|
return;
|
|
END
|
|
|
|
if ((Memo("BCLR")) OR (Memo("BSET")))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else if (DecodeBitAddr(ArgStr[1],&BAdr1,&BOfs1,False))
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=(BOfs1 << 4)+0x0e + Ord(Memo("BSET")); /* ANSI :-0 */
|
|
BAsmCode[1]=BAdr1;
|
|
END
|
|
return;
|
|
END
|
|
|
|
if ((Memo("BFLDH")) OR (Memo("BFLDL")))
|
|
BEGIN
|
|
if (ArgCnt!=3) WrError(1110);
|
|
else
|
|
BEGIN
|
|
strmaxcat(ArgStr[1],".0",255);
|
|
if (DecodeBitAddr(ArgStr[1],&BAdr1,&BOfs1,False))
|
|
BEGIN
|
|
OpSize=0; BAsmCode[1]=BAdr1;
|
|
DecodeAdr(ArgStr[2],MModImm,False,False);
|
|
if (AdrType==ModImm)
|
|
BEGIN
|
|
BAsmCode[2]=AdrVals[0];
|
|
DecodeAdr(ArgStr[3],MModImm,False,False);
|
|
if (AdrType==ModImm)
|
|
BEGIN
|
|
BAsmCode[3]=AdrVals[0];
|
|
CodeLen=4; BAsmCode[0]=0x0a;
|
|
if (Memo("BFLDH"))
|
|
BEGIN
|
|
BAdr1=BAsmCode[2]; BAsmCode[2]=BAsmCode[3]; BAsmCode[3]=BAdr1;
|
|
BAsmCode[0]+=0x10;
|
|
END
|
|
END
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
/*Spruenge */
|
|
|
|
if (Memo("JMP"))
|
|
BEGIN
|
|
if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110);
|
|
else
|
|
BEGIN
|
|
Cond=(ArgCnt==1) ? TrueCond : DecodeCondition(ArgStr[1]);
|
|
if (Cond>=ConditionCount) WrXError(1360,ArgStr[1]);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[ArgCnt],MModAbs+MModLAbs+MModIReg,True,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModLAbs:
|
|
if (Cond!=TrueCond) WrXError(1360,ArgStr[1]);
|
|
else
|
|
BEGIN
|
|
CodeLen=2+AdrCnt; BAsmCode[0]=0xfa; BAsmCode[1]=AdrMode;
|
|
memcpy(BAsmCode+2,AdrVals,AdrCnt);
|
|
END
|
|
break;
|
|
case ModAbs:
|
|
AdrLong=WordVal()-(EProgCounter()+2);
|
|
if ((AdrLong<=254) AND (AdrLong>=-256) AND ((AdrLong&1)==0))
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=0x0d+(Conditions[Cond].Code << 4);
|
|
BAsmCode[1]=(AdrLong/2)&0xff;
|
|
END
|
|
else
|
|
BEGIN
|
|
CodeLen=2+AdrCnt; BAsmCode[0]=0xea;
|
|
BAsmCode[1]=Conditions[Cond].Code << 4;
|
|
memcpy(BAsmCode+2,AdrVals,AdrCnt);
|
|
END
|
|
break;
|
|
case ModIReg:
|
|
CodeLen=2; BAsmCode[0]=0x9c;
|
|
BAsmCode[1]=(Conditions[Cond].Code << 4)+AdrMode;
|
|
break;
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("CALL"))
|
|
BEGIN
|
|
if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110);
|
|
else
|
|
BEGIN
|
|
Cond=(ArgCnt==1) ? TrueCond : DecodeCondition(ArgStr[1]);
|
|
if (Cond>=ConditionCount) WrXError(1360,ArgStr[1]);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[ArgCnt],MModAbs+MModLAbs+MModIReg,True,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModLAbs:
|
|
if (Cond!=TrueCond) WrXError(1360,ArgStr[1]);
|
|
else
|
|
BEGIN
|
|
CodeLen=2+AdrCnt; BAsmCode[0]=0xda; BAsmCode[1]=AdrMode;
|
|
memcpy(BAsmCode+2,AdrVals,AdrCnt);
|
|
END
|
|
break;
|
|
case ModAbs:
|
|
AdrLong=WordVal()-(EProgCounter()+2);
|
|
if ((AdrLong<=254) AND (AdrLong>=-256) AND ((AdrLong&1)==0) AND (Cond==TrueCond))
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=0xbb;
|
|
BAsmCode[1]=(AdrLong/2) & 0xff;
|
|
END
|
|
else
|
|
BEGIN
|
|
CodeLen=2+AdrCnt; BAsmCode[0]=0xca;
|
|
BAsmCode[1]=0x00+(Conditions[Cond].Code << 4);
|
|
memcpy(BAsmCode+2,AdrVals,AdrCnt);
|
|
END
|
|
break;
|
|
case ModIReg:
|
|
CodeLen=2; BAsmCode[0]=0xab;
|
|
BAsmCode[1]=(Conditions[Cond].Code << 4)+AdrMode;
|
|
break;
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("JMPR"))
|
|
BEGIN
|
|
if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110);
|
|
else
|
|
BEGIN
|
|
Cond=(ArgCnt==1) ? TrueCond : DecodeCondition(ArgStr[1]);
|
|
if (Cond>=ConditionCount) WrXError(1360,ArgStr[1]);
|
|
else
|
|
BEGIN
|
|
AdrLong=EvalIntExpression(ArgStr[ArgCnt],MemInt,&OK)-(EProgCounter()+2);
|
|
if (OK)
|
|
if ((AdrLong&1)==1) WrError(1375);
|
|
else if ((NOT SymbolQuestionable) AND ((AdrLong>254) OR (AdrLong<-256))) WrError(1370);
|
|
else
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=0x0d+(Conditions[Cond].Code << 4);
|
|
BAsmCode[1]=(AdrLong/2) & 0xff;
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("CALLR"))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
AdrLong=EvalIntExpression(ArgStr[ArgCnt],MemInt,&OK)-(EProgCounter()+2);
|
|
if (OK)
|
|
if ((AdrLong&1)==1) WrError(1375);
|
|
else if ((NOT SymbolQuestionable) AND ((AdrLong>254) OR (AdrLong<-256))) WrError(1370);
|
|
else
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=0xbb;
|
|
BAsmCode[1]=(AdrLong/2) & 0xff;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if ((Memo("JMPA")) OR (Memo("CALLA")))
|
|
BEGIN
|
|
if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110);
|
|
else
|
|
BEGIN
|
|
Cond=(ArgCnt==1) ? TrueCond : DecodeCondition(ArgStr[1]);
|
|
if (Cond>=ConditionCount) WrXError(1360,ArgStr[1]);
|
|
else
|
|
BEGIN
|
|
AdrLong=EvalIntExpression(ArgStr[ArgCnt],MemInt,&OK);
|
|
if (OK)
|
|
if ((AdrLong >> 16)!=(EProgCounter() >> 16)) WrError(1910);
|
|
else
|
|
BEGIN
|
|
CodeLen=4;
|
|
BAsmCode[0]=(Memo("JMPA")) ? 0xea : 0xca;
|
|
BAsmCode[1]=0x00+(Conditions[Cond].Code << 4);
|
|
BAsmCode[2]=Lo(AdrLong); BAsmCode[3]=Hi(AdrLong);
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if ((Memo("JMPS")) OR (Memo("CALLS")))
|
|
BEGIN
|
|
if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110);
|
|
else
|
|
BEGIN
|
|
if (ArgCnt==1)
|
|
BEGIN
|
|
AdrLong=EvalIntExpression(ArgStr[1],MemInt,&OK);
|
|
AdrWord=AdrLong & 0xffff; AdrBank=AdrLong >> 16;
|
|
END
|
|
else
|
|
BEGIN
|
|
AdrWord=EvalIntExpression(ArgStr[2],UInt16,&OK);
|
|
if (OK) AdrBank=EvalIntExpression(ArgStr[1],MemInt2,&OK); else AdrBank=0;
|
|
END
|
|
if (OK)
|
|
BEGIN
|
|
CodeLen=4;
|
|
BAsmCode[0]=(Memo("JMPS")) ? 0xfa : 0xda;
|
|
BAsmCode[1]=AdrBank;
|
|
BAsmCode[2]=Lo(AdrWord); BAsmCode[3]=Hi(AdrWord);
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if ((Memo("JMPI")) OR (Memo("CALLI")))
|
|
BEGIN
|
|
if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110);
|
|
else
|
|
BEGIN
|
|
Cond=(ArgCnt==1) ? TrueCond : DecodeCondition(ArgStr[1]);
|
|
if (Cond>=ConditionCount) WrXError(1360,ArgStr[1]);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[ArgCnt],MModIReg,True,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModIReg:
|
|
CodeLen=2;
|
|
BAsmCode[0]=(Memo("JMPI")) ? 0x9c : 0xab;
|
|
BAsmCode[1]=AdrMode+(Conditions[Cond].Code << 4);
|
|
break;
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
for (z=0; z<BJmpOrderCount; z++)
|
|
if (Memo(BJmpOrders[z]))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if (DecodeBitAddr(ArgStr[1],&BAdr1,&BOfs1,False))
|
|
BEGIN
|
|
AdrLong=EvalIntExpression(ArgStr[2],MemInt,&OK)-(EProgCounter()+4);
|
|
if (OK)
|
|
if ((AdrLong&1)==1) WrError(1375);
|
|
else if ((NOT SymbolQuestionable) AND ((AdrLong<-256) OR (AdrLong>254))) WrError(1370);
|
|
else
|
|
BEGIN
|
|
CodeLen=4; BAsmCode[0]=0x8a+(z << 4);
|
|
BAsmCode[1]=BAdr1;
|
|
BAsmCode[2]=(AdrLong/2) & 0xff;
|
|
BAsmCode[3]=BOfs1 << 4;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("PCALL"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1],MModMReg,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModMReg:
|
|
BAsmCode[1]=AdrVals[0];
|
|
DecodeAdr(ArgStr[2],MModAbs,True,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModAbs:
|
|
CodeLen=4; BAsmCode[0]=0xe2; memcpy(BAsmCode+2,AdrVals,2);
|
|
break;
|
|
END
|
|
break;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("RETP"))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1],MModMReg,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModMReg:
|
|
BAsmCode[1]=AdrVals[0]; BAsmCode[0]=0xeb; CodeLen=2;
|
|
if (SPChanged) WrXError(200,RegNames[5]);
|
|
break;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("TRAP"))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else if (*ArgStr[1]!='#') WrError(1350);
|
|
else
|
|
BEGIN
|
|
BAsmCode[1]=EvalIntExpression(ArgStr[1]+1,UInt7,&OK) << 1;
|
|
if (OK)
|
|
BEGIN
|
|
BAsmCode[0]=0x9b; CodeLen=2;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
/* spezielle Steuerbefehle */
|
|
|
|
if (Memo("ATOMIC"))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else if (MomCPU<CPU80C167) WrError(1500);
|
|
else if (DecodePref(ArgStr[1],&HReg))
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=0xd1; BAsmCode[1]=HReg << 4;
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("EXTR"))
|
|
BEGIN
|
|
if (ArgCnt!=1) WrError(1110);
|
|
else if (MomCPU<CPU80C167) WrError(1500);
|
|
else if (DecodePref(ArgStr[1],&HReg))
|
|
BEGIN
|
|
CodeLen=2; BAsmCode[0]=0xd1; BAsmCode[1]=0x80+(HReg << 4);
|
|
ExtCounter=HReg+1; ExtSFRs=True;
|
|
END
|
|
return;
|
|
END
|
|
|
|
if ((Memo("EXTP")) OR (Memo("EXTPR")))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if (MomCPU<CPU80C167) WrError(1500);
|
|
else if (DecodePref(ArgStr[2],&HReg))
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1],MModReg+MModImm,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
CodeLen=2; BAsmCode[0]=0xdc; BAsmCode[1]=0x40+(HReg << 4)+AdrMode;
|
|
if (Memo("EXTPR")) BAsmCode[1]+=0x80;
|
|
ExtCounter=HReg+1; MemMode=MemModeZeroPage;
|
|
break;
|
|
case ModImm:
|
|
CodeLen=4; BAsmCode[0]=0xd7; BAsmCode[1]=0x40+(HReg << 4);
|
|
if (Memo("EXTPR")) BAsmCode[1]+=0x80;
|
|
BAsmCode[2]=WordVal() & 0xff; BAsmCode[3]=(WordVal() >> 8) & 3;
|
|
ExtCounter=HReg+1; MemMode=MemModeFixedPage; MemPage=WordVal() & 0x3ff;
|
|
break;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if ((Memo("EXTS")) OR (Memo("EXTSR")))
|
|
BEGIN
|
|
OpSize=0;
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if (MomCPU<CPU80C167) WrError(1500);
|
|
else if (DecodePref(ArgStr[2],&HReg))
|
|
BEGIN
|
|
DecodeAdr(ArgStr[1],MModReg+MModImm,False,False);
|
|
switch (AdrType)
|
|
BEGIN
|
|
case ModReg:
|
|
CodeLen=2; BAsmCode[0]=0xdc; BAsmCode[1]=0x00+(HReg << 4)+AdrMode;
|
|
if (Memo("EXTSR")) BAsmCode[1]+=0x80;
|
|
ExtCounter=HReg+1; MemMode=MemModeNoCheck;
|
|
break;
|
|
case ModImm:
|
|
CodeLen=4; BAsmCode[0]=0xd7; BAsmCode[1]=0x00+(HReg << 4);
|
|
if (Memo("EXTSR")) BAsmCode[1]+=0x80;
|
|
BAsmCode[2]=AdrVals[0]; BAsmCode[3]=0;
|
|
ExtCounter=HReg+1; MemMode=MemModeFixedBank; MemPage=AdrVals[0];
|
|
break;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
WrXError(1200,OpPart);
|
|
END
|
|
|
|
static void InitCode_166(void)
|
|
BEGIN
|
|
int z;
|
|
|
|
SaveInitProc();
|
|
for (z=0; z<DPPCount; z++)
|
|
BEGIN
|
|
DPPAssumes[z]=z; N_DPPChanged[z]=False;
|
|
END
|
|
N_CPChanged=False; N_SPChanged=False;
|
|
|
|
MemMode=MemModeStd; ExtSFRs=False; ExtCounter=(-1);
|
|
END
|
|
|
|
static Boolean IsDef_166(void)
|
|
BEGIN
|
|
return (Memo("BIT")) OR (Memo("REG"));
|
|
END
|
|
|
|
static void SwitchFrom_166(void)
|
|
BEGIN
|
|
DeinitFields();
|
|
END
|
|
|
|
static void SwitchTo_166(void)
|
|
BEGIN
|
|
Byte z;
|
|
|
|
TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False;
|
|
OpSize=1;
|
|
|
|
PCSymbol="$"; HeaderID=0x4c; NOPCode=0xcc00;
|
|
DivideChars=","; HasAttrs=False;
|
|
|
|
ValidSegs=(1<<SegCode);
|
|
Grans[SegCode]=1; ListGrans[SegCode]=1; SegInits[SegCode]=0;
|
|
|
|
MakeCode=MakeCode_166; IsDef=IsDef_166;
|
|
SwitchFrom=SwitchFrom_166;
|
|
|
|
if (MomCPU==CPU80C166)
|
|
BEGIN
|
|
MemInt=UInt18; MemInt2=UInt2; ASSUME166s[0].Max=15;
|
|
SegLimits[SegCode] = 0x3ffffl;
|
|
END
|
|
else
|
|
BEGIN
|
|
MemInt=UInt24; MemInt2=UInt8; ASSUME166s[0].Max=1023;
|
|
SegLimits[SegCode] = 0xffffffl;
|
|
END
|
|
for (z=1; z<4; z++) ASSUME166s[z].Max=ASSUME166s[0].Max;
|
|
|
|
InitFields();
|
|
END
|
|
|
|
void code166_init(void)
|
|
BEGIN
|
|
CPU80C166=AddCPU("80C166",SwitchTo_166);
|
|
CPU80C167=AddCPU("80C167",SwitchTo_166);
|
|
|
|
SaveInitProc=InitPassProc; InitPassProc=InitCode_166;
|
|
END
|