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

1294 lines
32 KiB
C

/* code90c141.c */
/*****************************************************************************/
/* AS-Portierung */
/* */
/* Codegenerator Toshiba TLCS-90 */
/* */
/* Historie: 30.10.1996 Grundsteinlegung */
/* 2. 1.1999 ChkPC umgebaut */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <string.h>
#include <ctype.h>
#include "nls.h"
#include "bpemu.h"
#include "strutil.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "asmitree.h"
#include "codepseudo.h"
#include "codevars.h"
typedef struct
{
Byte Code;
} FixedOrder;
typedef struct
{
Byte Code;
Boolean MayReg;
} ShiftOrder;
typedef struct
{
char *Name;
Byte Code;
} Condition;
#define AccReg 6
#define HLReg 2
#define FixedOrderCnt 18
#define MoveOrderCnt 8
#define ShiftOrderCnt 10
#define BitOrderCnt 4
#define AccOrderCnt 3
#define ALU2OrderCnt 8
#define ConditionCnt 24
#define ModNone (-1)
#define ModReg8 0
#define MModReg8 (1 << ModReg8)
#define ModReg16 1
#define MModReg16 (1 << ModReg16)
#define ModIReg16 2
#define MModIReg16 (1 << ModIReg16)
#define ModIndReg 3
#define MModIndReg (1 << ModIndReg)
#define ModIdxReg 4
#define MModIdxReg (1 << ModIdxReg)
#define ModDir 5
#define MModDir (1 << ModDir)
#define ModMem 6
#define MModMem (1 << ModMem)
#define ModImm 7
#define MModImm (1 << ModImm)
static int DefaultCondition;
static ShortInt AdrType;
static Byte AdrMode;
static ShortInt OpSize;
static Byte AdrVals[10];
static Boolean MinOneIs0;
static FixedOrder *FixedOrders;
static FixedOrder *MoveOrders;
static ShiftOrder *ShiftOrders;
static FixedOrder *BitOrders;
static FixedOrder *AccOrders;
static char **ALU2Orders;
static Condition *Conditions;
static PInstTreeNode ITree;
static CPUVar CPU90C141;
/*---------------------------------------------------------------------------*/
static void ChkAdr(Byte Erl)
BEGIN
if (AdrType!=ModNone)
if (((1 << AdrType) & Erl)==0)
BEGIN
WrError(1350); AdrType=ModNone; AdrCnt=0;
END
END
static void SetOpSize(ShortInt New)
BEGIN
if (OpSize==-1) OpSize=New;
else if (OpSize!=New)
BEGIN
WrError(1131); AdrType=ModNone; AdrCnt=0;
END
END
static void DecodeAdr(char *Asc, Byte Erl)
BEGIN
#define Reg8Cnt 7
static char *Reg8Names[Reg8Cnt]={"B","C","D","E","H","L","A"};
#define Reg16Cnt 7
static char *Reg16Names[Reg16Cnt]={"BC","DE","HL","\0","IX","IY","SP"};
#define IReg16Cnt 3
static char *IReg16Names[IReg16Cnt]={"IX","IY","SP"};
int z;
char *p,*ppos,*mpos;
LongInt DispAcc,DispVal;
Byte OccFlag,BaseReg;
Boolean ok,fnd,NegFlag,NNegFlag,Unknown;
String Part;
AdrType=ModNone; AdrCnt=0;
/* 1. 8-Bit-Register */
for (z=0; z<Reg8Cnt; z++)
if (strcasecmp(Asc,Reg8Names[z])==0)
BEGIN
AdrType=ModReg8; AdrMode=z; SetOpSize(0);
ChkAdr(Erl); return;
END
/* 2. 16-Bit-Register, indiziert */
if ((Erl & MModIReg16)!=0)
for (z=0; z<IReg16Cnt; z++)
if (strcasecmp(Asc,IReg16Names[z])==0)
BEGIN
AdrType=ModIReg16; AdrMode=z; SetOpSize(1);
ChkAdr(Erl); return;
END
/* 3. 16-Bit-Register, normal */
for (z=0; z<Reg16Cnt; z++)
if (strcasecmp(Asc,Reg16Names[z])==0)
BEGIN
AdrType=ModReg16; AdrMode=z; SetOpSize(1);
ChkAdr(Erl); return;
END
/* Speicheradresse */
if (IsIndirect(Asc))
BEGIN
OccFlag=0; BaseReg=0; DispAcc=0; ok=True; NegFlag=False; Unknown=False;
strcpy(Asc,Asc+1); Asc[strlen(Asc)-1]='\0';
do
BEGIN
ppos=QuotPos(Asc,'+');
mpos=QuotPos(Asc,'-');
if (ppos==Nil) p=mpos;
else if (mpos==Nil) p=ppos;
else p=min(mpos,ppos);
NNegFlag=((p!=Nil) AND (*p=='-'));
if (p==Nil)
BEGIN
strmaxcpy(Part,Asc,255); *Asc='\0';
END
else
BEGIN
*p='\0'; strmaxcpy(Part,Asc,255); strcpy(Asc,p+1);
END
fnd=False;
if (strcasecmp(Part,"A")==0)
BEGIN
fnd=True;
ok=((NOT NegFlag) AND ((OccFlag & 1)==0));
if (ok) OccFlag+=1; else WrError(1350);
END
if (NOT fnd)
for (z=0; z<Reg16Cnt; z++)
if (strcasecmp(Part,Reg16Names[z])==0)
BEGIN
fnd=True; BaseReg=z;
ok=((NOT NegFlag) AND ((OccFlag & 2)==0));
if (ok) OccFlag+=2; else WrError(1350);
END
if (NOT fnd)
BEGIN
FirstPassUnknown=False;
DispVal=EvalIntExpression(Part,Int32,&ok);
if (ok)
BEGIN
if (NegFlag) DispAcc-=DispVal; else DispAcc+=DispVal;
if (FirstPassUnknown) Unknown=True;
END
END
NegFlag=NNegFlag;
END
while ((*Asc!='\0') AND (ok));
if (NOT ok) return;
if (Unknown) DispAcc&=0x7f;
switch (OccFlag)
BEGIN
case 1:
WrError(1350); break;
case 3:
if ((BaseReg!=2) OR (DispAcc!=0)) WrError(1350);
else
BEGIN
AdrType=ModIdxReg; AdrMode=3;
END
break;
case 2:
if ((DispAcc>127) OR (DispAcc<-128)) WrError(1320);
else if (DispAcc==0)
BEGIN
AdrType=ModIndReg; AdrMode=BaseReg;
END
else if (BaseReg<4) WrError(1350);
else
BEGIN
AdrType=ModIdxReg; AdrMode=BaseReg-4;
AdrCnt=1; AdrVals[0]=DispAcc & 0xff;
END
break;
case 0:
if (DispAcc>0xffff) WrError(1925);
else if ((Hi(DispAcc)==0xff) AND ((Erl & MModDir)!=0))
BEGIN
AdrType=ModDir; AdrCnt=1; AdrVals[0]=Lo(DispAcc);
END
else
BEGIN
AdrType=ModMem; AdrCnt=2;
AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc);
END
break;
END
END
/* immediate */
else
BEGIN
if ((OpSize==-1) AND (MinOneIs0)) OpSize=0;
switch (OpSize)
BEGIN
case -1:
WrError(1130); break;
case 0:
AdrVals[0]=EvalIntExpression(Asc,Int8,&ok);
if (ok)
BEGIN
AdrType=ModImm; AdrCnt=1;
END
break;
case 1:
DispVal=EvalIntExpression(Asc,Int16,&ok);
if (ok)
BEGIN
AdrType=ModImm; AdrCnt=2;
AdrVals[0]=Lo(DispVal); AdrVals[1]=Hi(DispVal);
END
break;
END
END
/* gefunden */
ChkAdr(Erl);
END
/*--------------------------------------------------------------------------*/
static Boolean DecodePseudo(void)
BEGIN
return False;
END
static Boolean WMemo(char *Name)
BEGIN
String tmp;
if (Memo(Name)) return True;
sprintf(tmp,"%sW",Name);
if (Memo(tmp))
BEGIN
OpSize=1; return True;
END
else return False;
END
static Boolean ArgPair(char *Arg1, char *Arg2)
BEGIN
return (((strcasecmp(ArgStr[1],Arg1)==0) AND (strcasecmp(ArgStr[2],Arg2)==0))
OR ((strcasecmp(ArgStr[1],Arg2)==0) AND (strcasecmp(ArgStr[2],Arg1)==0)));
END
/*-------------------------------------------------------------------------*/
/* ohne Argument */
static void CodeFixed(Word Index)
BEGIN
if (ArgCnt!=0) WrError(1110);
else
BEGIN
CodeLen=1; BAsmCode[0]=FixedOrders[Index].Code;
END
END
static void CodeMove(Word Index)
BEGIN
if (ArgCnt!=0) WrError(1110);
else
BEGIN
CodeLen=2; BAsmCode[0]=0xfe; BAsmCode[1]=MoveOrders[Index].Code;
END
END
static void CodeShift(Word Index)
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],((ShiftOrders[Index].MayReg)?MModReg8:0)+MModIndReg+MModIdxReg+MModMem+MModDir);
switch (AdrType)
BEGIN
case ModReg8:
CodeLen=2; BAsmCode[0]=0xf8+AdrMode; BAsmCode[1]=ShiftOrders[Index].Code;
if (AdrMode==AccReg) WrError(10);
break;
case ModIndReg:
CodeLen=2; BAsmCode[0]=0xe0+AdrMode; BAsmCode[1]=ShiftOrders[Index].Code;
break;
case ModIdxReg:
CodeLen=2+AdrCnt; BAsmCode[0]=0xf0+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=ShiftOrders[Index].Code;
break;
case ModDir:
CodeLen=3; BAsmCode[0]=0xe7; BAsmCode[1]=AdrVals[0];
BAsmCode[2]=ShiftOrders[Index].Code;
break;
case ModMem:
CodeLen=4; BAsmCode[0]=0xe3;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
BAsmCode[3]=ShiftOrders[Index].Code;
break;
END
END
END
/* Logik */
static void CodeBit(Word Index)
BEGIN
Byte HReg;
Boolean OK;
if (ArgCnt!=2) WrError(1110);
else
BEGIN
HReg=EvalIntExpression(ArgStr[1],UInt3,&OK);
if (OK)
BEGIN
DecodeAdr(ArgStr[2],MModReg8+MModIndReg+MModIdxReg+MModMem+MModDir);
switch (AdrType)
BEGIN
case ModReg8:
CodeLen=2;
BAsmCode[0]=0xf8+AdrMode; BAsmCode[1]=BitOrders[Index].Code+HReg;
break;
case ModIndReg:
CodeLen=2;
BAsmCode[0]=0xe0+AdrMode; BAsmCode[1]=BitOrders[Index].Code+HReg;
break;
case ModIdxReg:
CodeLen=2+AdrCnt; memcpy(BAsmCode+1,AdrVals,AdrCnt);
BAsmCode[0]=0xf0+AdrMode; BAsmCode[1+AdrCnt]=BitOrders[Index].Code+HReg;
break;
case ModMem:
CodeLen=4; memcpy(BAsmCode+1,AdrVals,AdrCnt);
BAsmCode[0]=0xe3; BAsmCode[1+AdrCnt]=BitOrders[Index].Code+HReg;
break;
case ModDir:
BAsmCode[1]=AdrVals[0];
if (Index==4)
BEGIN
BAsmCode[0]=0xe7; BAsmCode[2]=BitOrders[Index].Code+HReg; CodeLen=3;
END
else
BEGIN
BAsmCode[0]=BitOrders[Index].Code+HReg; CodeLen=2;
END
break;
END
END
END
END
static void CodeAcc(Word Index)
BEGIN
if (ArgCnt!=1) WrError(1110);
else if (strcasecmp(ArgStr[1],"A")!=0) WrError(1350);
else
BEGIN
CodeLen=1; BAsmCode[0]=AccOrders[Index].Code;
END
END
static void MakeCode_90C141(void)
BEGIN
int z;
Integer AdrInt;
Boolean OK;
Byte HReg;
CodeLen=0; DontPrint=False; OpSize=(-1);
/* zu ignorierendes */
if (Memo("")) return;
/* Pseudoanweisungen */
if (DecodePseudo()) return;
if (DecodeIntelPseudo(False)) return;
if (SearchInstTree(ITree,OpPart)) return;
/* Datentransfer */
if (WMemo("LD"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg8+MModReg16+MModIndReg+MModIdxReg+MModDir+MModMem);
switch (AdrType)
BEGIN
case ModReg8:
HReg=AdrMode;
DecodeAdr(ArgStr[2],MModReg8+MModIndReg+MModIdxReg+MModDir+MModMem+MModImm);
switch (AdrType)
BEGIN
case ModReg8:
if (HReg==AccReg)
BEGIN
CodeLen=1; BAsmCode[0]=0x20+AdrMode;
END
else if (AdrMode==AccReg)
BEGIN
CodeLen=1; BAsmCode[0]=0x28+HReg;
END
else
BEGIN
CodeLen=2; BAsmCode[0]=0xf8+AdrMode; BAsmCode[1]=0x30+HReg;
END
break;
case ModIndReg:
CodeLen=2; BAsmCode[0]=0xe0+AdrMode; BAsmCode[1]=0x28+HReg;
break;
case ModIdxReg:
CodeLen=2+AdrCnt; BAsmCode[0]=0xf0+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=0x28+HReg;
break;
case ModDir:
if (HReg==AccReg)
BEGIN
CodeLen=2; BAsmCode[0]=0x27; BAsmCode[1]=AdrVals[0];
END
else
BEGIN
CodeLen=3; BAsmCode[0]=0xe7; BAsmCode[1]=AdrVals[0];
BAsmCode[2]=0x28+HReg;
END
break;
case ModMem:
CodeLen=4; BAsmCode[0]=0xe3;
memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[3]=0x28+HReg;
break;
case ModImm:
CodeLen=2; BAsmCode[0]=0x30+HReg; BAsmCode[1]=AdrVals[0];
break;
END
break;
case ModReg16:
HReg=AdrMode;
DecodeAdr(ArgStr[2],MModReg16+MModIndReg+MModIdxReg+MModDir+MModMem+MModImm);
switch (AdrType)
BEGIN
case ModReg16:
if (HReg==HLReg)
BEGIN
CodeLen=1; BAsmCode[0]=0x40+AdrMode;
END
else if (AdrMode==HLReg)
BEGIN
CodeLen=1; BAsmCode[0]=0x48+HReg;
END
else
BEGIN
CodeLen=2; BAsmCode[0]=0xf8+AdrMode; BAsmCode[1]=0x38+HReg;
END
break;
case ModIndReg:
CodeLen=2;
BAsmCode[0]=0xe0+AdrMode; BAsmCode[1]=0x48+HReg;
break;
case ModIdxReg:
CodeLen=2+AdrCnt; BAsmCode[0]=0xf0+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=0x48+HReg;
break;
case ModDir:
if (HReg==HLReg)
BEGIN
CodeLen=2; BAsmCode[0]=0x47; BAsmCode[1]=AdrVals[0];
END
else
BEGIN
CodeLen=3; BAsmCode[0]=0xe7; BAsmCode[1]=AdrVals[0];
BAsmCode[2]=0x48+HReg;
END
break;
case ModMem:
CodeLen=4; BAsmCode[0]=0xe3; BAsmCode[3]=0x48+HReg;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
break;
case ModImm:
CodeLen=3; BAsmCode[0]=0x38+HReg;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
break;
END
break;
case ModIndReg:
case ModIdxReg:
case ModDir:
case ModMem:
MinOneIs0=True; HReg=AdrCnt; memcpy(BAsmCode+1,AdrVals,AdrCnt);
switch (AdrType)
BEGIN
case ModIndReg: BAsmCode[0]=0xe8+AdrMode; break;
case ModIdxReg: BAsmCode[0]=0xf4+AdrMode; break;
case ModMem: BAsmCode[0]=0xeb; break;
case ModDir: BAsmCode[0]=0x0f; break;
END
DecodeAdr(ArgStr[2],MModReg16+MModReg8+MModImm);
if (BAsmCode[0]==0x0f)
switch (AdrType)
BEGIN
case ModReg8:
if (AdrMode==AccReg)
BEGIN
CodeLen=2; BAsmCode[0]=0x2f;
END
else
BEGIN
CodeLen=3; BAsmCode[0]=0xef; BAsmCode[2]=0x20+AdrMode;
END
break;
case ModReg16:
if (AdrMode==HLReg)
BEGIN
CodeLen=2; BAsmCode[0]=0x4f;
END
else
BEGIN
CodeLen=3; BAsmCode[0]=0xef; BAsmCode[2]=0x40+AdrMode;
END
break;
case ModImm:
CodeLen=3+OpSize; BAsmCode[0]=0x37+(OpSize << 3);
memcpy(BAsmCode+2,AdrVals,AdrCnt);
break;
END
else
BEGIN
switch (AdrType)
BEGIN
case ModReg8: BAsmCode[1+HReg]=0x20+AdrMode; break;
case ModReg16: BAsmCode[1+HReg]=0x40+AdrMode; break;
case ModImm: BAsmCode[1+HReg]=0x37+(OpSize << 3); break;
END
memcpy(BAsmCode+2+HReg,AdrVals,AdrCnt);
CodeLen=1+HReg+1+AdrCnt;
END
break;
END
END
return;
END
if ((Memo("PUSH")) OR (Memo("POP")))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
HReg=Ord(Memo("POP")) << 3;
if (strcasecmp(ArgStr[1],"AF")==0)
BEGIN
CodeLen=1; BAsmCode[0]=0x56+HReg;
END
else
BEGIN
DecodeAdr(ArgStr[1],MModReg16);
if (AdrType==ModReg16)
if (AdrMode==6) WrError(1350);
else
BEGIN
CodeLen=1; BAsmCode[0]=0x50+HReg+AdrMode;
END
END
END
return;
END
if (Memo("LDA"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg16);
if (AdrType==ModReg16)
BEGIN
HReg=0x38+AdrMode;
DecodeAdr(ArgStr[2],MModIndReg+MModIdxReg);
switch (AdrType)
BEGIN
case ModIndReg:
if (AdrMode<4) WrError(1350);
else
BEGIN
CodeLen=3; BAsmCode[0]=0xf0+AdrMode;
BAsmCode[1]=0; BAsmCode[2]=HReg;
END
break;
case ModIdxReg:
CodeLen=2+AdrCnt; BAsmCode[0]=0xf4+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=HReg;
break;
END
END
END
return;
END
if (Memo("LDAR"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else if (strcasecmp(ArgStr[1],"HL")!=0) WrError(1350);
else
BEGIN
AdrInt=EvalIntExpression(ArgStr[2],Int16,&OK)-(EProgCounter()+2);
if (OK)
BEGIN
CodeLen=3; BAsmCode[0]=0x17;
BAsmCode[1]=Lo(AdrInt); BAsmCode[2]=Hi(AdrInt);
END
END
return;
END
if (Memo("EX"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else if (ArgPair("DE","HL"))
BEGIN
CodeLen=1; BAsmCode[0]=0x08;
END
else if ((ArgPair("AF","AF\'") OR ArgPair("AF","AF`")))
BEGIN
CodeLen=1; BAsmCode[0]=0x09;
END
else
BEGIN
DecodeAdr(ArgStr[1],MModReg16+MModIndReg+MModIdxReg+MModMem+MModDir);
switch (AdrType)
BEGIN
case ModReg16:
HReg=0x50+AdrMode;
DecodeAdr(ArgStr[2],MModIndReg+MModIdxReg+MModMem+MModDir);
switch (AdrType)
BEGIN
case ModIndReg:
CodeLen=2; BAsmCode[0]=0xe0+AdrMode; BAsmCode[1]=HReg;
break;
case ModIdxReg:
CodeLen=2+AdrCnt; BAsmCode[0]=0xf0+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
BAsmCode[1+AdrCnt]=HReg;
break;
case ModDir:
CodeLen=3; BAsmCode[0]=0xe7; BAsmCode[1]=AdrVals[0];
BAsmCode[2]=HReg;
break;
case ModMem:
CodeLen=4; BAsmCode[0]=0xe3; memcpy(BAsmCode+1,AdrVals,AdrCnt);
BAsmCode[3]=HReg;
break;
END
break;
case ModIndReg:
case ModIdxReg:
case ModDir:
case ModMem:
switch (AdrType)
BEGIN
case ModIndReg: BAsmCode[0]=0xe0+AdrMode; break;
case ModIdxReg: BAsmCode[0]=0xf0+AdrMode; break;
case ModDir: BAsmCode[0]=0xe7; break;
case ModMem: BAsmCode[0]=0xe3; break;
END
memcpy(BAsmCode+1,AdrVals,AdrCnt); HReg=2+AdrCnt;
DecodeAdr(ArgStr[2],MModReg16);
if (AdrType==ModReg16)
BEGIN
BAsmCode[HReg-1]=0x50+AdrMode; CodeLen=HReg;
END
break;
END
END
return;
END
/* Arithmetik */
for (z=0; z<ALU2OrderCnt; z++)
if (Memo(ALU2Orders[z]))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg8+MModReg16+MModIdxReg+MModIndReg+MModDir+MModMem);
switch (AdrType)
BEGIN
case ModReg8:
DecodeAdr(ArgStr[2],MModImm+(((HReg=AdrMode)==AccReg)?MModReg8+MModIndReg+MModIdxReg+MModDir+MModMem:0));
switch(AdrType)
BEGIN
case ModReg8:
CodeLen=2;
BAsmCode[0]=0xf8+AdrMode; BAsmCode[1]=0x60+z;
break;
case ModIndReg:
CodeLen=2;
BAsmCode[0]=0xe0+AdrMode; BAsmCode[1]=0x60+z;
break;
case ModIdxReg:
CodeLen=2+AdrCnt;
BAsmCode[0]=0xf0+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
BAsmCode[1+AdrCnt]=0x60+z;
break;
case ModDir:
CodeLen=2;
BAsmCode[0]=0x60+z;
BAsmCode[1]=AdrVals[0];
break;
case ModMem:
CodeLen=4;
BAsmCode[0]=0xe3; BAsmCode[3]=0x60+z;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
break;
case ModImm:
if (HReg==AccReg)
BEGIN
CodeLen=2;
BAsmCode[0]=0x68+z; BAsmCode[1]=AdrVals[0];
END
else
BEGIN
CodeLen=3;
BAsmCode[0]=0xf8+HReg; BAsmCode[1]=0x68+z;
BAsmCode[2]=AdrVals[0];
END
break;
END
break;
case ModReg16:
if ((AdrMode==2) OR ((z==0) AND (AdrMode>=4)))
BEGIN
HReg=AdrMode;
DecodeAdr(ArgStr[2],MModReg16+MModIndReg+MModIdxReg+MModDir+MModMem+MModImm);
switch (AdrType)
BEGIN
case ModReg16:
CodeLen=2;
BAsmCode[0]=0xf8+AdrMode;
BAsmCode[1]=(HReg>=4) ? 0x14+HReg-4 : 0x70+z;
break;
case ModIndReg:
CodeLen=2;
BAsmCode[0]=0xe0+AdrMode;
BAsmCode[1]=(HReg>=4) ? 0x14+HReg-4 : 0x70+z;
break;
case ModIdxReg:
CodeLen=2+AdrCnt;
BAsmCode[0]=0xf0+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
BAsmCode[1+AdrCnt]=(HReg>=4) ? 0x14+HReg-4 : 0x70+z;
break;
case ModDir:
if (HReg>=4)
BEGIN
CodeLen=3;
BAsmCode[0]=0xe7;
BAsmCode[1]=AdrVals[0];
BAsmCode[2]=0x10+HReg;
END
else
BEGIN
CodeLen=2;
BAsmCode[0]=0x70+z; BAsmCode[1]=AdrVals[0];
END
break;
case ModMem:
CodeLen=4;
BAsmCode[0]=0xe3;
memcpy(BAsmCode+1,AdrVals,2);
BAsmCode[3]=(HReg>=4) ? 0x14+HReg-4 : 0x70+z;
break;
case ModImm:
CodeLen=3;
BAsmCode[0]=(HReg>=4) ? 0x14+HReg-4 : 0x78+z;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
break;
END
END
else WrError(1350);
break;
case ModIndReg:
case ModIdxReg:
case ModDir:
case ModMem:
OpSize=0;
switch (AdrType)
BEGIN
case ModIndReg:
HReg=3;
BAsmCode[0]=0xe8+AdrMode; BAsmCode[1]=0x68+z;
break;
case ModIdxReg:
HReg=3+AdrCnt;
BAsmCode[0]=0xf4+AdrMode; BAsmCode[1+AdrCnt]=0x68+z;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
break;
case ModDir:
HReg=4;
BAsmCode[0]=0xef; BAsmCode[1]=AdrVals[0]; BAsmCode[2]=0x68+z;
break;
case ModMem:
HReg=5;
BAsmCode[0]=0xeb; memcpy(BAsmCode+1,AdrVals,2); BAsmCode[3]=0x68+z;
break;
default:
HReg=0;
END
DecodeAdr(ArgStr[2],MModImm);
if (AdrType==ModImm)
BEGIN
BAsmCode[HReg-1]=AdrVals[0]; CodeLen=HReg;
END
break;
END
END
return;
END
if ((WMemo("INC")) OR (WMemo("DEC")))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
HReg=Ord(WMemo("DEC")) << 3;
DecodeAdr(ArgStr[1],MModReg8+MModReg16+MModIndReg+MModIdxReg+MModDir+MModMem);
if (OpSize==-1) OpSize=0;
switch (AdrType)
BEGIN
case ModReg8:
CodeLen=1; BAsmCode[0]=0x80+HReg+AdrMode;
break;
case ModReg16:
CodeLen=1; BAsmCode[0]=0x90+HReg+AdrMode;
break;
case ModIndReg:
CodeLen=2; BAsmCode[0]=0xe0+AdrMode;
BAsmCode[1]=0x87+(OpSize << 4)+HReg;
break;
case ModIdxReg:
CodeLen=2+AdrCnt; BAsmCode[0]=0xf0+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
BAsmCode[1+AdrCnt]=0x87+(OpSize << 4)+HReg;
break;
case ModDir:
CodeLen=2; BAsmCode[0]=0x87+(OpSize << 4)+HReg;
BAsmCode[1]=AdrVals[0];
break;
case ModMem:
CodeLen=4; BAsmCode[0]=0xe3;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
BAsmCode[3]=0x87+(OpSize << 4)+HReg;
BAsmCode[1]=AdrVals[0];
break;
END
END
return;
END
if ((Memo("INCX")) OR (Memo("DECX")))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModDir);
if (AdrType==ModDir)
BEGIN
CodeLen=2;
BAsmCode[0]=0x07+(Ord(Memo("DECX")) << 3);
BAsmCode[1]=AdrVals[0];
END
END
return;
END
if ((Memo("MUL")) OR (Memo("DIV")))
BEGIN
if (ArgCnt!=2) WrError(1110);
else if (strcasecmp(ArgStr[1],"HL")!=0) WrError(1350);
else
BEGIN
HReg=0x12+Ord(Memo("DIV")); OpSize=0;
DecodeAdr(ArgStr[2],MModReg8+MModIndReg+MModIdxReg+MModDir+MModMem+MModImm);
switch (AdrType)
BEGIN
case ModReg8:
CodeLen=2;
BAsmCode[0]=0xf8+AdrMode; BAsmCode[1]=HReg;
break;
case ModIndReg:
CodeLen=2;
BAsmCode[0]=0xe0+AdrMode; BAsmCode[1]=HReg;
break;
case ModIdxReg:
CodeLen=2+AdrCnt;
BAsmCode[0]=0xf0+AdrMode; BAsmCode[1+AdrCnt]=HReg;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
break;
case ModDir:
CodeLen=3; BAsmCode[0]=0xe7;
BAsmCode[1]=AdrVals[0]; BAsmCode[2]=HReg;
break;
case ModMem:
CodeLen=4; BAsmCode[0]=0xe3; BAsmCode[3]=HReg;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
break;
case ModImm:
CodeLen=3; BAsmCode[0]=0xe7; BAsmCode[1]=AdrVals[0]; BAsmCode[2]=HReg;
break;
END
END
return;
END
/* Spruenge */
if (Memo("JR"))
BEGIN
if ((ArgCnt==0) OR (ArgCnt>2)) WrError(1110);
else
BEGIN
if (ArgCnt==1) z=DefaultCondition;
else
BEGIN
NLS_UpString(ArgStr[1]);
for (z=0; z<ConditionCnt; z++)
if (strcmp(ArgStr[1],Conditions[z].Name)==0) break;
END
if (z>=ConditionCnt) WrError(1360);
else
BEGIN
AdrInt=EvalIntExpression(ArgStr[ArgCnt],Int16,&OK)-(EProgCounter()+2);
if (OK)
if ((NOT SymbolQuestionable) AND ((AdrInt>127) OR (AdrInt<-128))) WrError(1370);
else
BEGIN
CodeLen=2;
BAsmCode[0]=0xc0+Conditions[z].Code;
BAsmCode[1]=AdrInt & 0xff;
END
END
END
return;
END
if ((Memo("CALL")) OR (Memo("JP")))
BEGIN
if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110);
else
BEGIN
if (ArgCnt==1) z=DefaultCondition;
else
BEGIN
NLS_UpString(ArgStr[1]);
for (z=0; z<ConditionCnt; z++)
if (strcmp(Conditions[z].Name,ArgStr[1])==0) break;
END
if (z>=ConditionCnt) WrError(1360);
else
BEGIN
OpSize=1; HReg=Ord(Memo("CALL"));
DecodeAdr(ArgStr[ArgCnt],MModIndReg+MModIdxReg+MModMem+MModImm);
if (AdrType==ModImm) AdrType=ModMem;
switch (AdrType)
BEGIN
case ModIndReg:
CodeLen=2;
BAsmCode[0]=0xe8+AdrMode;
BAsmCode[1]=0xc0+(HReg << 4)+Conditions[z].Code;
break;
case ModIdxReg:
CodeLen=2+AdrCnt;
BAsmCode[0]=0xf4+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
BAsmCode[1+AdrCnt]=0xc0+(HReg << 4)+Conditions[z].Code;
break;
case ModMem:
if (z==DefaultCondition)
BEGIN
CodeLen=3;
BAsmCode[0]=0x1a+(HReg << 1);
memcpy(BAsmCode+1,AdrVals,AdrCnt);
END
else
BEGIN
CodeLen=4;
BAsmCode[0]=0xeb;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
BAsmCode[3]=0xc0+(HReg << 4)+Conditions[z].Code;
END
break;
END
END
END
return;
END
if (Memo("RET"))
BEGIN
if ((ArgCnt!=0) AND (ArgCnt!=1)) WrError(1110);
else
BEGIN
if (ArgCnt==0) z=DefaultCondition;
else
BEGIN
NLS_UpString(ArgStr[1]);
for (z=0; z<ConditionCnt; z++)
if (strcmp(ArgStr[1],Conditions[z].Name)==0) break;
END
if (z>=ConditionCnt) WrError(1360);
if (z==DefaultCondition)
BEGIN
CodeLen=1; BAsmCode[0]=0x1e;
END
else if (z<ConditionCnt)
BEGIN
CodeLen=2; BAsmCode[0]=0xfe;
BAsmCode[1]=0xd0+Conditions[z].Code;
END
END
return;
END
if (Memo("DJNZ"))
BEGIN
if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110);
else
BEGIN
if (ArgCnt==1)
BEGIN
AdrType=ModReg8; AdrMode=0; OpSize=0;
END
else DecodeAdr(ArgStr[1],MModReg8+MModReg16);
if (AdrType!=ModNone)
if (AdrMode!=0) WrError(1350);
else
BEGIN
AdrInt=EvalIntExpression(ArgStr[ArgCnt],Int16,&OK)-(EProgCounter()+2);
if (OK)
if ((NOT SymbolQuestionable) AND ((AdrInt>127) OR (AdrInt<-128))) WrError(1370);
else
BEGIN
CodeLen=2;
BAsmCode[0]=0x18+OpSize;
BAsmCode[1]=AdrInt & 0xff;
END
END
END
return;
END
if ((Memo("JRL")) OR (Memo("CALR")))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
AdrInt=EvalIntExpression(ArgStr[1],Int16,&OK)-(EProgCounter()+2);
if (OK)
BEGIN
CodeLen=3;
if (Memo("JRL"))
BEGIN
BAsmCode[0]=0x1b;
if ((AdrInt>=-128) AND (AdrInt<=127)) WrError(20);
END
else BAsmCode[0]=0x1d;
BAsmCode[1]=Lo(AdrInt); BAsmCode[2]=Hi(AdrInt);
END
END
return;
END
WrXError(1200,OpPart);
END
/*-------------------------------------------------------------------------*/
static void AddFixed(char *NName, Byte NCode)
BEGIN
if (InstrZ>=FixedOrderCnt) exit(255);
FixedOrders[InstrZ].Code=NCode;
AddInstTree(&ITree,NName,CodeFixed,InstrZ++);
END
static void AddMove(char *NName, Byte NCode)
BEGIN
if (InstrZ>=MoveOrderCnt) exit(255);
MoveOrders[InstrZ].Code=NCode;
AddInstTree(&ITree,NName,CodeMove,InstrZ++);
END
static void AddShift(char *NName, Byte NCode, Boolean NMay)
BEGIN
if (InstrZ>=ShiftOrderCnt) exit(255);
ShiftOrders[InstrZ].Code=NCode;
ShiftOrders[InstrZ].MayReg=NMay;
AddInstTree(&ITree,NName,CodeShift,InstrZ++);
END
static void AddBit(char *NName, Byte NCode)
BEGIN
if (InstrZ>=BitOrderCnt) exit(255);
BitOrders[InstrZ].Code=NCode;
AddInstTree(&ITree,NName,CodeBit,InstrZ++);
END
static void AddAcc(char *NName, Byte NCode)
BEGIN
if (InstrZ>=AccOrderCnt) exit(255);
AccOrders[InstrZ].Code=NCode;
AddInstTree(&ITree,NName,CodeAcc,InstrZ++);
END
static void AddCondition(char *NName, Byte NCode)
BEGIN
if (InstrZ>=ConditionCnt) exit(255);
Conditions[InstrZ].Name=NName;
Conditions[InstrZ++].Code=NCode;
END
static void InitFields(void)
BEGIN
ITree=Nil;
FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); InstrZ=0;
AddFixed("EXX" ,0x0a); AddFixed("CCF" ,0x0e);
AddFixed("SCF" ,0x0d); AddFixed("RCF" ,0x0c);
AddFixed("NOP" ,0x00); AddFixed("HALT",0x01);
AddFixed("DI" ,0x02); AddFixed("EI" ,0x03);
AddFixed("SWI" ,0xff); AddFixed("RLCA",0xa0);
AddFixed("RRCA",0xa1); AddFixed("RLA" ,0xa2);
AddFixed("RRA" ,0xa3); AddFixed("SLAA",0xa4);
AddFixed("SRAA",0xa5); AddFixed("SLLA",0xa6);
AddFixed("SRLA",0xa7); AddFixed("RETI",0x1f);
MoveOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*MoveOrderCnt); InstrZ=0;
AddMove("LDI" ,0x58);
AddMove("LDIR",0x59);
AddMove("LDD" ,0x5a);
AddMove("LDDR",0x5b);
AddMove("CPI" ,0x5c);
AddMove("CPIR",0x5d);
AddMove("CPD" ,0x5e);
AddMove("CPDR",0x5f);
ShiftOrders=(ShiftOrder *) malloc(sizeof(ShiftOrder)*ShiftOrderCnt); InstrZ=0;
AddShift("RLC",0xa0,True );
AddShift("RRC",0xa1,True );
AddShift("RL" ,0xa2,True );
AddShift("RR" ,0xa3,True );
AddShift("SLA",0xa4,True );
AddShift("SRA",0xa5,True );
AddShift("SLL",0xa6,True );
AddShift("SRL",0xa7,True );
AddShift("RLD",0x10,False);
AddShift("RRD",0x11,False);
BitOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*BitOrderCnt); InstrZ=0;
AddBit("BIT" ,0xa8);
AddBit("SET" ,0xb8);
AddBit("RES" ,0xb0);
AddBit("TSET",0x18);
AccOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*AccOrderCnt); InstrZ=0;
AddAcc("DAA",0x0b);
AddAcc("CPL",0x10);
AddAcc("NEG",0x11);
ALU2Orders=(char **) malloc(sizeof(char *)*ALU2OrderCnt); InstrZ=0;
ALU2Orders[InstrZ++]="ADD"; ALU2Orders[InstrZ++]="ADC";
ALU2Orders[InstrZ++]="SUB"; ALU2Orders[InstrZ++]="SBC";
ALU2Orders[InstrZ++]="AND"; ALU2Orders[InstrZ++]="XOR";
ALU2Orders[InstrZ++]="OR"; ALU2Orders[InstrZ++]="CP";
Conditions=(Condition *) malloc(sizeof(Condition)*ConditionCnt); InstrZ=0;
AddCondition("F" , 0); DefaultCondition=InstrZ; AddCondition("T" , 8);
AddCondition("Z" , 6); AddCondition("NZ" , 14);
AddCondition("C" , 7); AddCondition("NC" , 15);
AddCondition("PL" , 13); AddCondition("MI" , 5);
AddCondition("P" , 13); AddCondition("M" , 5);
AddCondition("NE" , 14); AddCondition("EQ" , 6);
AddCondition("OV" , 4); AddCondition("NOV", 12);
AddCondition("PE" , 4); AddCondition("PO" , 12);
AddCondition("GE" , 9); AddCondition("LT" , 1);
AddCondition("GT" , 10); AddCondition("LE" , 2);
AddCondition("UGE", 15); AddCondition("ULT", 7);
AddCondition("UGT", 11); AddCondition("ULE", 3);
END
static void DeinitFields(void)
BEGIN
ClearInstTree(&ITree);
free(FixedOrders);
free(MoveOrders);
free(ShiftOrders);
free(BitOrders);
free(AccOrders);
free(ALU2Orders);
free(Conditions);
END
/*-------------------------------------------------------------------------*/
static Boolean IsDef_90C141(void)
BEGIN
return False;
END
static void SwitchFrom_90C141(void)
BEGIN
DeinitFields();
END
static void SwitchTo_90C141(void)
BEGIN
TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=True;
PCSymbol="$"; HeaderID=0x53; NOPCode=0x00;
DivideChars=","; HasAttrs=False;
ValidSegs=1<<SegCode;
Grans[SegCode]=1; ListGrans[SegCode]=1; SegInits[SegCode]=0;
SegLimits[SegCode] = 0xffff;
MakeCode=MakeCode_90C141; IsDef=IsDef_90C141;
SwitchFrom=SwitchFrom_90C141; InitFields();
END
void code90c141_init(void)
BEGIN
CPU90C141=AddCPU("90C141",SwitchTo_90C141);
END