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

1317 lines
31 KiB
C

/* code87c800.c */
/*****************************************************************************/
/* AS-Portierung */
/* */
/* Codegenerator TLCS-870 */
/* */
/* Historie: 29.12.1996 Grundsteinlegung */
/* 2. 1.1999 ChkPC umgebaut */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <ctype.h>
#include <string.h>
#include "nls.h"
#include "bpemu.h"
#include "strutil.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "codepseudo.h"
#include "codevars.h"
typedef struct
{
char *Name;
Word Code;
} FixedOrder;
typedef struct
{
char *Name;
Byte Code;
} CondRec;
#define FixedOrderCnt 7
#define ConditionCnt 12
#define RegOrderCnt 7
#define ALUOrderCnt 8
#define ModNone (-1)
#define ModReg8 0
#define MModReg8 (1 << ModReg8)
#define ModReg16 1
#define MModReg16 (1 << ModReg16)
#define ModImm 2
#define MModImm (1 << ModImm)
#define ModAbs 3
#define MModAbs (1 << ModAbs)
#define ModMem 4
#define MModMem (1 << ModMem)
#define AccReg 0
#define WAReg 0
#define Reg8Cnt 8
static char *Reg8Names="AWCBEDLH";
static CPUVar CPU87C00,CPU87C20,CPU87C40,CPU87C70;
static ShortInt OpSize;
static Byte AdrVals[4];
static ShortInt AdrType;
static Byte AdrMode;
static FixedOrder *FixedOrders;
static CondRec *Conditions;
static FixedOrder *RegOrders;
static char **ALUOrders;
/*--------------------------------------------------------------------------*/
static void AddFixed(char *NName, Word NCode)
BEGIN
if (InstrZ>=FixedOrderCnt) exit(255);
FixedOrders[InstrZ].Name=NName;
FixedOrders[InstrZ++].Code=NCode;
END
static void AddCond(char *NName, Byte NCode)
BEGIN
if (InstrZ>=ConditionCnt) exit(255);
Conditions[InstrZ].Name=NName;
Conditions[InstrZ++].Code=NCode;
END
static void AddReg(char *NName, Word NCode)
BEGIN
if (InstrZ>=RegOrderCnt) exit(255);
RegOrders[InstrZ].Name=NName;
RegOrders[InstrZ++].Code=NCode;
END
static void InitFields(void)
BEGIN
FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); InstrZ=0;
AddFixed("DI" , 0x483a);
AddFixed("EI" , 0x403a);
AddFixed("RET" , 0x0005);
AddFixed("RETI", 0x0004);
AddFixed("RETN", 0xe804);
AddFixed("SWI" , 0x00ff);
AddFixed("NOP" , 0x0000);
Conditions=(CondRec *) malloc(sizeof(CondRec)*ConditionCnt); InstrZ=0;
AddCond("EQ", 0); AddCond("Z" , 0);
AddCond("NE", 1); AddCond("NZ", 1);
AddCond("CS", 2); AddCond("LT", 2);
AddCond("CC", 3); AddCond("GE", 3);
AddCond("LE", 4); AddCond("GT", 5);
AddCond("T" , 6); AddCond("F" , 7);
RegOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*RegOrderCnt); InstrZ=0;
AddReg("DAA" , 0x0a); AddReg("DAS" , 0x0b);
AddReg("SHLC", 0x1c); AddReg("SHRC", 0x1d);
AddReg("ROLC", 0x1e); AddReg("RORC", 0x1f);
AddReg("SWAP", 0x01);
ALUOrders=(char **) malloc(sizeof(char *)*ALUOrderCnt); InstrZ=0;
ALUOrders[InstrZ++]="ADDC";
ALUOrders[InstrZ++]="ADD";
ALUOrders[InstrZ++]="SUBB";
ALUOrders[InstrZ++]="SUB";
ALUOrders[InstrZ++]="AND";
ALUOrders[InstrZ++]="XOR";
ALUOrders[InstrZ++]="OR";
ALUOrders[InstrZ++]="CMP";
END
static void DeinitFields(void)
BEGIN
free(FixedOrders);
free(Conditions);
free(RegOrders);
free(ALUOrders);
END
/*--------------------------------------------------------------------------*/
static void ChkAdr(Byte Erl)
BEGIN
if ((AdrType!=ModNone) AND (((1<<AdrType)&Erl)==0))
BEGIN
AdrType=ModNone; AdrCnt=0; WrError(1350);
END
END
static void DecodeAdr(char *Asc, Byte Erl)
BEGIN
#define Reg16Cnt 4
static char *Reg16Names[Reg16Cnt]={"WA","BC","DE","HL"};
#define AdrRegCnt 5
static char *AdrRegs[AdrRegCnt]={"HL","DE","C","PC","A"};
int z;
Byte RegFlag;
LongInt DispAcc,DispPart;
String AdrPart;
Boolean OK,NegFlag,NNegFlag,FirstFlag;
char *PPos,*NPos,*EPos;
AdrType=ModNone; AdrCnt=0;
if (strlen(Asc)==1)
for (z=0; z<Reg8Cnt; z++)
if (toupper(*Asc)==Reg8Names[z])
BEGIN
AdrType=ModReg8; OpSize=0; AdrMode=z;
ChkAdr(Erl); return;
END
for (z=0; z<Reg16Cnt; z++)
if (strcasecmp(Asc,Reg16Names[z])==0)
BEGIN
AdrType=ModReg16; OpSize=1; AdrMode=z;
ChkAdr(Erl); return;
END
if (IsIndirect(Asc))
BEGIN
strcpy(Asc,Asc+1); Asc[strlen(Asc)-1]='\0';
if (strcasecmp(Asc,"-HL")==0)
BEGIN
AdrType=ModMem; AdrMode=7; ChkAdr(Erl); return;
END
if (strcasecmp(Asc,"HL+")==0)
BEGIN
AdrType=ModMem; AdrMode=6; ChkAdr(Erl); return;
END
RegFlag=0; DispAcc=0; NegFlag=False; OK=True; FirstFlag=False;
while ((OK) AND (*Asc!='\0'))
BEGIN
PPos=QuotPos(Asc,'+'); NPos=QuotPos(Asc,'-');
if (PPos==Nil) EPos=NPos;
else if (NPos==Nil) EPos=PPos;
else EPos=min(NPos,PPos);
NNegFlag=((EPos!=Nil) AND (*EPos=='-'));
if (EPos==Nil)
BEGIN
strmaxcpy(AdrPart,Asc,255); *Asc='\0';
END
else
BEGIN
*EPos='\0'; strmaxcpy(AdrPart,Asc,255); strcpy(Asc,EPos+1);
END
for (z=0; z<AdrRegCnt; z++)
if (strcasecmp(AdrPart,AdrRegs[z])==0) break;
if (z>=AdrRegCnt)
BEGIN
FirstPassUnknown=False;
DispPart=EvalIntExpression(AdrPart,Int32,&OK);
FirstFlag|=FirstPassUnknown;
if (NegFlag) DispAcc-=DispPart; else DispAcc+=DispPart;
END
else if ((NegFlag) OR ((RegFlag & (1 << z))!=0))
BEGIN
WrError(1350); OK=False;
END
else RegFlag+=1 << z;
NegFlag=NNegFlag;
END
if (DispAcc!=0) RegFlag+=1 << AdrRegCnt;
if (OK)
switch (RegFlag)
BEGIN
case 0x20:
if (FirstFlag) DispAcc&=0xff;
if (DispAcc>0xff) WrError(1320);
else
BEGIN
AdrType=ModAbs; AdrMode=0;
AdrCnt=1; AdrVals[0]=DispAcc & 0xff;
END
break;
case 0x02:
AdrType=ModMem; AdrMode=2;
break;
case 0x01:
AdrType=ModMem; AdrMode=3;
break;
case 0x21:
if (FirstFlag) DispAcc&=0x7f;
if (DispAcc>127) WrError(1320);
else if (DispAcc<-128) WrError(1315);
else
BEGIN
AdrType=ModMem; AdrMode=4;
AdrCnt=1; AdrVals[0]=DispAcc & 0xff;
END
break;
case 0x05:
AdrType=ModMem; AdrMode=5;
break;
case 0x18:
AdrType=ModMem; AdrMode=1;
break;
default:
WrError(1350);
END
ChkAdr(Erl); return;
END
else
switch (OpSize)
BEGIN
case -1:
WrError(1132);
break;
case 0:
AdrVals[0]=EvalIntExpression(Asc,Int8,&OK);
if (OK)
BEGIN
AdrType=ModImm; AdrCnt=1;
END
break;
case 1:
DispAcc=EvalIntExpression(Asc,Int16,&OK);
if (OK)
BEGIN
AdrType=ModImm; AdrCnt=2;
AdrVals[0]=DispAcc & 0xff;
AdrVals[1]=(DispAcc >> 8) & 0xff;
END
break;
END
ChkAdr(Erl);
END
static Boolean SplitBit(char *Asc, Byte *Erg)
BEGIN
char *p;
String Part;
p=RQuotPos(Asc,'.');
if (p==Nil) return False;
*p='\0'; strmaxcpy(Part,p+1,255);
if (strlen(Part)!=1) return False;
else
if ((*Part>='0') AND (*Part<='7'))
BEGIN
*Erg=(*Part)-'0'; return True;
END
else
BEGIN
for (*Erg=0; *Erg<Reg8Cnt; (*Erg)++)
if (toupper(*Part)==Reg8Names[*Erg]) break;
if (*Erg<Reg8Cnt)
BEGIN
*Erg+=8; return True;
END
else return False;
END
END
static Boolean DecodePseudo(void)
BEGIN
return False;
END
static void CodeMem(Byte Entry, Byte Opcode)
BEGIN
BAsmCode[0]=Entry+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
BAsmCode[1+AdrCnt]=Opcode;
END
static void MakeCode_87C800(void)
BEGIN
int z;
Integer AdrInt,Condition;
Byte HReg,HCnt,HMode,HVal;
Boolean OK;
CodeLen=0; DontPrint=False; OpSize=(-1);
/* zu ignorierendes */
if (Memo("")) return;
/* Pseudoanweisungen */
if (DecodePseudo()) return;
if (DecodeIntelPseudo(False)) return;
/* ohne Argument */
for (z=0; z<FixedOrderCnt; z++)
if (Memo(FixedOrders[z].Name))
BEGIN
if (ArgCnt!=0) WrError(1110);
else
BEGIN
CodeLen=0;
if (Hi(FixedOrders[z].Code)!=0) BAsmCode[CodeLen++]=Hi(FixedOrders[z].Code);
BAsmCode[CodeLen++]=Lo(FixedOrders[z].Code);
END
return;
END
/* Datentransfer */
if (Memo("LD"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else if (strcasecmp(ArgStr[1],"SP")==0)
BEGIN
OpSize=1;
DecodeAdr(ArgStr[2],MModImm+MModReg16);
switch (AdrType)
BEGIN
case ModReg16:
CodeLen=2; BAsmCode[0]=0xe8+AdrMode; BAsmCode[1]=0xfa;
break;
case ModImm:
CodeLen=3; BAsmCode[0]=0xfa; memcpy(BAsmCode+1,AdrVals,AdrCnt);
break;
END
END
else if (strcasecmp(ArgStr[2],"SP")==0)
BEGIN
DecodeAdr(ArgStr[1],MModReg16);
switch (AdrType)
BEGIN
case ModReg16:
CodeLen=2; BAsmCode[0]=0xe8+AdrMode; BAsmCode[1]=0xfb;
break;
END
END
else if (strcasecmp(ArgStr[1],"RBS")==0)
BEGIN
BAsmCode[1]=EvalIntExpression(ArgStr[2],Int4,&OK);
if (OK)
BEGIN
CodeLen=2; BAsmCode[0]=0x0f;
END
END
else if (strcasecmp(ArgStr[1],"CF")==0)
BEGIN
if (NOT SplitBit(ArgStr[2],&HReg)) WrError(1510);
else
BEGIN
DecodeAdr(ArgStr[2],MModReg8+MModAbs+MModMem);
switch (AdrType)
BEGIN
case ModReg8:
if (HReg>=8) WrError(1350);
else
BEGIN
CodeLen=2; BAsmCode[0]=0xe8+AdrMode; BAsmCode[1]=0xd8+HReg;
END
break;
case ModAbs:
if (HReg>=8) WrError(1350);
else
BEGIN
CodeLen=2; BAsmCode[0]=0xd8+HReg; BAsmCode[1]=AdrVals[0];
END
break;
case ModMem:
if (HReg<8)
BEGIN
CodeLen=2+AdrCnt;
CodeMem(0xe0,0xd8+HReg);
END
else if ((AdrMode!=2) AND (AdrMode!=3)) WrError(1350);
else
BEGIN
CodeLen=2; BAsmCode[0]=0xe0+HReg; BAsmCode[1]=0x9c+AdrMode;
END
break;
END
END
END
else if (strcasecmp(ArgStr[2],"CF")==0)
BEGIN
if (NOT SplitBit(ArgStr[1],&HReg)) WrError(1510);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg8+MModAbs+MModMem);
switch (AdrType)
BEGIN
case ModReg8:
if (HReg>=8) WrError(1350);
else
BEGIN
CodeLen=2; BAsmCode[0]=0xe8+AdrMode; BAsmCode[1]=0xc8+HReg;
END
break;
case ModAbs:
case ModMem:
if (HReg<8)
BEGIN
CodeLen=2+AdrCnt; CodeMem(0xe0,0xc8+HReg);
END
else if ((AdrMode!=2) AND (AdrMode!=3)) WrError(1350);
else
BEGIN
CodeLen=2; BAsmCode[0]=0xe0+HReg; BAsmCode[1]=0x98+AdrMode;
END
break;
END
END
END
else
BEGIN
DecodeAdr(ArgStr[1],MModReg8+MModReg16+MModAbs+MModMem);
switch (AdrType)
BEGIN
case ModReg8:
HReg=AdrMode;
DecodeAdr(ArgStr[2],MModReg8+MModAbs+MModMem+MModImm);
switch (AdrType)
BEGIN
case ModReg8:
if (HReg==AccReg)
BEGIN
CodeLen=1; BAsmCode[0]=0x50+AdrMode;
END
else if (AdrMode==AccReg)
BEGIN
CodeLen=1; BAsmCode[0]=0x58+HReg;
END
else
BEGIN
CodeLen=2; BAsmCode[0]=0xe8+AdrMode; BAsmCode[1]=0x58+HReg;
END
break;
case ModAbs:
if (HReg==AccReg)
BEGIN
CodeLen=2; BAsmCode[0]=0x22; BAsmCode[1]=AdrVals[0];
END
else
BEGIN
CodeLen=3; BAsmCode[0]=0xe0; BAsmCode[1]=AdrVals[0];
BAsmCode[2]=0x58+HReg;
END
break;
case ModMem:
if ((HReg==AccReg) AND (AdrMode==3)) /* A,(HL) */
BEGIN
CodeLen=1; BAsmCode[0]=0x23;
END
else
BEGIN
CodeLen=2+AdrCnt; CodeMem(0xe0,0x58+HReg);
if ((HReg>=6) AND (AdrMode==6)) WrError(140);
END
break;
case ModImm:
CodeLen=2; BAsmCode[0]=0x30+HReg; BAsmCode[1]=AdrVals[0];
break;
END
break;
case ModReg16:
HReg=AdrMode;
DecodeAdr(ArgStr[2],MModReg16+MModAbs+MModMem+MModImm);
switch (AdrType)
BEGIN
case ModReg16:
CodeLen=2; BAsmCode[0]=0xe8+AdrMode; BAsmCode[1]=0x14+HReg;
break;
case ModAbs:
CodeLen=3; BAsmCode[0]=0xe0; BAsmCode[1]=AdrVals[0];
BAsmCode[2]=0x14+HReg;
break;
case ModMem:
if (AdrMode>5) WrError(1350); /* (-HL),(HL+) */
else
BEGIN
CodeLen=2+AdrCnt; BAsmCode[0]=0xe0+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
BAsmCode[1+AdrCnt]=0x14+HReg;
END
break;
case ModImm:
CodeLen=3; BAsmCode[0]=0x14+HReg; memcpy(BAsmCode+1,AdrVals,2);
break;
END
break;
case ModAbs:
HReg=AdrVals[0]; OpSize=0;
DecodeAdr(ArgStr[2],MModReg8+MModReg16+MModAbs+MModMem+MModImm);
switch (AdrType)
BEGIN
case ModReg8:
if (AdrMode==AccReg)
BEGIN
CodeLen=2; BAsmCode[0]=0x2a; BAsmCode[1]=HReg;
END
else
BEGIN
CodeLen=3; BAsmCode[0]=0xf0; BAsmCode[1]=HReg;
BAsmCode[2]=0x50+AdrMode;
END
break;
case ModReg16:
CodeLen=3; BAsmCode[0]=0xf0; BAsmCode[1]=HReg;
BAsmCode[2]=0x10+AdrMode;
break;
case ModAbs:
CodeLen=3; BAsmCode[0]=0x26; BAsmCode[1]=AdrVals[0];
BAsmCode[2]=HReg;
break;
case ModMem:
if (AdrMode>5) WrError(1350); /* (-HL),(HL+) */
else
BEGIN
CodeLen=3+AdrCnt; BAsmCode[0]=0xe0+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=0x26;
BAsmCode[2+AdrCnt]=HReg;
END
break;
case ModImm:
CodeLen=3; BAsmCode[0]=0x2c; BAsmCode[1]=HReg;
BAsmCode[2]=AdrVals[0];
break;
END
break;
case ModMem:
HVal=AdrVals[0]; HCnt=AdrCnt; HMode=AdrMode; OpSize=0;
DecodeAdr(ArgStr[2],MModReg8+MModReg16+MModAbs+MModMem+MModImm);
switch (AdrType)
BEGIN
case ModReg8:
if ((HMode==3) AND (AdrMode==AccReg)) /* (HL),A */
BEGIN
CodeLen=1; BAsmCode[0]=0x2b;
END
else if ((HMode==1) OR (HMode==5)) WrError(1350);
else
BEGIN
CodeLen=2+HCnt; BAsmCode[0]=0xf0+HMode;
memcpy(BAsmCode+1,&HVal,HCnt);
BAsmCode[1+HCnt]=0x50+AdrMode;
if ((HMode==6) AND (AdrMode>=6)) WrError(140);
END
break;
case ModReg16:
if ((HMode<2) OR (HMode>4)) WrError(1350); /* (HL),(DE),(HL+d) */
else
BEGIN
CodeLen=2+HCnt; BAsmCode[0]=0xf0+HMode;
memcpy(BAsmCode+1,&HVal,HCnt); BAsmCode[1+HCnt]=0x10+AdrMode;
END
break;
case ModAbs:
if (HMode!=3) WrError(1350); /* (HL) */
else
BEGIN
CodeLen=3; BAsmCode[0]=0xe0; BAsmCode[1]=AdrVals[0];
BAsmCode[2]=0x27;
END
break;
case ModMem:
if (HMode!=3) WrError(1350); /* (HL) */
else if (AdrMode>5) WrError(1350); /* (-HL),(HL+) */
else
BEGIN
CodeLen=2+AdrCnt; BAsmCode[0]=0xe0+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=0x27;
END
break;
case ModImm:
if ((HMode==1) OR (HMode==5)) WrError(1350); /* (HL+C),(PC+A) */
else if (HMode==3) /* (HL) */
BEGIN
CodeLen=2; BAsmCode[0]=0x2d; BAsmCode[1]=AdrVals[0];
END
else
BEGIN
CodeLen=3+HCnt; BAsmCode[0]=0xf0+HMode;
memcpy(BAsmCode+1,&HVal,HCnt); BAsmCode[1+HCnt]=0x2c;
BAsmCode[2+HCnt]=AdrVals[0];
END
break;
END
break;
END
END
return;
END
if (Memo("XCH"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg8+MModReg16+MModAbs+MModMem);
switch (AdrType)
BEGIN
case ModReg8:
HReg=AdrMode;
DecodeAdr(ArgStr[2],MModReg8+MModAbs+MModMem);
switch (AdrType)
BEGIN
case ModReg8:
CodeLen=2; BAsmCode[0]=0xe8+AdrMode; BAsmCode[1]=0xa8+HReg;
break;
case ModAbs:
case ModMem:
CodeLen=2+AdrCnt; CodeMem(0xe0,0xa8+HReg);
if ((HReg>=6) AND (AdrMode==6)) WrError(140);
break;
END
break;
case ModReg16:
HReg=AdrMode;
DecodeAdr(ArgStr[2],MModReg16);
if (AdrType!=ModNone)
BEGIN
CodeLen=2; BAsmCode[0]=0xe8+AdrMode; BAsmCode[1]=0x10+HReg;
END
break;
case ModAbs:
BAsmCode[1]=AdrVals[0];
DecodeAdr(ArgStr[2],MModReg8);
if (AdrType!=ModNone)
BEGIN
CodeLen=3; BAsmCode[0]=0xe0; BAsmCode[2]=0xa8+AdrMode;
END
break;
case ModMem:
BAsmCode[0]=0xe0+AdrMode; memcpy(BAsmCode+1,AdrVals,AdrCnt);
HReg=AdrCnt;
DecodeAdr(ArgStr[2],MModReg8);
if (AdrType!=ModNone)
BEGIN
CodeLen=2+HReg; BAsmCode[1+HReg]=0xa8+AdrMode;
if ((AdrMode>=6) AND ((BAsmCode[0] & 0x0f)==6)) WrError(140);
END
break;
END
END
return;
END
if (Memo("CLR"))
BEGIN
if (ArgCnt!=1) WrError(1110);
else if (strcasecmp(ArgStr[1],"CF")==0)
BEGIN
CodeLen=1; BAsmCode[0]=0x0c;
END
else if (SplitBit(ArgStr[1],&HReg))
BEGIN
DecodeAdr(ArgStr[1],MModReg8+MModAbs+MModMem);
switch (AdrType)
BEGIN
case ModReg8:
if (HReg>=8) WrError(1350);
else
BEGIN
CodeLen=2; BAsmCode[0]=0xe8+AdrMode; BAsmCode[1]=0x48+HReg;
END
break;
case ModAbs:
if (HReg>=8) WrError(1350);
else
BEGIN
CodeLen=2; BAsmCode[0]=0x48+HReg; BAsmCode[1]=AdrVals[0];
END
break;
case ModMem:
if (HReg<=8)
BEGIN
CodeLen=2+AdrCnt; CodeMem(0xe0,0x48+HReg);
END
else if ((AdrMode!=2) AND (AdrMode!=3)) WrError(1350);
else
BEGIN
CodeLen=2; BAsmCode[0]=0xe0+HReg; BAsmCode[1]=0x88+AdrMode;
END
break;
END
END
else
BEGIN
DecodeAdr(ArgStr[1],MModReg8+MModReg16+MModAbs+MModMem);
switch (AdrType)
BEGIN
case ModReg8:
CodeLen=2; BAsmCode[0]=0x30+AdrMode; BAsmCode[1]=0;
break;
case ModReg16:
CodeLen=3; BAsmCode[0]=0x14+AdrMode; BAsmCode[1]=0; BAsmCode[2]=0;
break;
case ModAbs:
CodeLen=2; BAsmCode[0]=0x2e; BAsmCode[1]=AdrVals[0];
break;
case ModMem:
if ((AdrMode==5) OR (AdrMode==1)) WrError(1350); /* (PC+A, HL+C) */
else if (AdrMode==3) /* (HL) */
BEGIN
CodeLen=1; BAsmCode[0]=0x2f;
END
else
BEGIN
CodeLen=3+AdrCnt; BAsmCode[0]=0xf0+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
BAsmCode[1+AdrCnt]=0x2c; BAsmCode[2+AdrCnt]=0;
END
break;
END
END
return;
END
if (Memo("LDW"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
AdrInt=EvalIntExpression(ArgStr[2],Int16,&OK);
if (OK)
BEGIN
DecodeAdr(ArgStr[1],MModReg16+MModAbs+MModMem);
switch (AdrType)
BEGIN
case ModReg16:
CodeLen=3; BAsmCode[0]=0x14+AdrMode;
BAsmCode[1]=AdrInt & 0xff; BAsmCode[2]=AdrInt >> 8;
break;
case ModAbs:
CodeLen=4; BAsmCode[0]=0x24; BAsmCode[1]=AdrVals[0];
BAsmCode[2]=AdrInt & 0xff; BAsmCode[3]=AdrInt >> 8;
break;
case ModMem:
if (AdrMode!=3) WrError(1350); /* (HL) */
else
BEGIN
CodeLen=3; BAsmCode[0]=0x25;
BAsmCode[1]=AdrInt & 0xff; BAsmCode[2]=AdrInt >> 8;
END
break;
END
END
END
return;
END
if ((Memo("PUSH")) OR (Memo("POP")))
BEGIN
HReg=Ord(Memo("PUSH"))+6;
if (ArgCnt!=1) WrError(1110);
else if (strcasecmp(ArgStr[1],"PSW")==0)
BEGIN
CodeLen=1; BAsmCode[0]=HReg;
END
else
BEGIN
DecodeAdr(ArgStr[1],MModReg16);
if (AdrType!=ModNone)
BEGIN
CodeLen=2; BAsmCode[0]=0xe8+AdrMode; BAsmCode[1]=HReg;
END
END
return;
END
if ((Memo("TEST")) OR (Memo("CPL")) OR (Memo("SET")))
BEGIN
if (ArgCnt!=1) WrError(1110);
else if (strcasecmp(ArgStr[1],"CF")==0)
BEGIN
if (Memo("TEST")) WrError(1350);
else
BEGIN
CodeLen=1; BAsmCode[0]=0x0d+Ord(Memo("CPL"));
END
END
else if (NOT SplitBit(ArgStr[1],&HReg)) WrError(1510);
else
BEGIN
if (Memo("TEST")) HVal=0xd8;
else if (Memo("SET")) HVal=0x40;
else HVal=0xc0;
DecodeAdr(ArgStr[1],MModReg8+MModAbs+MModMem);
switch (AdrType)
BEGIN
case ModReg8:
if (HReg>=8) WrError(1350);
else
BEGIN
CodeLen=2; BAsmCode[0]=0xe8+AdrMode; BAsmCode[1]=HVal+HReg;
END
break;
case ModAbs:
if (HReg>=8) WrError(1350);
else if (Memo("CPL"))
BEGIN
CodeLen=3; CodeMem(0xe0,HVal+HReg);
END
else
BEGIN
CodeLen=2; BAsmCode[0]=HVal+HReg; BAsmCode[1]=AdrVals[0];
END
break;
case ModMem:
if (HReg<8)
BEGIN
CodeLen=2+AdrCnt; CodeMem(0xe0,HVal+HReg);
END
else if ((AdrMode!=2) AND (AdrMode!=3)) WrError(1350);
else
BEGIN
CodeLen=2; BAsmCode[0]=0xe0+HReg;
BAsmCode[1]=((HVal & 0x18) >> 1)+((HVal & 0x80) >> 3)+0x80+AdrMode;
END
break;
END
END
return;
END
/* Arithmetik */
for (z=0; z<RegOrderCnt; z++)
if (Memo(RegOrders[z].Name))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg8);
if (AdrType!=ModNone)
if (AdrMode==AccReg)
BEGIN
CodeLen=1; BAsmCode[0]=RegOrders[z].Code;
END
else
BEGIN
CodeLen=2; BAsmCode[0]=0xe8+AdrMode; BAsmCode[1]=RegOrders[z].Code;
END
END
return;
END
for (z=0; z<ALUOrderCnt; z++)
if (Memo(ALUOrders[z]))
BEGIN
if (ArgCnt!=2) WrError(1110);
else if (strcasecmp(ArgStr[1],"CF")==0)
BEGIN
if (NOT Memo("XOR")) WrError(1350);
else if (NOT SplitBit(ArgStr[2],&HReg)) WrError(1510);
else if (HReg>=8) WrError(1350);
else
BEGIN
DecodeAdr(ArgStr[2],MModReg8+MModAbs+MModMem);
switch (AdrType)
BEGIN
case ModReg8:
CodeLen=2; BAsmCode[0]=0xe8+AdrMode; BAsmCode[1]=0xd0+HReg;
break;
case ModAbs:
case ModMem:
CodeLen=2+AdrCnt; CodeMem(0xe0,0xd0+HReg);
break;
END
END
END
else
BEGIN
DecodeAdr(ArgStr[1],MModReg8+MModReg16+MModMem+MModAbs);
switch (AdrType)
BEGIN
case ModReg8:
HReg=AdrMode;
DecodeAdr(ArgStr[2],MModReg8+MModMem+MModAbs+MModImm);
switch (AdrType)
BEGIN
case ModReg8:
if (HReg==AccReg)
BEGIN
CodeLen=2;
BAsmCode[0]=0xe8+AdrMode; BAsmCode[1]=0x60+z;
END
else if (AdrMode==AccReg)
BEGIN
CodeLen=2;
BAsmCode[0]=0xe8+HReg; BAsmCode[1]=0x68+z;
END
else WrError(1350);
break;
case ModMem:
if (HReg!=AccReg) WrError(1350);
else
BEGIN
CodeLen=2+AdrCnt; BAsmCode[0]=0xe0+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
BAsmCode[1+AdrCnt]=0x78+z;
END
break;
case ModAbs:
if (HReg!=AccReg) WrError(1350);
else
BEGIN
CodeLen=2; BAsmCode[0]=0x78+z; BAsmCode[1]=AdrVals[0];
END
break;
case ModImm:
if (HReg==AccReg)
BEGIN
CodeLen=2; BAsmCode[0]=0x70+z; BAsmCode[1]=AdrVals[0];
END
else
BEGIN
CodeLen=3; BAsmCode[0]=0xe8+HReg;
BAsmCode[1]=0x70+z; BAsmCode[2]=AdrVals[0];
END
break;
END
break;
case ModReg16:
HReg=AdrMode; DecodeAdr(ArgStr[2],MModImm+MModReg16);
switch (AdrType)
BEGIN
case ModImm:
CodeLen=4; BAsmCode[0]=0xe8+HReg; BAsmCode[1]=0x38+z;
memcpy(BAsmCode+2,AdrVals,AdrCnt);
break;
case ModReg16:
if (HReg!=WAReg) WrError(1350);
else
BEGIN
CodeLen=2; BAsmCode[0]=0xe8+AdrMode; BAsmCode[1]=0x30+z;
END
break;
END
break;
case ModAbs:
if (strcasecmp(ArgStr[2],"(HL)")==0)
BEGIN
CodeLen=3; BAsmCode[0]=0xe0;
BAsmCode[1]=AdrVals[0]; BAsmCode[2]=0x60+z;
END
else
BEGIN
BAsmCode[3]=EvalIntExpression(ArgStr[2],Int8,&OK);
if (OK)
BEGIN
CodeLen=4; BAsmCode[0]=0xe0;
BAsmCode[1]=AdrVals[0]; BAsmCode[2]=0x70+z;
END
END
break;
case ModMem:
if (strcasecmp(ArgStr[2],"(HL)")==0)
BEGIN
CodeLen=2+AdrCnt; BAsmCode[0]=0xe0+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=0x60+z;
END
else
BEGIN
BAsmCode[2+AdrCnt]=EvalIntExpression(ArgStr[2],Int8,&OK);
if (OK)
BEGIN
CodeLen=3+AdrCnt; BAsmCode[0]=0xe0+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=0x70+z;
END
END
break;
END
END
return;
END
if (Memo("MCMP"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
HReg=EvalIntExpression(ArgStr[2],Int8,&OK);
if (OK)
BEGIN
DecodeAdr(ArgStr[1],MModMem+MModAbs);
if (AdrType!=ModNone)
BEGIN
CodeLen=3+AdrCnt; CodeMem(0xe0,0x2f); BAsmCode[2+AdrCnt]=HReg;
END
END
END
return;
END
if ((Memo("DEC")) OR (Memo("INC")))
BEGIN
HReg=Ord(Memo("DEC")) << 3;
if (ArgCnt!=1) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg8+MModReg16+MModAbs+MModMem);
switch (AdrType)
BEGIN
case ModReg8:
CodeLen=1; BAsmCode[0]=0x60+HReg+AdrMode;
break;
case ModReg16:
CodeLen=1; BAsmCode[0]=0x10+HReg+AdrMode;
break;
case ModAbs:
CodeLen=2; BAsmCode[0]=0x20+HReg; BAsmCode[1]=AdrVals[0];
break;
case ModMem:
if (AdrMode==3) /* (HL) */
BEGIN
CodeLen=1; BAsmCode[0]=0x21+HReg;
END
else
BEGIN
CodeLen=2+AdrCnt; BAsmCode[0]=0xe0+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=0x20+HReg;
END
break;
END
END
return;
END
if (Memo("MUL"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg8);
if (AdrType==ModReg8)
BEGIN
HReg=AdrMode;
DecodeAdr(ArgStr[2],MModReg8);
if (AdrType==ModReg8)
if ((HReg ^ AdrMode)!=1) WrError(1760);
else
BEGIN
HReg=HReg >> 1;
if (HReg==0)
BEGIN
CodeLen=1; BAsmCode[0]=0x02;
END
else
BEGIN
CodeLen=2; BAsmCode[0]=0xe8+HReg; BAsmCode[1]=0x02;
END
END
END
END
return;
END
if (Memo("DIV"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg16);
if (AdrType==ModReg16)
BEGIN
HReg=AdrMode;
DecodeAdr(ArgStr[2],MModReg8);
if (AdrType==ModReg8)
if (AdrMode!=2) WrError(1350); /* C */
else if (HReg==0)
BEGIN
CodeLen=1; BAsmCode[0]=0x03;
END
else
BEGIN
CodeLen=2; BAsmCode[0]=0xe8+HReg; BAsmCode[1]=0x03;
if (HReg==1) WrError(140);
END
END
END
return;
END
if ((Memo("ROLD")) OR (Memo("RORD")))
BEGIN
if (ArgCnt!=2) WrError(1110);
else if (strcasecmp(ArgStr[1],"A")!=0) WrError(1350);
else
BEGIN
HReg=Ord(Memo("RORD"))+8;
DecodeAdr(ArgStr[2],MModAbs+MModMem);
if (AdrType!=ModNone)
BEGIN
CodeLen=2+AdrCnt; CodeMem(0xe0,HReg);
if (AdrMode==1) WrError(140);
END
END
return;
END
/* Spruenge */
if (Memo("JRS"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
NLS_UpString(ArgStr[1]);
for (Condition=ConditionCnt-2; Condition<ConditionCnt; Condition++)
if (strcmp(ArgStr[1],Conditions[Condition].Name)==0) break;
if (Condition>=ConditionCnt) WrXError(1360,ArgStr[1]);
else
BEGIN
AdrInt=EvalIntExpression(ArgStr[2],Int16,&OK)-(EProgCounter()+2);
if (OK)
if (((AdrInt<-16) OR (AdrInt>15)) AND (NOT SymbolQuestionable)) WrError(1370);
else
BEGIN
CodeLen=1;
BAsmCode[0]=((Conditions[Condition].Code-2) << 5)+(AdrInt & 0x1f);
END
END
END
return;
END
if (Memo("JR"))
BEGIN
if ((ArgCnt!=2) AND (ArgCnt!=1)) WrError(1110);
else
BEGIN
if (ArgCnt==1) Condition=(-1);
else
BEGIN
NLS_UpString(ArgStr[1]);
for (Condition=0; Condition<ConditionCnt; Condition++)
if (strcmp(ArgStr[1],Conditions[Condition].Name)==0) break;
END
if (Condition>=ConditionCnt) WrXError(1360,ArgStr[1]);
else
BEGIN
AdrInt=EvalIntExpression(ArgStr[2],Int16,&OK)-(EProgCounter()+2);
if (OK)
if (((AdrInt<-128) OR (AdrInt>127)) AND (NOT SymbolQuestionable)) WrError(1370);
else
BEGIN
CodeLen=2;
if (Condition==-1) BAsmCode[0]=0xfb;
else BAsmCode[0]=0xd0+Conditions[Condition].Code;
BAsmCode[1]=AdrInt & 0xff;
END
END
END
return;
END
if ((Memo("JP")) OR (Memo("CALL")))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
OpSize=1; HReg=0xfc+2*Ord(Memo("JP"));
DecodeAdr(ArgStr[1],MModReg16+MModAbs+MModMem+MModImm);
switch (AdrType)
BEGIN
case ModReg16:
CodeLen=2; BAsmCode[0]=0xe8+AdrMode; BAsmCode[1]=HReg;
break;
case ModAbs:
CodeLen=3; BAsmCode[0]=0xe0; BAsmCode[1]=AdrVals[0];
BAsmCode[2]=HReg;
break;
case ModMem:
if (AdrMode>5) WrError(1350);
else
BEGIN
CodeLen=2+AdrCnt; BAsmCode[0]=0xe0+AdrMode;
memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=HReg;
END
break;
case ModImm:
if ((AdrVals[1]==0xff) AND (Memo("CALL")))
BEGIN
CodeLen=2; BAsmCode[0]=0xfd; BAsmCode[1]=AdrVals[0];
END
else
BEGIN
CodeLen=3; BAsmCode[0]=HReg; memcpy(BAsmCode+1,AdrVals,AdrCnt);
END
break;
END
END
return;
END
if (Memo("CALLV"))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
HVal=EvalIntExpression(ArgStr[1],Int4,&OK);
if (OK)
BEGIN
CodeLen=1; BAsmCode[0]=0xc0+(HVal & 15);
END
END
return;
END
if (Memo("CALLP"))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
AdrInt=EvalIntExpression(ArgStr[1],Int16,&OK);
if (OK)
if ((Hi(AdrInt)!=0xff) AND (Hi(AdrInt)!=0)) WrError(1320);
else
BEGIN
CodeLen=2; BAsmCode[0]=0xfd; BAsmCode[1]=Lo(AdrInt);
END
END
return;
END
WrXError(1200,OpPart);
END
static Boolean IsDef_87C800(void)
BEGIN
return False;
END
static void SwitchFrom_87C800(void)
BEGIN
DeinitFields();
END
static void SwitchTo_87C800(void)
BEGIN
TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=True;
PCSymbol="$"; HeaderID=0x54; NOPCode=0x00;
DivideChars=","; HasAttrs=False;
ValidSegs=1<<SegCode;
Grans[SegCode]=1; ListGrans[SegCode]=1; SegInits[SegCode]=0;
SegLimits[SegCode] = 0xffff;
MakeCode=MakeCode_87C800; IsDef=IsDef_87C800;
SwitchFrom=SwitchFrom_87C800; InitFields();
END
void code87c800_init(void)
BEGIN
CPU87C00=AddCPU("87C00",SwitchTo_87C800);
CPU87C20=AddCPU("87C20",SwitchTo_87C800);
CPU87C40=AddCPU("87C40",SwitchTo_87C800);
CPU87C70=AddCPU("87C70",SwitchTo_87C800);
END