aboutsummaryrefslogtreecommitdiffstats
path: root/code87c800.c
diff options
context:
space:
mode:
Diffstat (limited to 'code87c800.c')
-rw-r--r--code87c800.c1316
1 files changed, 1316 insertions, 0 deletions
diff --git a/code87c800.c b/code87c800.c
new file mode 100644
index 0000000..8cbfa33
--- /dev/null
+++ b/code87c800.c
@@ -0,0 +1,1316 @@
+/* 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