aboutsummaryrefslogtreecommitdiffstats
path: root/codez8.c
diff options
context:
space:
mode:
Diffstat (limited to 'codez8.c')
-rw-r--r--codez8.c856
1 files changed, 856 insertions, 0 deletions
diff --git a/codez8.c b/codez8.c
new file mode 100644
index 0000000..5818bb5
--- /dev/null
+++ b/codez8.c
@@ -0,0 +1,856 @@
+/* codez8.c */
+/*****************************************************************************/
+/* AS-Portierung */
+/* */
+/* Codegenerator Zilog Z8 */
+/* */
+/* Historie: 8.11.1996 Grundsteinlegung */
+/* 2. 1.1998 ChkPC ersetzt */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+#include <string.h>
+#include <ctype.h>
+
+#include "nls.h"
+#include "strutil.h"
+#include "bpemu.h"
+#include "asmdef.h"
+#include "asmsub.h"
+#include "asmpars.h"
+#include "codepseudo.h"
+#include "codevars.h"
+
+typedef struct
+ {
+ char *Name;
+ Byte Code;
+ } FixedOrder;
+
+typedef struct
+ {
+ char *Name;
+ Byte Code;
+ Boolean Is16;
+ } ALU1Order;
+
+typedef struct
+ {
+ char *Name;
+ Byte Code;
+ } Condition;
+
+
+#define WorkOfs 0xe0
+
+
+#define FixedOrderCnt 12
+
+#define ALU2OrderCnt 10
+
+#define ALU1OrderCnt 14
+
+#define CondCnt 20
+
+#define ModNone (-1)
+#define ModWReg 0
+#define MModWReg (1 << ModWReg)
+#define ModReg 1
+#define MModReg (1 << ModReg)
+#define ModIWReg 2
+#define MModIWReg (1 << ModIWReg)
+#define ModIReg 3
+#define MModIReg (1 << ModIReg)
+#define ModImm 4
+#define MModImm (1 << ModImm)
+#define ModRReg 5
+#define MModRReg (1 << ModRReg)
+#define ModIRReg 6
+#define MModIRReg (1 << ModIRReg)
+#define ModInd 7
+#define MModInd (1 << ModInd)
+
+static ShortInt AdrType;
+static Byte AdrMode,AdrIndex;
+static Word AdrWMode;
+
+static FixedOrder *FixedOrders;
+static FixedOrder *ALU2Orders;
+static ALU1Order *ALU1Orders;
+static Condition *Conditions;
+static int TrueCond;
+
+static CPUVar CPUZ8601,CPUZ8604,CPUZ8608,CPUZ8630,CPUZ8631;
+
+/*--------------------------------------------------------------------------*/
+
+ static void AddFixed(char *NName, Byte NCode)
+BEGIN
+ if (InstrZ>=FixedOrderCnt) exit(255);
+ FixedOrders[InstrZ].Name=NName;
+ FixedOrders[InstrZ++].Code=NCode;
+END
+
+ static void AddALU2(char *NName, Byte NCode)
+BEGIN
+ if (InstrZ>=ALU2OrderCnt) exit(255);
+ ALU2Orders[InstrZ].Name=NName;
+ ALU2Orders[InstrZ++].Code=NCode;
+END
+
+ static void AddALU1(char *NName, Byte NCode, Boolean NIs)
+BEGIN
+ if (InstrZ>=ALU1OrderCnt) exit(255);
+ ALU1Orders[InstrZ].Name=NName;
+ ALU1Orders[InstrZ].Is16=NIs;
+ ALU1Orders[InstrZ++].Code=NCode;
+END
+
+ static void AddCondition(char *NName, Byte NCode)
+BEGIN
+ if (InstrZ>=CondCnt) exit(255);
+ Conditions[InstrZ].Name=NName;
+ Conditions[InstrZ++].Code=NCode;
+END
+
+ static void InitFields(void)
+BEGIN
+ FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); InstrZ=0;
+ AddFixed("CCF" , 0xef); AddFixed("DI" , 0x8f);
+ AddFixed("EI" , 0x9f); AddFixed("HALT", 0x7f);
+ AddFixed("IRET", 0xbf); AddFixed("NOP" , 0xff);
+ AddFixed("RCF" , 0xcf); AddFixed("RET" , 0xaf);
+ AddFixed("SCF" , 0xdf); AddFixed("STOP", 0x6f);
+ AddFixed("WDH" , 0x4f); AddFixed("WDT" , 0x5f);
+
+ ALU2Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*ALU2OrderCnt); InstrZ=0;
+ AddALU2("ADD" ,0x00);
+ AddALU2("ADC" ,0x10);
+ AddALU2("SUB" ,0x20);
+ AddALU2("SBC" ,0x30);
+ AddALU2("OR" ,0x40);
+ AddALU2("AND" ,0x50);
+ AddALU2("TCM" ,0x60);
+ AddALU2("TM" ,0x70);
+ AddALU2("CP" ,0xa0);
+ AddALU2("XOR" ,0xb0);
+
+ ALU1Orders=(ALU1Order *) malloc(sizeof(ALU1Order)*ALU1OrderCnt); InstrZ=0;
+ AddALU1("DEC" , 0x00, False);
+ AddALU1("RLC" , 0x10, False);
+ AddALU1("DA" , 0x40, False);
+ AddALU1("POP" , 0x50, False);
+ AddALU1("COM" , 0x60, False);
+ AddALU1("PUSH", 0x70, False);
+ AddALU1("DECW", 0x80, True );
+ AddALU1("RL" , 0x90, False);
+ AddALU1("INCW", 0xa0, True );
+ AddALU1("CLR" , 0xb0, False);
+ AddALU1("RRC" , 0xc0, False);
+ AddALU1("SRA" , 0xd0, False);
+ AddALU1("RR" , 0xe0, False);
+ AddALU1("SWAP", 0xf0, False);
+
+ Conditions=(Condition *) malloc(sizeof(Condition)*CondCnt); InstrZ=0;
+ AddCondition("F" , 0); TrueCond=InstrZ; AddCondition("T" , 8);
+ AddCondition("C" , 7); AddCondition("NC" ,15);
+ AddCondition("Z" , 6); AddCondition("NZ" ,14);
+ AddCondition("MI" , 5); AddCondition("PL" ,13);
+ AddCondition("OV" , 4); AddCondition("NOV",12);
+ AddCondition("EQ" , 6); AddCondition("NE" ,14);
+ AddCondition("LT" , 1); AddCondition("GE" , 9);
+ AddCondition("LE" , 2); AddCondition("GT" ,10);
+ AddCondition("ULT", 7); AddCondition("UGE",15);
+ AddCondition("ULE", 3); AddCondition("UGT",11);
+END
+
+ static void DeinitFields(void)
+BEGIN
+ free(FixedOrders);
+ free(ALU2Orders);
+ free(ALU1Orders);
+ free(Conditions);
+END
+
+/*--------------------------------------------------------------------------*/
+
+ static Boolean IsWReg(char *Asc, Byte *Erg)
+BEGIN
+ Boolean Err;
+
+ if ((strlen(Asc)<2) OR (toupper(*Asc)!='R')) return False;
+ else
+ BEGIN
+ *Erg=ConstLongInt(Asc+1,&Err);
+ if (NOT Err) return False;
+ else return (*Erg<=15);
+ END
+END
+
+ static Boolean IsRReg(char *Asc, Byte *Erg)
+BEGIN
+ Boolean Err;
+
+ if ((strlen(Asc)<3) OR (strncasecmp(Asc,"RR",2)!=0)) return False;
+ else
+ BEGIN
+ *Erg=ConstLongInt(Asc+2,&Err);
+ if (NOT Err) return False;
+ else return (*Erg<=15);
+ END
+END
+
+ static void CorrMode(Byte Mask, ShortInt Old, ShortInt New)
+BEGIN
+ if ((AdrType==Old) AND ((Mask & (1 << Old))==0))
+ BEGIN
+ AdrType=New; AdrMode+=WorkOfs;
+ END
+END
+
+ static void ChkAdr(Byte Mask, Boolean Is16)
+BEGIN
+ if (NOT Is16)
+ BEGIN
+ CorrMode(Mask,ModWReg,ModReg);
+ CorrMode(Mask,ModIWReg,ModIReg);
+ END
+
+ if ((AdrType!=ModNone) AND ((Mask & (1 << AdrType))==0))
+ BEGIN
+ WrError(1350); AdrType=ModNone;
+ END
+END
+
+ static void DecodeAdr(char *Asc, Byte Mask, Boolean Is16)
+BEGIN
+ Boolean OK;
+ char *p;
+
+ AdrType=ModNone;
+
+ /* immediate ? */
+
+ if (*Asc=='#')
+ BEGIN
+ AdrMode=EvalIntExpression(Asc+1,Int8,&OK);
+ if (OK) AdrType=ModImm;
+ ChkAdr(Mask,Is16); return;
+ END;
+
+ /* Register ? */
+
+ if (IsWReg(Asc,&AdrMode))
+ BEGIN
+ AdrType=ModWReg; ChkAdr(Mask,Is16); return;
+ END
+
+ if (IsRReg(Asc,&AdrMode))
+ BEGIN
+ if ((AdrMode&1)==1) WrError(1351); else AdrType=ModRReg;
+ ChkAdr(Mask,Is16); return;
+ END
+
+ /* indirekte Konstrukte ? */
+
+ if (*Asc=='@')
+ BEGIN
+ strcpy(Asc,Asc+1);
+ if (IsWReg(Asc,&AdrMode)) AdrType=ModIWReg;
+ else if (IsRReg(Asc,&AdrMode))
+ BEGIN
+ if ((AdrMode&1)==1) WrError(1351); else AdrType=ModIRReg;
+ END
+ else
+ BEGIN
+ AdrMode=EvalIntExpression(Asc,Int8,&OK);
+ if (OK)
+ BEGIN
+ AdrType=ModIReg; ChkSpace(SegData);
+ END
+ END
+ ChkAdr(Mask,Is16); return;
+ END
+
+ /* indiziert ? */
+
+ if ((Asc[strlen(Asc)-1]==')') AND (strlen(Asc)>4))
+ BEGIN
+ p=Asc+strlen(Asc)-1; *p='\0';
+ while ((p>=Asc) AND (*p!='(')) p--;
+ if (*p!='(') WrError(1300);
+ else if (NOT IsWReg(p+1,&AdrMode)) WrXError(1445,p+1);
+ else
+ BEGIN
+ *p='\0';
+ AdrIndex=EvalIntExpression(Asc,Int8,&OK);
+ if (OK)
+ BEGIN
+ AdrType=ModInd; ChkSpace(SegData);
+ END
+ ChkAdr(Mask,Is16); return;
+ END
+ END
+
+ /* einfache direkte Adresse ? */
+
+ if (Is16) AdrWMode=EvalIntExpression(Asc,UInt16,&OK);
+ else AdrMode=EvalIntExpression(Asc,UInt8,&OK);
+ if (OK)
+ BEGIN
+ AdrType=ModReg;
+ ChkSpace((Is16)?SegCode:SegData);
+ ChkAdr(Mask,Is16); return;
+ END
+
+ ChkAdr(Mask,Is16);
+END
+
+/*---------------------------------------------------------------------*/
+
+ static Boolean DecodePseudo(void)
+BEGIN
+ if (Memo("SFR"))
+ BEGIN
+ CodeEquate(SegData,0,0xff);
+ return True;
+ END
+
+ return False;
+END
+
+ static void MakeCode_Z8(void)
+BEGIN
+ Integer AdrInt;
+ int z;
+ Byte Save;
+ Boolean OK;
+
+ CodeLen=0; DontPrint=False;
+
+ /* zu ignorierendes */
+
+ if (Memo("")) return;
+
+ /* Pseudoanweisungen */
+
+ if (DecodePseudo()) return;
+
+ if (DecodeIntelPseudo(True)) return;
+
+ /* ohne Argument */
+
+ for (z=0; z<FixedOrderCnt; z++)
+ if (Memo(FixedOrders[z].Name))
+ BEGIN
+ if (ArgCnt!=0) WrError(1110);
+ else
+ BEGIN
+ CodeLen=1; BAsmCode[0]=FixedOrders[z].Code;
+ END
+ return;
+ END
+
+ /* Datentransfer */
+
+ if (Memo("LD"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg+MModWReg+MModIReg+MModIWReg+MModInd,False);
+ switch (AdrType)
+ BEGIN
+ case ModReg:
+ Save=AdrMode;
+ DecodeAdr(ArgStr[2],MModReg+MModWReg+MModIReg+MModImm,False);
+ switch (AdrType)
+ BEGIN
+ case ModReg:
+ BAsmCode[0]=0xe4;
+ BAsmCode[1]=AdrMode; BAsmCode[2]=Save;
+ CodeLen=3;
+ break;
+ case ModWReg:
+ BAsmCode[0]=(AdrMode << 4)+9;
+ BAsmCode[1]=Save;
+ CodeLen=2;
+ break;
+ case ModIReg:
+ BAsmCode[0]=0xe5;
+ BAsmCode[1]=AdrMode; BAsmCode[2]=Save;
+ CodeLen=3;
+ break;
+ case ModImm:
+ BAsmCode[0]=0xe6;
+ BAsmCode[1]=Save; BAsmCode[2]=AdrMode;
+ CodeLen=3;
+ break;
+ END
+ break;
+ case ModWReg:
+ Save=AdrMode;
+ DecodeAdr(ArgStr[2],MModWReg+MModReg+MModIWReg+MModIReg+MModImm+MModInd,False);
+ switch (AdrType)
+ BEGIN
+ case ModWReg:
+ BAsmCode[0]=(Save << 4)+8; BAsmCode[1]=AdrMode+WorkOfs;
+ CodeLen=2;
+ break;
+ case ModReg:
+ BAsmCode[0]=(Save << 4)+8; BAsmCode[1]=AdrMode;
+ CodeLen=2;
+ break;
+ case ModIWReg:
+ BAsmCode[0]=0xe3; BAsmCode[1]=(Save << 4)+AdrMode;
+ CodeLen=2;
+ break;
+ case ModIReg:
+ BAsmCode[0]=0xe5;
+ BAsmCode[1]=AdrMode; BAsmCode[2]=WorkOfs+Save;
+ CodeLen=3;
+ break;
+ case ModImm:
+ BAsmCode[0]=(Save << 4)+12; BAsmCode[1]=AdrMode;
+ CodeLen=2;
+ break;
+ case ModInd:
+ BAsmCode[0]=0xc7;
+ BAsmCode[1]=(Save << 4)+AdrMode; BAsmCode[2]=AdrIndex;
+ CodeLen=3;
+ break;
+ END
+ break;
+ case ModIReg:
+ Save=AdrMode;
+ DecodeAdr(ArgStr[2],MModReg+MModImm,False);
+ switch (AdrType)
+ BEGIN
+ case ModReg:
+ BAsmCode[0]=0xf5;
+ BAsmCode[1]=AdrMode; BAsmCode[2]=Save;
+ CodeLen=3;
+ break;
+ case ModImm:
+ BAsmCode[0]=0xe7;
+ BAsmCode[1]=Save; BAsmCode[2]=AdrMode;
+ CodeLen=3;
+ break;
+ END
+ break;
+ case ModIWReg:
+ Save=AdrMode;
+ DecodeAdr(ArgStr[2],MModWReg+MModReg+MModImm,False);
+ switch (AdrType)
+ BEGIN
+ case ModWReg:
+ BAsmCode[0]=0xf3; BAsmCode[1]=(Save << 4)+AdrMode;
+ CodeLen=2;
+ break;
+ case ModReg:
+ BAsmCode[0]=0xf5;
+ BAsmCode[1]=AdrMode; BAsmCode[2]=WorkOfs+Save;
+ CodeLen=3;
+ break;
+ case ModImm:
+ BAsmCode[0]=0xe7;
+ BAsmCode[1]=WorkOfs+Save; BAsmCode[2]=AdrMode;
+ CodeLen=3;
+ break;
+ END
+ break;
+ case ModInd:
+ Save=AdrMode;
+ DecodeAdr(ArgStr[2],MModWReg,False);
+ switch (AdrType)
+ BEGIN
+ case ModWReg:
+ BAsmCode[0]=0xd7;
+ BAsmCode[1]=(AdrMode << 4)+Save; BAsmCode[2]=AdrIndex;
+ CodeLen=3;
+ break;
+ END
+ break;
+ END
+ END
+ return;
+ END
+
+ if ((Memo("LDC")) OR (Memo("LDE")))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModWReg+MModIRReg,False);
+ switch (AdrType)
+ BEGIN
+ case ModWReg:
+ Save=AdrMode; DecodeAdr(ArgStr[2],MModIRReg,False);
+ if (AdrType!=ModNone)
+ BEGIN
+ BAsmCode[0]=(Memo("LDC")) ? 0xc2 : 0x82;
+ BAsmCode[1]=(Save << 4)+AdrMode;
+ CodeLen=2;
+ END
+ break;
+ case ModIRReg:
+ Save=AdrMode; DecodeAdr(ArgStr[2],MModWReg,False);
+ if (AdrType!=ModNone)
+ BEGIN
+ BAsmCode[0]=(Memo("LDC")) ? 0xd2 : 0x92;
+ BAsmCode[1]=(AdrMode << 4)+Save;
+ CodeLen=2;
+ END
+ break;
+ END
+ END
+ return;
+ END
+
+ if ((Memo("LDCI")) OR (Memo("LDEI")))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModIWReg+MModIRReg,False);
+ switch (AdrType)
+ BEGIN
+ case ModIWReg:
+ Save=AdrMode; DecodeAdr(ArgStr[2],MModIRReg,False);
+ if (AdrType!=ModNone)
+ BEGIN
+ BAsmCode[0]=(Memo("LDCI")) ? 0xc3 : 0x83;
+ BAsmCode[1]=(Save << 4)+AdrMode;
+ CodeLen=2;
+ END
+ break;
+ case ModIRReg:
+ Save=AdrMode; DecodeAdr(ArgStr[2],MModIWReg,False);
+ if (AdrType!=ModNone)
+ BEGIN
+ BAsmCode[0]=(Memo("LDCI")) ? 0xd3 : 0x93;
+ BAsmCode[1]=(AdrMode << 4)+Save;
+ CodeLen=2;
+ END
+ break;
+ END
+ END
+ return;
+ END
+
+ /* Arithmetik */
+
+ for (z=0; z<ALU2OrderCnt; z++)
+ if (Memo(ALU2Orders[z].Name))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModReg+MModWReg+MModIReg,False);
+ switch (AdrType)
+ BEGIN
+ case ModReg:
+ Save=AdrMode;
+ DecodeAdr(ArgStr[2],MModReg+MModIReg+MModImm,False);
+ switch (AdrType)
+ BEGIN
+ case ModReg:
+ BAsmCode[0]=ALU2Orders[z].Code+4;
+ BAsmCode[1]=AdrMode;
+ BAsmCode[2]=Save;
+ CodeLen=3;
+ break;
+ case ModIReg:
+ BAsmCode[0]=ALU2Orders[z].Code+5;
+ BAsmCode[1]=AdrMode;
+ BAsmCode[2]=Save;
+ CodeLen=3;
+ break;
+ case ModImm:
+ BAsmCode[0]=ALU2Orders[z].Code+6;
+ BAsmCode[1]=Save;
+ BAsmCode[2]=AdrMode;
+ CodeLen=3;
+ break;
+ END
+ break;
+ case ModWReg:
+ Save=AdrMode;
+ DecodeAdr(ArgStr[2],MModWReg+MModReg+MModIWReg+MModIReg+MModImm,False);
+ switch (AdrType)
+ BEGIN
+ case ModWReg:
+ BAsmCode[0]=ALU2Orders[z].Code+2;
+ BAsmCode[1]=(Save << 4)+AdrMode;
+ CodeLen=2;
+ break;
+ case ModReg:
+ BAsmCode[0]=ALU2Orders[z].Code+4;
+ BAsmCode[1]=AdrMode;
+ BAsmCode[2]=WorkOfs+Save;
+ CodeLen=3;
+ break;
+ case ModIWReg:
+ BAsmCode[0]=ALU2Orders[z].Code+3;
+ BAsmCode[1]=(Save << 4)+AdrMode;
+ CodeLen=2;
+ break;
+ case ModIReg:
+ BAsmCode[0]=ALU2Orders[z].Code+5;
+ BAsmCode[1]=AdrMode;
+ BAsmCode[2]=WorkOfs+Save;
+ CodeLen=3;
+ break;
+ case ModImm:
+ BAsmCode[0]=ALU2Orders[z].Code+6;
+ BAsmCode[1]=Save+WorkOfs;
+ BAsmCode[2]=AdrMode;
+ CodeLen=3;
+ break;
+ END
+ break;
+ case ModIReg:
+ Save=AdrMode;
+ DecodeAdr(ArgStr[2],MModImm,False);
+ switch (AdrType)
+ BEGIN
+ case ModImm:
+ BAsmCode[0]=ALU2Orders[z].Code+7;
+ BAsmCode[1]=Save;
+ BAsmCode[2]=AdrMode;
+ CodeLen=3;
+ break;
+ END
+ break;
+ END
+ END
+ return;
+ END
+
+ /* INC hat eine Optimierungsmoeglichkeit */
+
+ if (Memo("INC"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModWReg+MModReg+MModIReg,False);
+ switch (AdrType)
+ BEGIN
+ case ModWReg:
+ BAsmCode[0]=(AdrMode << 4)+0x0e; CodeLen=1;
+ break;
+ case ModReg:
+ BAsmCode[0]=0x20; BAsmCode[1]=AdrMode; CodeLen=2;
+ break;
+ case ModIReg:
+ BAsmCode[0]=0x21; BAsmCode[1]=AdrMode; CodeLen=2;
+ break;
+ END
+ END
+ return;
+ END
+
+ /* ...alle anderen nicht */
+
+ for (z=0; z<ALU1OrderCnt; z++)
+ if (Memo(ALU1Orders[z].Name))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],((ALU1Orders[z].Is16)?MModRReg:0)+MModReg+MModIReg,False);
+ switch (AdrType)
+ BEGIN
+ case ModReg:
+ BAsmCode[0]=ALU1Orders[z].Code; BAsmCode[1]=AdrMode; CodeLen=2;
+ break;
+ case ModRReg:
+ BAsmCode[0]=ALU1Orders[z].Code; BAsmCode[1]=WorkOfs+AdrMode; CodeLen=2;
+ break;
+ case ModIReg:
+ BAsmCode[0]=ALU1Orders[z].Code+1; BAsmCode[1]=AdrMode; CodeLen=2;
+ break;
+ END
+ END
+ return;
+ END
+
+ /* Spruenge */
+
+ if (Memo("JR"))
+ BEGIN
+ if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110);
+ else
+ BEGIN
+ if (ArgCnt==1) z=TrueCond;
+ else
+ BEGIN
+ z=0; NLS_UpString(ArgStr[1]);
+ while ((z<CondCnt) AND (strcmp(Conditions[z].Name,ArgStr[1])!=0)) z++;
+ if (z>=CondCnt) WrError(1360);
+ END
+ if (z<CondCnt)
+ BEGIN
+ AdrInt=EvalIntExpression(ArgStr[ArgCnt],Int16,&OK)-(EProgCounter()+2);
+ if (OK)
+ if ((NOT SymbolQuestionable) AND ((AdrInt>127) OR (AdrInt<-128))) WrError(1370);
+ else
+ BEGIN
+ ChkSpace(SegCode);
+ BAsmCode[0]=(Conditions[z].Code << 4)+0x0b;
+ BAsmCode[1]=Lo(AdrInt);
+ CodeLen=2;
+ END
+ END
+ END
+ return;
+ END
+
+ if (Memo("DJNZ"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModWReg,False);
+ if (AdrType!=ModNone)
+ BEGIN
+ AdrInt=EvalIntExpression(ArgStr[2],Int16,&OK)-(EProgCounter()+2);
+ if (OK)
+ if ((NOT SymbolQuestionable) AND ((AdrInt>127) OR (AdrInt<-128))) WrError(1370);
+ else
+ BEGIN
+ BAsmCode[0]=(AdrMode << 4)+0x0a;
+ BAsmCode[1]=Lo(AdrInt);
+ CodeLen=2;
+ END
+ END
+ END
+ return;
+ END
+
+ if (Memo("CALL"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModIRReg+MModIReg+MModReg,True);
+ switch (AdrType)
+ BEGIN
+ case ModIRReg:
+ BAsmCode[0]=0xd4; BAsmCode[1]=0xe0+AdrMode; CodeLen=2;
+ break;
+ case ModIReg:
+ BAsmCode[0]=0xd4; BAsmCode[1]=AdrMode; CodeLen=2;
+ break;
+ case ModReg:
+ BAsmCode[0]=0xd6;
+ BAsmCode[1]=Hi(AdrWMode); BAsmCode[2]=Lo(AdrWMode);
+ CodeLen=3;
+ break;
+ END
+ END
+ return;
+ END
+
+ if (Memo("JP"))
+ BEGIN
+ if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110);
+ else
+ BEGIN
+ if (ArgCnt==1) z=TrueCond;
+ else
+ BEGIN
+ z=0; NLS_UpString(ArgStr[1]);
+ while ((z<CondCnt) AND (strcmp(Conditions[z].Name,ArgStr[1])!=0)) z++;
+ if (z>=CondCnt) WrError(1360);
+ END
+ if (z<CondCnt)
+ BEGIN
+ DecodeAdr(ArgStr[ArgCnt],MModIRReg+MModIReg+MModReg,True);
+ switch (AdrType)
+ BEGIN
+ case ModIRReg:
+ if (z!=TrueCond) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0x30; BAsmCode[1]=0xe0+AdrMode; CodeLen=2;
+ END
+ break;
+ case ModIReg:
+ if (z!=TrueCond) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0x30; BAsmCode[1]=AdrMode; CodeLen=2;
+ END
+ break;
+ case ModReg:
+ BAsmCode[0]=(Conditions[z].Code << 4)+0x0d;
+ BAsmCode[1]=Hi(AdrWMode); BAsmCode[2]=Lo(AdrWMode);
+ CodeLen=3;
+ break;
+ END
+ END
+ END
+ return;
+ END
+
+ /* Sonderbefehle */
+
+ if (Memo("SRP"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModImm,False);
+ if (AdrType==ModImm)
+ if (((AdrMode & 15)!=0) OR ((AdrMode>0x70) AND (AdrMode<0xf0))) WrError(120);
+ else
+ BEGIN
+ BAsmCode[0]=0x31; BAsmCode[1]=AdrMode;
+ CodeLen=2;
+ END
+ END
+ return;
+ END
+
+ WrXError(1200,OpPart);
+END
+
+ static Boolean IsDef_Z8(void)
+BEGIN
+ return (Memo("SFR"));
+END
+
+ static void SwitchFrom_Z8(void)
+BEGIN
+ DeinitFields();
+END
+
+ static void SwitchTo_Z8(void)
+BEGIN
+ TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False;
+
+ PCSymbol="$"; HeaderID=0x79; NOPCode=0xff;
+ DivideChars=","; HasAttrs=False;
+
+ ValidSegs=(1<<SegCode)|(1<<SegData);
+ Grans[SegCode]=1; ListGrans[SegCode]=1; SegInits[SegCode]=0;
+ SegLimits[SegCode] = 0xffff;
+ Grans[SegData]=1; ListGrans[SegData]=1; SegInits[SegData]=0;
+ SegLimits[SegData] = 0xff;
+
+ MakeCode=MakeCode_Z8; IsDef=IsDef_Z8;
+ SwitchFrom=SwitchFrom_Z8; InitFields();
+END
+
+ void codez8_init(void)
+BEGIN
+ CPUZ8601=AddCPU("Z8601",SwitchTo_Z8);
+ CPUZ8604=AddCPU("Z8604",SwitchTo_Z8);
+ CPUZ8608=AddCPU("Z8608",SwitchTo_Z8);
+ CPUZ8630=AddCPU("Z8630",SwitchTo_Z8);
+ CPUZ8631=AddCPU("Z8631",SwitchTo_Z8);
+END
+