aboutsummaryrefslogtreecommitdiffstats
path: root/code78k0.c
diff options
context:
space:
mode:
Diffstat (limited to 'code78k0.c')
-rw-r--r--code78k0.c1228
1 files changed, 1228 insertions, 0 deletions
diff --git a/code78k0.c b/code78k0.c
new file mode 100644
index 0000000..3a03e94
--- /dev/null
+++ b/code78k0.c
@@ -0,0 +1,1228 @@
+/* code78k0.c */
+/*****************************************************************************/
+/* AS-Portierung */
+/* */
+/* Codegenerator 78K0-Familie */
+/* */
+/* Historie: 1.12.1996 Grundsteinlegung */
+/* 3. 1.1999 ChkPC-Anpassung */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+#include <string.h>
+#include <ctype.h>
+
+#include "bpemu.h"
+#include "strutil.h"
+#include "asmdef.h"
+#include "asmsub.h"
+#include "asmpars.h"
+#include "codepseudo.h"
+#include "codevars.h"
+
+
+#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 ModShort 3
+#define MModShort (1 << ModShort)
+#define ModSFR 4
+#define MModSFR (1 << ModSFR)
+#define ModAbs 5
+#define MModAbs (1 << ModAbs)
+#define ModIReg 6
+#define MModIReg (1 << ModIReg)
+#define ModIndex 7
+#define MModIndex (1 << ModIndex)
+#define ModDisp 8
+#define MModDisp (1 << ModDisp)
+
+#define AccReg 1
+#define AccReg16 0
+
+#define FixedOrderCount 11
+#define AriOrderCount 8
+#define Ari16OrderCount 3
+#define ShiftOrderCount 4
+#define Bit2OrderCount 3
+#define RelOrderCount 4
+#define BRelOrderCount 3
+
+typedef struct
+ {
+ char *Name;
+ Word Code;
+ } FixedOrder;
+
+static FixedOrder *FixedOrders;
+static char **AriOrders;
+static char **Ari16Orders;
+static char **ShiftOrders;
+static char **Bit2Orders;
+static char **RelOrders;
+static char **BRelOrders;
+
+static Byte OpSize,AdrPart;
+static Byte AdrVals[2];
+static ShortInt AdrMode;
+
+static CPUVar CPU78070;
+
+
+/*-------------------------------------------------------------------------*/
+/* dynamische Codetabellenverwaltung */
+
+ static void AddFixed(char *NewName, Word NewCode)
+BEGIN
+ if (InstrZ>=FixedOrderCount) exit(255);
+ FixedOrders[InstrZ].Name=NewName;
+ FixedOrders[InstrZ++].Code=NewCode;
+END
+
+ static void AddAri(char *NewName)
+BEGIN
+ if (InstrZ>=AriOrderCount) exit(255);
+ AriOrders[InstrZ++]=NewName;
+END
+
+ static void AddAri16(char *NewName)
+BEGIN
+ if (InstrZ>=Ari16OrderCount) exit(255);
+ Ari16Orders[InstrZ++]=NewName;
+END
+
+ static void AddShift(char *NewName)
+BEGIN
+ if (InstrZ>=ShiftOrderCount) exit(255);
+ ShiftOrders[InstrZ++]=NewName;
+END
+
+ static void AddBit2(char *NewName)
+BEGIN
+ if (InstrZ>=Bit2OrderCount) exit(255);
+ Bit2Orders[InstrZ++]=NewName;
+END
+
+ static void AddRel(char *NewName)
+BEGIN
+ if (InstrZ>=RelOrderCount) exit(255);
+ RelOrders[InstrZ++]=NewName;
+END
+
+ static void AddBRel(char *NewName)
+BEGIN
+ if (InstrZ>=BRelOrderCount) exit(255);
+ BRelOrders[InstrZ++]=NewName;
+END
+
+ static void InitFields(void)
+BEGIN
+ FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCount); InstrZ=0;
+ AddFixed("BRK" ,0x00bf);
+ AddFixed("RET" ,0x00af);
+ AddFixed("RETB" ,0x009f);
+ AddFixed("RETI" ,0x008f);
+ AddFixed("HALT" ,0x7110);
+ AddFixed("STOP" ,0x7100);
+ AddFixed("NOP" ,0x0000);
+ AddFixed("EI" ,0x7a1e);
+ AddFixed("DI" ,0x7b1e);
+ AddFixed("ADJBA",0x6180);
+ AddFixed("ADJBS",0x6190);
+
+ AriOrders=(char **) malloc(sizeof(char *)*AriOrderCount); InstrZ=0;
+ AddAri("ADD" ); AddAri("SUB" ); AddAri("ADDC"); AddAri("SUBC");
+ AddAri("CMP" ); AddAri("AND" ); AddAri("OR" ); AddAri("XOR" );
+
+ Ari16Orders=(char **) malloc(sizeof(char *)*Ari16OrderCount); InstrZ=0;
+ AddAri16("ADDW"); AddAri16("SUBW"); AddAri16("CMPW");
+
+ ShiftOrders=(char **) malloc(sizeof(char *)*ShiftOrderCount); InstrZ=0;
+ AddShift("ROR"); AddShift("RORC"); AddShift("ROL"); AddShift("ROLC");
+
+ Bit2Orders=(char **) malloc(sizeof(char *)*Bit2OrderCount); InstrZ=0;
+ AddBit2("AND1"); AddBit2("OR1"); AddBit2("XOR1");
+
+ RelOrders=(char **) malloc(sizeof(char *)*RelOrderCount); InstrZ=0;
+ AddRel("BC"); AddRel("BNC"); AddRel("BZ"); AddRel("BNZ");
+
+ BRelOrders=(char **) malloc(sizeof(char *)*BRelOrderCount); InstrZ=0;
+ AddBRel("BTCLR"); AddBRel("BT"); AddBRel("BF");
+END
+
+ static void DeinitFields(void)
+BEGIN
+ free(FixedOrders);
+ free(AriOrders);
+ free(Ari16Orders);
+ free(ShiftOrders);
+ free(Bit2Orders);
+ free(RelOrders);
+ free(BRelOrders);
+END
+
+/*-------------------------------------------------------------------------*/
+/* Adressausdruck parsen */
+
+ static void ChkAdr(Word Mask)
+BEGIN
+ if ((AdrMode!=ModNone) AND ((Mask & (1 << AdrMode))==0))
+ BEGIN
+ WrError(1350);
+ AdrMode=ModNone; AdrCnt=0;
+ END
+END
+
+ static void DecodeAdr(char *Asc, Word Mask)
+BEGIN
+ static char *RegNames[8]={"X","A","C","B","E","D","L","H"};
+
+ Word AdrWord;
+ int z;
+ Boolean OK,LongFlag;
+
+ AdrMode=ModNone; AdrCnt=0;
+
+ /* Register */
+
+ for (z=0; z<8; z++)
+ if (strcasecmp(Asc,RegNames[z])==0)
+ BEGIN
+ AdrMode=ModReg8; AdrPart=z; ChkAdr(Mask); return;
+ END
+
+ if (toupper(*Asc)=='R')
+ if ((strlen(Asc)==2) AND (Asc[1]>='0') AND (Asc[1]<='7'))
+ BEGIN
+ AdrMode=ModReg8; AdrPart=Asc[1]-'0'; ChkAdr(Mask); return;
+ END
+ else if ((strlen(Asc)==3) AND (toupper(Asc[1])=='P') AND (Asc[2]>='0') AND (Asc[2]<='3'))
+ BEGIN
+ AdrMode=ModReg16; AdrPart=Asc[2]-'0'; ChkAdr(Mask); return;
+ END
+
+ if (strlen(Asc)==2)
+ for (z=0; z<4; z++)
+ if ((toupper(*Asc)==*RegNames[(z<<1)+1]) AND (toupper(Asc[1])==*RegNames[z<<1]))
+ BEGIN
+ AdrMode=ModReg16; AdrPart=z; ChkAdr(Mask); return;
+ END
+
+ /* immediate */
+
+ if (*Asc=='#')
+ BEGIN
+ switch (OpSize)
+ BEGIN
+ case 0:
+ AdrVals[0]=EvalIntExpression(Asc+1,Int8,&OK);
+ break;
+ case 1:
+ AdrWord=EvalIntExpression(Asc+1,Int16,&OK);
+ if (OK)
+ BEGIN
+ AdrVals[0]=Lo(AdrWord); AdrVals[1]=Hi(AdrWord);
+ END
+ break;
+ END
+ if (OK)
+ BEGIN
+ AdrMode=ModImm; AdrCnt=OpSize+1;
+ END
+ ChkAdr(Mask); return;
+ END
+
+ /* indirekt */
+
+ if ((*Asc=='[') AND (Asc[strlen(Asc)-1]==']'))
+ BEGIN
+ strcpy(Asc,Asc+1); Asc[strlen(Asc)-1]='\0';
+
+ if ((strcasecmp(Asc,"DE")==0) OR (strcasecmp(Asc,"RP2")==0))
+ BEGIN
+ AdrMode=ModIReg; AdrPart=0;
+ END
+ else if ((strncasecmp(Asc,"HL",2)!=0) AND (strncasecmp(Asc,"RP3",3)!=0)) WrXError(1445,Asc);
+ else
+ BEGIN
+ strcpy(Asc,Asc+2); if (*Asc=='3') strcpy(Asc,Asc+1);
+ if ((strcasecmp(Asc,"+B")==0) OR (strcasecmp(Asc,"+R3")==0))
+ BEGIN
+ AdrMode=ModIndex; AdrPart=1;
+ END
+ else if ((strcasecmp(Asc,"+C")==0) OR (strcasecmp(Asc,"+R2")==0))
+ BEGIN
+ AdrMode=ModIndex; AdrPart=0;
+ END
+ else
+ BEGIN
+ AdrVals[0]=EvalIntExpression(Asc,UInt8,&OK);
+ if (OK)
+ if (AdrVals[0]==0)
+ BEGIN
+ AdrMode=ModIReg; AdrPart=1;
+ END
+ else
+ BEGIN
+ AdrMode=ModDisp; AdrCnt=1;
+ END;
+ END
+ END
+
+ ChkAdr(Mask); return;
+ END
+
+ /* erzwungen lang ? */
+
+ if (*Asc=='!')
+ BEGIN
+ LongFlag=True; strcpy(Asc,Asc+1);
+ END
+ else LongFlag=False;
+
+ /* -->absolut */
+
+ FirstPassUnknown=True;
+ AdrWord=EvalIntExpression(Asc,UInt16,&OK);
+ if (FirstPassUnknown)
+ BEGIN
+ AdrWord&=0xffffe;
+ if ((Mask & MModAbs)==0)
+ AdrWord=(AdrWord | 0xff00) & 0xff1f;
+ END
+ if (OK)
+ if ((NOT LongFlag) AND ((Mask & MModShort)!=0) AND (AdrWord>=0xfe20) AND (AdrWord<=0xff1f))
+ BEGIN
+ AdrMode=ModShort; AdrCnt=1; AdrVals[0]=Lo(AdrWord);
+ END
+ else if ((NOT LongFlag) AND ((Mask & MModSFR)!=0) AND (((AdrWord>=0xff00) AND (AdrWord<=0xffcf)) OR (AdrWord>=0xffe0)))
+ BEGIN
+ AdrMode=ModSFR; AdrCnt=1; AdrVals[0]=Lo(AdrWord);
+ END
+ else
+ BEGIN
+ AdrMode=ModAbs; AdrCnt=2; AdrVals[0]=Lo(AdrWord); AdrVals[1]=Hi(AdrWord);
+ END
+
+ ChkAdr(Mask);
+END
+
+ static void ChkEven(void)
+BEGIN
+ if ((AdrMode==ModAbs) OR (AdrMode==ModShort) OR (AdrMode==ModSFR))
+ if ((AdrVals[0]&1)==1) WrError(180);
+END
+
+ static Boolean DecodeBitAdr(char *Asc, Byte *Erg)
+BEGIN
+ char *p;
+ Boolean OK;
+
+ p=RQuotPos(Asc,'.');
+ if (p==Nil)
+ BEGIN
+ WrError(1510); return False;
+ END
+
+ *p='\0';
+ *Erg=EvalIntExpression(p+1,UInt3,&OK) << 4;
+ if (NOT OK) return False;
+
+ DecodeAdr(Asc,MModShort+MModSFR+MModIReg+MModReg8);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if (AdrPart!=AccReg)
+ BEGIN
+ WrError(1350); return False;
+ END
+ else
+ BEGIN
+ *Erg+=0x88; return True;
+ END
+ case ModShort:
+ return True;
+ case ModSFR:
+ *Erg+=0x08; return True;
+ case ModIReg:
+ if (AdrPart==0)
+ BEGIN
+ WrError(1350); return False;
+ END
+ else
+ BEGIN
+ *Erg+=0x80; return True;
+ END
+ default:
+ return False;
+ END
+END
+
+/*-------------------------------------------------------------------------*/
+
+ static Boolean DecodePseudo(void)
+BEGIN
+ return False;
+END
+
+ static void MakeCode_78K0(void)
+BEGIN
+ int z;
+ Byte HReg;
+ Word AdrWord;
+ Integer AdrInt;
+ Boolean OK;
+
+ CodeLen=0; DontPrint=False; OpSize=0;
+
+ /* zu ignorierendes */
+
+ if (Memo("")) return;
+
+ /* Pseudoanweisungen */
+
+ if (DecodePseudo()) return;
+
+ if (DecodeIntelPseudo(False)) return;
+
+ /* ohne Argument */
+
+ for (z=0; z<FixedOrderCount; z++)
+ if (Memo(FixedOrders[z].Name))
+ BEGIN
+ if (ArgCnt!=0) WrError(1110);
+ else if (Hi(FixedOrders[z].Code)==0) CodeLen=1;
+ else
+ BEGIN
+ BAsmCode[0]=Hi(FixedOrders[z].Code); CodeLen=2;
+ END
+ BAsmCode[CodeLen-1]=Lo(FixedOrders[z].Code);
+ return;
+ END
+
+ /* Datentransfer */
+
+ if (Memo("MOV"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg8+MModShort+MModSFR+MModAbs+MModIReg+MModIndex+MModDisp);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ HReg=AdrPart;
+ DecodeAdr(ArgStr[2],MModImm+MModReg8+((HReg==AccReg)?MModShort+MModSFR+MModAbs+MModIReg+MModIndex+MModDisp:0));
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if ((HReg==AccReg)==(AdrPart==AccReg)) WrError(1350);
+ else if (HReg==AccReg)
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0x60+AdrPart;
+ END
+ else
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0x70+HReg;
+ END
+ break;
+ case ModImm:
+ CodeLen=2; BAsmCode[0]=0xa0+HReg; BAsmCode[1]=AdrVals[0];
+ break;
+ case ModShort:
+ CodeLen=2; BAsmCode[0]=0xf0; BAsmCode[1]=AdrVals[0];
+ break;
+ case ModSFR:
+ CodeLen=2; BAsmCode[0]=0xf4; BAsmCode[1]=AdrVals[0];
+ break;
+ case ModAbs:
+ CodeLen=3; BAsmCode[0]=0xfe; memcpy(BAsmCode+1,AdrVals,AdrCnt);
+ break;
+ case ModIReg:
+ CodeLen=1; BAsmCode[0]=0x85+(AdrPart << 1);
+ break;
+ case ModIndex:
+ CodeLen=1; BAsmCode[0]=0xaa+AdrPart;
+ break;
+ case ModDisp:
+ CodeLen=2; BAsmCode[0]=0xae; BAsmCode[1]=AdrVals[0];
+ break;
+ END
+ break;
+ case ModShort:
+ BAsmCode[1]=AdrVals[0];
+ DecodeAdr(ArgStr[2],MModReg8+MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if (AdrPart!=AccReg) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0xf2; CodeLen=2;
+ END
+ break;
+ case ModImm:
+ BAsmCode[0]=0x11; BAsmCode[2]=AdrVals[0]; CodeLen=3;
+ break;
+ END
+ break;
+ case ModSFR:
+ BAsmCode[1]=AdrVals[0];
+ DecodeAdr(ArgStr[2],MModReg8+MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if (AdrPart!=AccReg) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0xf6; CodeLen=2;
+ END
+ break;
+ case ModImm:
+ BAsmCode[0]=0x13; BAsmCode[2]=AdrVals[0]; CodeLen=3;
+ break;
+ END
+ break;
+ case ModAbs:
+ memcpy(BAsmCode+1,AdrVals,2);
+ DecodeAdr(ArgStr[2],MModReg8);
+ if (AdrMode==ModReg8)
+ if (AdrPart!=AccReg) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0x9e; CodeLen=3;
+ END
+ break;
+ case ModIReg:
+ HReg=AdrPart;
+ DecodeAdr(ArgStr[2],MModReg8);
+ if (AdrMode==ModReg8)
+ if (AdrPart!=AccReg) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0x95+(AdrPart << 1); CodeLen=1;
+ END
+ break;
+ case ModIndex:
+ HReg=AdrPart;
+ DecodeAdr(ArgStr[2],MModReg8);
+ if (AdrMode==ModReg8)
+ if (AdrPart!=AccReg) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0xba+HReg; CodeLen=1;
+ END
+ break;
+ case ModDisp:
+ BAsmCode[1]=AdrVals[0];
+ DecodeAdr(ArgStr[2],MModReg8);
+ if (AdrMode==ModReg8)
+ if (AdrPart!=AccReg) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0xbe; CodeLen=2;
+ END
+ break;
+ END
+ END
+ return;
+ END
+
+ if (Memo("XCH"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ if ((strcasecmp(ArgStr[2],"A")==0) OR (strcasecmp(ArgStr[2],"RP1")==0))
+ BEGIN
+ strcpy(ArgStr[3],ArgStr[1]); strcpy(ArgStr[1],ArgStr[2]); strcpy(ArgStr[2],ArgStr[3]);
+ END
+ DecodeAdr(ArgStr[1],MModReg8);
+ if (AdrMode!=ModNone)
+ if (AdrPart!=AccReg) WrError(1350);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[2],MModReg8+MModShort+MModSFR+MModAbs+MModIReg+MModIndex+MModDisp);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if (AdrPart==AccReg) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0x30+AdrPart; CodeLen=1;
+ END
+ break;
+ case ModShort:
+ BAsmCode[0]=0x83; BAsmCode[1]=AdrVals[0]; CodeLen=2;
+ break;
+ case ModSFR:
+ BAsmCode[0]=0x93; BAsmCode[1]=AdrVals[0]; CodeLen=2;
+ break;
+ case ModAbs:
+ BAsmCode[0]=0xce; memcpy(BAsmCode+1,AdrVals,AdrCnt); CodeLen=3;
+ break;
+ case ModIReg:
+ BAsmCode[0]=0x05+(AdrPart << 1); CodeLen=1;
+ break;
+ case ModIndex:
+ BAsmCode[0]=0x31; BAsmCode[1]=0x8a+AdrPart; CodeLen=2;
+ break;
+ case ModDisp:
+ BAsmCode[0]=0xde; BAsmCode[1]=AdrVals[0]; CodeLen=2;
+ break;
+ END
+ END
+ END
+ return;
+ END
+
+ if (Memo("MOVW"))
+ BEGIN
+ OpSize=1;
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg16+MModShort+MModSFR+MModAbs);
+ switch (AdrMode)
+ BEGIN
+ case ModReg16:
+ HReg=AdrPart;
+ DecodeAdr(ArgStr[2],MModReg16+MModImm+((HReg==AccReg16)?MModShort+MModSFR+MModAbs:0));
+ switch (AdrMode)
+ BEGIN
+ case ModReg16:
+ if ((HReg==AccReg16)==(AdrPart==AccReg16)) WrError(1350);
+ else if (HReg==AccReg16)
+ BEGIN
+ BAsmCode[0]=0xc0+(AdrPart << 1); CodeLen=1;
+ END
+ else
+ BEGIN
+ BAsmCode[0]=0xd0+(HReg << 1); CodeLen=1;
+ END
+ break;
+ case ModImm:
+ BAsmCode[0]=0x10+(HReg << 1); memcpy(BAsmCode+1,AdrVals,2);
+ CodeLen=3;
+ break;
+ case ModShort:
+ BAsmCode[0]=0x89; BAsmCode[1]=AdrVals[0]; CodeLen=2;
+ ChkEven();
+ break;
+ case ModSFR:
+ BAsmCode[0]=0xa9; BAsmCode[1]=AdrVals[0]; CodeLen=2;
+ ChkEven();
+ break;
+ case ModAbs:
+ BAsmCode[0]=0x02; memcpy(BAsmCode+1,AdrVals,2); CodeLen=3;
+ ChkEven();
+ break;
+ END
+ break;
+ case ModShort:
+ ChkEven();
+ BAsmCode[1]=AdrVals[0];
+ DecodeAdr(ArgStr[2],MModReg16+MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModReg16:
+ if (AdrPart!=AccReg16) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0x99; CodeLen=2;
+ END
+ break;
+ case ModImm:
+ BAsmCode[0]=0xee; memcpy(BAsmCode+2,AdrVals,2); CodeLen=4;
+ break;
+ END
+ break;
+ case ModSFR:
+ ChkEven();
+ BAsmCode[1]=AdrVals[0];
+ DecodeAdr(ArgStr[2],MModReg16+MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModReg16:
+ if (AdrPart!=AccReg16) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0xb9; CodeLen=2;
+ END
+ break;
+ case ModImm:
+ BAsmCode[0]=0xfe; memcpy(BAsmCode+2,AdrVals,2); CodeLen=4;
+ break;
+ END
+ break;
+ case ModAbs:
+ ChkEven();
+ memcpy(BAsmCode+1,AdrVals,AdrCnt);
+ DecodeAdr(ArgStr[2],MModReg16);
+ if (AdrMode==ModReg16)
+ if (AdrPart!=AccReg16) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0x03; CodeLen=3;
+ END
+ break;
+ END
+ END
+ return;
+ END
+
+ if (Memo("XCHW"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg16);
+ if (AdrMode==ModReg16)
+ BEGIN
+ HReg=AdrPart;
+ DecodeAdr(ArgStr[2],MModReg16);
+ if (AdrMode==ModReg16)
+ if ((HReg==AccReg16)==(AdrPart==AccReg16)) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=(HReg==AccReg16) ? 0xe0+(AdrPart << 1) : 0xe0+(HReg << 1);
+ CodeLen=1;
+ END
+ END
+ END
+ return;
+ END
+
+ if ((Memo("PUSH")) OR (Memo("POP")))
+ BEGIN
+ z=Ord(Memo("POP"));
+ if (ArgCnt!=1) WrError(1110);
+ else if (strcasecmp(ArgStr[1],"PSW")==0)
+ BEGIN
+ BAsmCode[0]=0x22+z; CodeLen=1;
+ END
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg16);
+ if (AdrMode==ModReg16)
+ BEGIN
+ BAsmCode[0]=0xb1-z+(AdrPart << 1); CodeLen=1;
+ END
+ END
+ return;
+ END
+
+ /* Arithmetik */
+
+ for (z=0; z<AriOrderCount; z++)
+ if (Memo(AriOrders[z]))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg8+MModShort);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ HReg=AdrPart;
+ DecodeAdr(ArgStr[2],MModReg8+((HReg==AccReg)?(MModImm+MModShort+MModAbs+MModIReg+MModIndex+MModDisp):0));
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if (AdrPart==AccReg)
+ BEGIN
+ BAsmCode[0]=0x61; BAsmCode[1]=(z << 4)+HReg; CodeLen=2;
+ END
+ else if (HReg==AccReg)
+ BEGIN
+ BAsmCode[0]=0x61; BAsmCode[1]=0x08+(z << 4)+AdrPart; CodeLen=2;
+ END
+ else WrError(1350);
+ break;
+ case ModImm:
+ BAsmCode[0]=(z << 4)+0x0d; BAsmCode[1]=AdrVals[0]; CodeLen=2;
+ break;
+ case ModShort:
+ BAsmCode[0]=(z << 4)+0x0e; BAsmCode[1]=AdrVals[0]; CodeLen=2;
+ break;
+ case ModAbs:
+ BAsmCode[0]=(z << 4)+0x08; memcpy(BAsmCode+1,AdrVals,2); CodeLen=3;
+ break;
+ case ModIReg:
+ if (AdrPart==0) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=(z << 4)+0x0f; CodeLen=2;
+ END
+ break;
+ case ModIndex:
+ BAsmCode[0]=0x31; BAsmCode[1]=(z << 4)+0x0a+AdrPart; CodeLen=2;
+ break;
+ case ModDisp:
+ BAsmCode[0]=(z << 4)+0x09; BAsmCode[1]=AdrVals[0]; CodeLen=2;
+ break;
+ END
+ break;
+ case ModShort:
+ BAsmCode[1]=AdrVals[0];
+ DecodeAdr(ArgStr[2],MModImm);
+ if (AdrMode==ModImm)
+ BEGIN
+ BAsmCode[0]=(z << 4)+0x88; BAsmCode[2]=AdrVals[0]; CodeLen=3;
+ END
+ break;
+ END
+ END
+ return;
+ END
+
+ for (z=0; z<Ari16OrderCount; z++)
+ if (Memo(Ari16Orders[z]))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ OpSize=1;
+ DecodeAdr(ArgStr[1],MModReg16);
+ if (AdrMode==ModReg16)
+ BEGIN
+ DecodeAdr(ArgStr[2],MModImm);
+ if (AdrMode==ModImm)
+ BEGIN
+ BAsmCode[0]=0xca+(z << 4); memcpy(BAsmCode+1,AdrVals,2); CodeLen=3;
+ END
+ END
+ END
+ return;
+ END
+
+ if (Memo("MULU"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg8);
+ if (AdrMode==ModReg8)
+ if (AdrPart!=0) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0x31; BAsmCode[1]=0x88; CodeLen=2;
+ END
+ END
+ return;
+ END
+
+ if (Memo("DIVUW"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg8);
+ if (AdrMode==ModReg8)
+ if (AdrPart!=2) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0x31; BAsmCode[1]=0x82; CodeLen=2;
+ END
+ END
+ return;
+ END
+
+ if ((Memo("INC")) OR (Memo("DEC")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ z=Ord(Memo("DEC")) << 4;
+ DecodeAdr(ArgStr[1],MModReg8+MModShort);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ BAsmCode[0]=0x40+AdrPart+z; CodeLen=1;
+ break;
+ case ModShort:
+ BAsmCode[0]=0x81+z; BAsmCode[1]=AdrVals[0]; CodeLen=2;
+ break;
+ END
+ END
+ return;
+ END
+
+ if ((Memo("INCW")) OR (Memo("DECW")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg16);
+ if (AdrMode==ModReg16)
+ BEGIN
+ BAsmCode[0]=0x80+(Ord(Memo("DECW")) << 4)+(AdrPart << 1);
+ CodeLen=1;
+ END
+ END
+ return;
+ END
+
+ for (z=0; z<ShiftOrderCount; z++)
+ if (Memo(ShiftOrders[z]))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg8);
+ if (AdrMode==ModReg8)
+ if (AdrPart!=AccReg) WrError(1350);
+ else
+ BEGIN
+ HReg=EvalIntExpression(ArgStr[2],UInt1,&OK);
+ if (OK)
+ if (HReg!=1) WrError(1315);
+ else
+ BEGIN
+ BAsmCode[0]=0x24+z; CodeLen=1;
+ END
+ END
+ END
+ return;
+ END
+
+ if ((Memo("ROL4")) OR (Memo("ROR4")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModIReg);
+ if (AdrMode==ModIReg)
+ if (AdrPart==0) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0x31; BAsmCode[1]=0x80+(Ord(Memo("ROR4")) << 4);
+ CodeLen=2;
+ END
+ END
+ return;
+ END
+
+ /* Bitoperationen */
+
+ if (Memo("MOV1"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ if (strcasecmp(ArgStr[2],"CY")==0)
+ BEGIN
+ strcpy(ArgStr[3],ArgStr[1]);
+ strcpy(ArgStr[1],ArgStr[2]);
+ strcpy(ArgStr[2],ArgStr[3]);
+ z=1;
+ END
+ else z=4;
+ if (strcasecmp(ArgStr[1],"CY")!=0) WrError(1110);
+ else if (DecodeBitAdr(ArgStr[2],&HReg))
+ BEGIN
+ BAsmCode[0]=0x61+(Ord((HReg & 0x88)!=0x88) << 4);
+ BAsmCode[1]=z+HReg;
+ memcpy(BAsmCode+2,AdrVals,AdrCnt);
+ CodeLen=2+AdrCnt;
+ END
+ END
+ return;
+ END
+
+ for (z=0; z<Bit2OrderCount; z++)
+ if (Memo(Bit2Orders[z]))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (strcasecmp(ArgStr[1],"CY")!=0) WrError(1110);
+ else if (DecodeBitAdr(ArgStr[2],&HReg))
+ BEGIN
+ BAsmCode[0]=0x61+(Ord((HReg & 0x88)!=0x88) << 4);
+ BAsmCode[1]=z+5+HReg;
+ memcpy(BAsmCode+2,AdrVals,AdrCnt);
+ CodeLen=2+AdrCnt;
+ END
+ return;
+ END
+
+ if ((Memo("SET1")) OR (Memo("CLR1")))
+ BEGIN
+ z=Ord(Memo("CLR1"));
+ if (ArgCnt!=1) WrError(1110);
+ else if (strcasecmp(ArgStr[1],"CY")==0)
+ BEGIN
+ BAsmCode[0]=0x20+z; CodeLen=1;
+ END
+ else if (DecodeBitAdr(ArgStr[1],&HReg))
+ if ((HReg & 0x88)==0)
+ BEGIN
+ BAsmCode[0]=0x0a+z+(HReg & 0x70);
+ BAsmCode[1]=AdrVals[0];
+ CodeLen=2;
+ END
+ else
+ BEGIN
+ BAsmCode[0]=0x61+(Ord((HReg & 0x88)!=0x88) << 4);
+ BAsmCode[1]=HReg+2+z;
+ memcpy(BAsmCode+2,AdrVals,AdrCnt);
+ CodeLen=2+AdrCnt;
+ END
+ return;
+ END
+
+ if (Memo("NOT1"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (strcasecmp(ArgStr[1],"CY")!=0) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0x01;
+ CodeLen=1;
+ END
+ return;
+ END
+
+ /* Spruenge */
+
+ if (Memo("CALL"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModAbs);
+ if (AdrMode==ModAbs)
+ BEGIN
+ BAsmCode[0]=0x9a; memcpy(BAsmCode+1,AdrVals,2); CodeLen=3;
+ END
+ END
+ return;
+ END
+
+ if (Memo("CALLF"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ if (*ArgStr[1]=='!') strcpy(ArgStr[1],ArgStr[1]+1);
+ AdrWord=EvalIntExpression(ArgStr[1],UInt11,&OK);
+ if (OK)
+ BEGIN
+ BAsmCode[0]=0x0c+(Hi(AdrWord) << 4);
+ BAsmCode[1]=Lo(AdrWord);
+ CodeLen=2;
+ END
+ END
+ return;
+ END
+
+ if (Memo("CALLT"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if ((*ArgStr[1]!='[') OR (ArgStr[1][strlen(ArgStr[1])-1]!=']')) WrError(1350);
+ else
+ BEGIN
+ FirstPassUnknown=False;
+ ArgStr[1][strlen(ArgStr[1])-1]='\0';
+ AdrWord=EvalIntExpression(ArgStr[1]+1,UInt6,&OK);
+ if (FirstPassUnknown) AdrWord&=0xfffe;
+ if (OK)
+ if (Odd(AdrWord)) WrError(1325);
+ else
+ BEGIN
+ BAsmCode[0]=0xc1+(AdrWord & 0x3e);
+ CodeLen=1;
+ END
+ END
+ return;
+ END
+
+ if (Memo("BR"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if ((strcasecmp(ArgStr[1],"AX")==0) OR (strcasecmp(ArgStr[1],"RP0")==0))
+ BEGIN
+ BAsmCode[0]=0x31; BAsmCode[1]=0x98; CodeLen=2;
+ END
+ else
+ BEGIN
+ if (*ArgStr[1]=='!')
+ BEGIN
+ strcpy(ArgStr[1],ArgStr[1]+1); HReg=1;
+ END
+ else if (*ArgStr[1]=='$')
+ BEGIN
+ strcpy(ArgStr[1],ArgStr[1]+1); HReg=2;
+ END
+ else HReg=0;
+ AdrWord=EvalIntExpression(ArgStr[1],UInt16,&OK);
+ if (OK)
+ BEGIN
+ if (HReg==0)
+ BEGIN
+ AdrInt=AdrWord-(EProgCounter()-2);
+ HReg=((AdrInt>=-128) AND (AdrInt<127)) ? 2 : 1;
+ END
+ switch (HReg)
+ BEGIN
+ case 1:
+ BAsmCode[0]=0x9b; BAsmCode[1]=Lo(AdrWord); BAsmCode[2]=Hi(AdrWord);
+ CodeLen=3;
+ break;
+ case 2:
+ AdrInt=AdrWord-(EProgCounter()+2);
+ if (((AdrInt<-128) OR (AdrInt>127)) AND (NOT SymbolQuestionable)) WrError(1370);
+ else
+ BEGIN
+ BAsmCode[0]=0xfa; BAsmCode[1]=AdrInt & 0xff; CodeLen=2;
+ END
+ break;
+ END
+ END
+ END
+ return;
+ END
+
+ for (z=0; z<RelOrderCount; z++)
+ if (Memo(RelOrders[z]))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ if (*ArgStr[1]=='$') strcpy(ArgStr[1],ArgStr[1]+1);
+ AdrInt=EvalIntExpression(ArgStr[1],UInt16,&OK)-(EProgCounter()+2);
+ if (OK)
+ if (((AdrInt<-128) OR (AdrInt>127)) AND (NOT SymbolQuestionable)) WrError(1370);
+ else
+ BEGIN
+ BAsmCode[0]=0x8b+(z << 4); BAsmCode[1]=AdrInt & 0xff;
+ CodeLen=2;
+ END
+ END
+ return;
+ END
+
+ for (z=0; z<BRelOrderCount; z++)
+ if (Memo(BRelOrders[z]))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (DecodeBitAdr(ArgStr[1],&HReg))
+ BEGIN
+ if ((z==1) AND ((HReg & 0x88)==0))
+ BEGIN
+ BAsmCode[0]=0x8c+HReg; BAsmCode[1]=AdrVals[0]; HReg=2;
+ END
+ else
+ BEGIN
+ BAsmCode[0]=0x31;
+ switch (HReg & 0x88)
+ BEGIN
+ case 0x00:
+ BAsmCode[1]=0x00; break;
+ case 0x08:
+ BAsmCode[1]=0x04; break;
+ case 0x80:
+ BAsmCode[1]=0x84; break;
+ case 0x88:
+ BAsmCode[1]=0x0c; break;
+ END
+ BAsmCode[1]+=(HReg & 0x70)+z+1;
+ BAsmCode[2]=AdrVals[0];
+ HReg=2+AdrCnt;
+ END
+ if (*ArgStr[2]=='$') strcpy(ArgStr[2],ArgStr[2]+1);
+ AdrInt=EvalIntExpression(ArgStr[2],UInt16,&OK)-(EProgCounter()+HReg+1);
+ if (OK)
+ if (((AdrInt<-128) OR (AdrInt>127)) AND (NOT SymbolQuestionable)) WrError(1370);
+ else
+ BEGIN
+ BAsmCode[HReg]=AdrInt & 0xff;
+ CodeLen=HReg+1;
+ END
+ END
+ return;
+ END
+
+ if (Memo("DBNZ"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg8+MModShort);
+ if ((AdrMode==ModReg8) AND ((AdrPart & 6)!=2)) WrError(1350);
+ else if (AdrMode!=ModNone)
+ BEGIN
+ BAsmCode[0]=(AdrMode==ModReg8) ? 0x88+AdrPart : 0x04;
+ BAsmCode[1]=AdrVals[0];
+ if (*ArgStr[2]=='$') strcpy(ArgStr[2],ArgStr[2]+1);
+ AdrInt=EvalIntExpression(ArgStr[2],UInt16,&OK)-(EProgCounter()+AdrCnt+2);
+ if (OK)
+ if (((AdrInt<-128) OR (AdrInt>127)) AND (NOT SymbolQuestionable)) WrError(1370);
+ else
+ BEGIN
+ BAsmCode[AdrCnt+1]=AdrInt & 0xff;
+ CodeLen=AdrCnt+2;
+ END
+ END
+ END
+ return;
+ END
+
+ /* Steueranweisungen */
+
+ if (Memo("SEL"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1350);
+ else if ((strlen(ArgStr[1])!=3) OR (strncasecmp(ArgStr[1],"RB",2)!=0)) WrError(1350);
+ else
+ BEGIN
+ HReg=ArgStr[1][2]-'0';
+ if (ChkRange(HReg,0,3))
+ BEGIN
+ BAsmCode[0]=0x61;
+ BAsmCode[1]=0xd0+((HReg & 1) << 3)+((HReg & 2) << 4);
+ CodeLen=2;
+ END
+ END
+ return;
+ END
+
+ WrXError(1200,OpPart);
+END
+
+ static Boolean IsDef_78K0(void)
+BEGIN
+ return False;
+END
+
+ static void SwitchFrom_78K0(void)
+BEGIN
+ DeinitFields();
+END
+
+ static void SwitchTo_78K0(void)
+BEGIN
+ TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False;
+
+ PCSymbol="PC"; HeaderID=0x7c; NOPCode=0x00;
+ DivideChars=","; HasAttrs=False;
+
+ ValidSegs=1<<SegCode;
+ Grans[SegCode]=1; ListGrans[SegCode]=1; SegInits[SegCode]=0;
+ SegLimits[SegCode] = 0xffff;
+
+ MakeCode=MakeCode_78K0; IsDef=IsDef_78K0;
+ SwitchFrom=SwitchFrom_78K0; InitFields();
+END
+
+ void code78k0_init(void)
+BEGIN
+ CPU78070=AddCPU("78070",SwitchTo_78K0);
+END
+
+
+