aboutsummaryrefslogtreecommitdiffstats
path: root/codez80.c
diff options
context:
space:
mode:
authorfishsoupisgood <github@madingley.org>2019-05-27 02:41:51 +0100
committerfishsoupisgood <github@madingley.org>2019-05-27 02:41:51 +0100
commit333b605b2afd472b823aeda0adf0e8b1ea9843c0 (patch)
treebc8f581317897e2e53f278f1716b4471fcdccd4f /codez80.c
downloadasl-master.tar.gz
asl-master.tar.bz2
asl-master.zip
initial commit from asl-1.41r8.tar.gzHEADmaster
Diffstat (limited to 'codez80.c')
-rw-r--r--codez80.c2814
1 files changed, 2814 insertions, 0 deletions
diff --git a/codez80.c b/codez80.c
new file mode 100644
index 0000000..055a5f0
--- /dev/null
+++ b/codez80.c
@@ -0,0 +1,2814 @@
+/* codez80.c */
+/*****************************************************************************/
+/* AS-Portierung */
+/* */
+/* Codegenerator Zilog Z80/180/380 */
+/* */
+/* Historie: 26. 8.1996 Grundsteinlegung */
+/* 1. 2.1998 ChkPC ersetzt */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+#include <ctype.h>
+#include <string.h>
+
+#include "nls.h"
+#include "strutil.h"
+#include "bpemu.h"
+#include "asmdef.h"
+#include "asmsub.h"
+#include "asmpars.h"
+#include "asmcode.h"
+#include "asmallg.h"
+#include "codepseudo.h"
+#include "codevars.h"
+
+/*-------------------------------------------------------------------------*/
+/* Instruktionsgruppendefinitionen */
+
+typedef struct
+ {
+ char *Name;
+ CPUVar MinCPU;
+ Byte Len;
+ Word Code;
+ } BaseOrder;
+
+typedef struct
+ {
+ char *Name;
+ Byte Code;
+ } Condition;
+
+typedef struct
+ {
+ char *Name;
+ Byte Code;
+ } ALUOrder;
+
+/*-------------------------------------------------------------------------*/
+/* Praefixtyp */
+
+typedef enum {Pref_IN_N,Pref_IN_W ,Pref_IB_W ,Pref_IW_W ,Pref_IB_N ,
+ Pref_IN_LW,Pref_IB_LW,Pref_IW_LW,Pref_IW_N} PrefType;
+
+
+#define ExtFlagName "INEXTMODE" /* Flag-Symbolnamen */
+#define LWordFlagName "INLWORDMODE"
+
+#define ModNone (-1)
+#define ModReg8 1
+#define ModReg16 2
+#define ModIndReg16 3
+#define ModImm 4
+#define ModAbs 5
+#define ModRef 6
+#define ModInt 7
+#define ModSPRel 8
+
+#define FixedOrderCnt 53
+#define AccOrderCnt 3
+#define HLOrderCnt 3
+#define ALUOrderCnt 5
+#define ShiftOrderCnt 8
+#define BitOrderCnt 3
+#define ConditionCnt 12
+
+#define IXPrefix 0xdd
+#define IYPrefix 0xfd
+
+/*-------------------------------------------------------------------------*/
+
+static Byte PrefixCnt;
+static Byte AdrPart,OpSize;
+static Byte AdrVals[4];
+static ShortInt AdrMode;
+
+static BaseOrder *FixedOrders;
+static BaseOrder *AccOrders;
+static BaseOrder *HLOrders;
+static ALUOrder *ALUOrders;
+static char **ShiftOrders;
+static char **BitOrders;
+static Condition *Conditions;
+
+static SimpProc SaveInitProc;
+
+static CPUVar CPUZ80,CPUZ80U,CPUZ180,CPUZ380;
+
+static Boolean MayLW, /* Instruktion erlaubt 32 Bit */
+ ExtFlag, /* Prozessor im 4GByte-Modus ? */
+ LWordFlag; /* 32-Bit-Verarbeitung ? */
+
+static PrefType CurrPrefix, /* mom. explizit erzeugter Praefix */
+ LastPrefix; /* von der letzten Anweisung generierter Praefix */
+
+/*==========================================================================*/
+/* Codetabellenerzeugung */
+
+ static void AddFixed(char *NewName, CPUVar NewMin, Byte NewLen, Word NewCode)
+BEGIN
+ if (InstrZ>=FixedOrderCnt) exit(255);
+ FixedOrders[InstrZ].Name=NewName;
+ FixedOrders[InstrZ].MinCPU=NewMin;
+ FixedOrders[InstrZ].Len=NewLen;
+ FixedOrders[InstrZ++].Code=NewCode;
+END
+
+ static void AddAcc(char *NewName, CPUVar NewMin, Byte NewLen, Word NewCode)
+BEGIN
+ if (InstrZ>=AccOrderCnt) exit(255);
+ AccOrders[InstrZ].Name=NewName;
+ AccOrders[InstrZ].MinCPU=NewMin;
+ AccOrders[InstrZ].Len=NewLen;
+ AccOrders[InstrZ++].Code=NewCode;
+END
+
+ static void AddHL(char *NewName, CPUVar NewMin, Byte NewLen, Word NewCode)
+BEGIN
+ if (InstrZ>=HLOrderCnt) exit(255);
+ HLOrders[InstrZ].Name=NewName;
+ HLOrders[InstrZ].MinCPU=NewMin;
+ HLOrders[InstrZ].Len=NewLen;
+ HLOrders[InstrZ++].Code=NewCode;
+END
+
+ static void AddALU(char *NewName, Byte NCode)
+BEGIN
+ if (InstrZ>=ALUOrderCnt) exit(255);
+ ALUOrders[InstrZ].Name=NewName;
+ ALUOrders[InstrZ++].Code=NCode;
+END
+
+ static void AddShift(char *NName)
+BEGIN
+ if (InstrZ>=ShiftOrderCnt) exit(255);
+ ShiftOrders[InstrZ++]=NName;
+END
+
+ static void AddBit(char *NName)
+BEGIN
+ if (InstrZ>=BitOrderCnt) exit(255);
+ BitOrders[InstrZ++]=NName;
+END
+
+ static void AddCondition(char *NewName, Byte NewCode)
+BEGIN
+ if (InstrZ>=ConditionCnt) exit(255);
+ Conditions[InstrZ].Name=NewName;
+ Conditions[InstrZ++].Code=NewCode;
+END
+
+ static void InitFields(void)
+BEGIN
+ InstrZ=0; Conditions=(Condition *) malloc(sizeof(Condition)*ConditionCnt);
+ AddCondition("NZ",0); AddCondition("Z" ,1);
+ AddCondition("NC",2); AddCondition("C" ,3);
+ AddCondition("PO",4); AddCondition("NV",4);
+ AddCondition("PE",5); AddCondition("V" ,5);
+ AddCondition("P" ,6); AddCondition("NS",6);
+ AddCondition("M" ,7); AddCondition("S" ,7);
+
+ InstrZ=0; FixedOrders=(BaseOrder *) malloc(sizeof(BaseOrder)*FixedOrderCnt);
+ AddFixed("EXX" ,CPUZ80 ,1,0x00d9); AddFixed("LDI" ,CPUZ80 ,2,0xeda0);
+ AddFixed("LDIR" ,CPUZ80 ,2,0xedb0); AddFixed("LDD" ,CPUZ80 ,2,0xeda8);
+ AddFixed("LDDR" ,CPUZ80 ,2,0xedb8); AddFixed("CPI" ,CPUZ80 ,2,0xeda1);
+ AddFixed("CPIR" ,CPUZ80 ,2,0xedb1); AddFixed("CPD" ,CPUZ80 ,2,0xeda9);
+ AddFixed("CPDR" ,CPUZ80 ,2,0xedb9); AddFixed("RLCA" ,CPUZ80 ,1,0x0007);
+ AddFixed("RRCA" ,CPUZ80 ,1,0x000f); AddFixed("RLA" ,CPUZ80 ,1,0x0017);
+ AddFixed("RRA" ,CPUZ80 ,1,0x001f); AddFixed("RLD" ,CPUZ80 ,2,0xed6f);
+ AddFixed("RRD" ,CPUZ80 ,2,0xed67); AddFixed("DAA" ,CPUZ80 ,1,0x0027);
+ AddFixed("CCF" ,CPUZ80 ,1,0x003f); AddFixed("SCF" ,CPUZ80 ,1,0x0037);
+ AddFixed("NOP" ,CPUZ80 ,1,0x0000); AddFixed("HALT" ,CPUZ80 ,1,0x0076);
+ AddFixed("RETI" ,CPUZ80 ,2,0xed4d); AddFixed("RETN" ,CPUZ80 ,2,0xed45);
+ AddFixed("INI" ,CPUZ80 ,2,0xeda2); AddFixed("INIR" ,CPUZ80 ,2,0xedb2);
+ AddFixed("IND" ,CPUZ80 ,2,0xedaa); AddFixed("INDR" ,CPUZ80 ,2,0xedba);
+ AddFixed("OUTI" ,CPUZ80 ,2,0xeda3); AddFixed("OTIR" ,CPUZ80 ,2,0xedb3);
+ AddFixed("OUTD" ,CPUZ80 ,2,0xedab); AddFixed("OTDR" ,CPUZ80 ,2,0xedbb);
+ AddFixed("SLP" ,CPUZ180,2,0xed76); AddFixed("OTIM" ,CPUZ180,2,0xed83);
+ AddFixed("OTIMR",CPUZ180,2,0xed93); AddFixed("OTDM" ,CPUZ180,2,0xed8b);
+ AddFixed("OTDMR",CPUZ180,2,0xed9b); AddFixed("BTEST",CPUZ380,2,0xedcf);
+ AddFixed("EXALL",CPUZ380,2,0xedd9); AddFixed("EXXX" ,CPUZ380,2,0xddd9);
+ AddFixed("EXXY" ,CPUZ380,2,0xfdd9); AddFixed("INDW" ,CPUZ380,2,0xedea);
+ AddFixed("INDRW",CPUZ380,2,0xedfa); AddFixed("INIW" ,CPUZ380,2,0xede2);
+ AddFixed("INIRW",CPUZ380,2,0xedf2); AddFixed("LDDW" ,CPUZ380,2,0xede8);
+ AddFixed("LDDRW",CPUZ380,2,0xedf8); AddFixed("LDIW" ,CPUZ380,2,0xede0);
+ AddFixed("LDIRW",CPUZ380,2,0xedf0); AddFixed("MTEST",CPUZ380,2,0xddcf);
+ AddFixed("OTDRW",CPUZ380,2,0xedfb); AddFixed("OTIRW",CPUZ380,2,0xedf3);
+ AddFixed("OUTDW",CPUZ380,2,0xedeb); AddFixed("OUTIW",CPUZ380,2,0xede3);
+ AddFixed("RETB" ,CPUZ380,2,0xed55);
+
+ InstrZ=0; AccOrders=(BaseOrder *) malloc(sizeof(BaseOrder)*AccOrderCnt);
+ AddAcc("CPL" ,CPUZ80 ,1,0x002f); AddAcc("NEG" ,CPUZ80 ,2,0xed44);
+ AddAcc("EXTS" ,CPUZ380,2,0xed65);
+
+ InstrZ=0; HLOrders=(BaseOrder *) malloc(sizeof(BaseOrder)*HLOrderCnt);
+ AddHL("CPLW" ,CPUZ380,2,0xdd2f); AddHL("NEGW" ,CPUZ380,2,0xed54);
+ AddHL("EXTSW",CPUZ380,2,0xed75);
+
+ InstrZ=0; ALUOrders=(ALUOrder *) malloc(sizeof(ALUOrder)*ALUOrderCnt);
+ AddALU("SUB", 2); AddALU("AND", 4);
+ AddALU("OR" , 6); AddALU("XOR", 5);
+ AddALU("CP" , 7);
+
+ InstrZ=0; ShiftOrders=(char **) malloc(sizeof(char *)*ShiftOrderCnt);
+ AddShift("RLC"); AddShift("RRC"); AddShift("RL"); AddShift("RR");
+ AddShift("SLA"); AddShift("SRA"); AddShift("SLIA"); AddShift("SRL");
+
+ InstrZ=0; BitOrders=(char **) malloc(sizeof(char *)*BitOrderCnt);
+ AddBit("BIT"); AddBit("RES"); AddBit("SET");
+END
+
+ static void DeinitFields(void)
+BEGIN
+ free(Conditions);
+ free(FixedOrders);
+ free(AccOrders);
+ free(HLOrders);
+ free(ALUOrders);
+ free(ShiftOrders);
+ free(BitOrders);
+END
+
+/*==========================================================================*/
+/* Adressbereiche */
+
+ static LargeWord CodeEnd(void)
+BEGIN
+#ifdef __STDC__
+ if (ExtFlag) return 0xfffffffflu;
+#else
+ if (ExtFlag) return 0xffffffffl;
+#endif
+ else if (MomCPU==CPUZ180) return 0x7ffffl;
+ else return 0xffff;
+END
+
+ static LargeWord PortEnd(void)
+BEGIN
+#ifdef __STDC__
+ if (ExtFlag) return 0xfffffffflu;
+#else
+ if (ExtFlag) return 0xffffffffl;
+#endif
+ else return 0xff;
+END
+
+/*==========================================================================*/
+/* Praefix dazuaddieren */
+
+ static Boolean ExtendPrefix(PrefType *Dest, char *AddArg)
+BEGIN
+ Byte SPart,IPart;
+
+ switch (*Dest)
+ BEGIN
+ case Pref_IB_N:
+ case Pref_IB_W:
+ case Pref_IB_LW: IPart=1; break;
+ case Pref_IW_N:
+ case Pref_IW_W:
+ case Pref_IW_LW: IPart=2; break;
+ default: IPart=0;
+ END
+
+ switch (*Dest)
+ BEGIN
+ case Pref_IN_W:
+ case Pref_IB_W:
+ case Pref_IW_W: SPart=1; break;
+ case Pref_IN_LW:
+ case Pref_IB_LW:
+ case Pref_IW_LW: SPart=2; break;
+ default: SPart=0;
+ END
+
+ if (strcmp(AddArg,"W")==0) /* Wortverarbeitung */
+ SPart=1;
+ else if (strcmp(AddArg,"LW")==0) /* Langwortverarbeitung */
+ SPart=2;
+ else if (strcmp(AddArg,"IB")==0) /* ein Byte im Argument mehr */
+ IPart=1;
+ else if (strcmp(AddArg,"IW")==0) /* ein Wort im Argument mehr */
+ IPart=2;
+ else return False;
+
+ switch ((IPart << 4)+SPart)
+ BEGIN
+ case 0x00:*Dest=Pref_IN_N; break;
+ case 0x01:*Dest=Pref_IN_W; break;
+ case 0x02:*Dest=Pref_IN_LW; break;
+ case 0x10:*Dest=Pref_IB_N; break;
+ case 0x11:*Dest=Pref_IB_W; break;
+ case 0x12:*Dest=Pref_IB_LW; break;
+ case 0x20:*Dest=Pref_IW_N; break;
+ case 0x21:*Dest=Pref_IW_W; break;
+ case 0x22:*Dest=Pref_IW_LW; break;
+ END
+
+ return True;
+END
+
+/*--------------------------------------------------------------------------*/
+/* Code fuer Praefix bilden */
+
+ static void GetPrefixCode(PrefType inp, Byte *b1 ,Byte *b2)
+BEGIN
+ int z;
+
+ z=((int)inp)-1;
+ *b1=0xdd+((z & 4) << 3);
+ *b2=0xc0+(z & 3);
+END
+
+/*--------------------------------------------------------------------------*/
+/* DD-Praefix addieren, nur EINMAL pro Instruktion benutzen! */
+
+ static void ChangeDDPrefix(char *Add)
+BEGIN
+ PrefType ActPrefix;
+ int z;
+
+ ActPrefix=LastPrefix;
+ if (ExtendPrefix(&ActPrefix,Add))
+ if (LastPrefix!=ActPrefix)
+ BEGIN
+ if (LastPrefix!=Pref_IN_N) RetractWords(2);
+ for (z=PrefixCnt-1; z>=0; z--) BAsmCode[2+z]=BAsmCode[z];
+ PrefixCnt+=2;
+ GetPrefixCode(ActPrefix,BAsmCode+0,BAsmCode+1);
+ END
+END
+
+/*--------------------------------------------------------------------------*/
+/* Wortgroesse ? */
+
+ static Boolean InLongMode(void)
+BEGIN
+ switch (LastPrefix)
+ BEGIN
+ case Pref_IN_W:
+ case Pref_IB_W:
+ case Pref_IW_W: return False;
+ case Pref_IN_LW:
+ case Pref_IB_LW:
+ case Pref_IW_LW: return MayLW;
+ default: return LWordFlag AND MayLW;
+ END
+END
+
+/*--------------------------------------------------------------------------*/
+/* absolute Adresse */
+
+ static LongWord EvalAbsAdrExpression(char *inp, Boolean *OK)
+BEGIN
+ return EvalIntExpression(inp,ExtFlag?Int32:UInt16,OK);
+END
+
+/*==========================================================================*/
+/* Adressparser */
+
+ static Boolean DecodeReg8(char *Asc, Byte *Erg)
+BEGIN
+#define Reg8Cnt 7
+ static char *Reg8Names[Reg8Cnt]={"B","C","D","E","H","L","A"};
+ int z;
+
+ for (z=0; z<Reg8Cnt; z++)
+ if (strcasecmp(Asc,Reg8Names[z])==0)
+ BEGIN
+ *Erg=z; if (z==6) (*Erg)++;
+ return True;
+ END
+
+ return False;
+END
+
+ static Boolean IsSym(char ch)
+BEGIN
+ return ((ch=='_') OR ((ch>='0') AND (ch<='9')) OR ((ch>='A') AND (ch<='Z')) OR ((ch>='a') AND (ch<='z')));
+END
+
+ static void DecodeAdr(char *Asc_O)
+BEGIN
+#define Reg8XCnt 4
+ static char *Reg8XNames[Reg8XCnt]={"IXU","IXL","IYU","IYL"};
+#define Reg16Cnt 6
+ static char *Reg16Names[Reg16Cnt]={"BC","DE","HL","SP","IX","IY"};
+
+ int z;
+ Integer AdrInt;
+ LongInt AdrLong;
+ Boolean OK;
+ String Asc;
+
+ AdrMode=ModNone; AdrCnt=0; AdrPart=0;
+
+ /* 0. Sonderregister */
+
+ if (strcasecmp(Asc_O,"R")==0)
+ BEGIN
+ AdrMode=ModRef; return;
+ END
+
+ if (strcasecmp(Asc_O,"I")==0)
+ BEGIN
+ AdrMode=ModInt; return;
+ END
+
+ /* 1. 8-Bit-Register ? */
+
+ if (DecodeReg8(Asc_O,&AdrPart))
+ BEGIN
+ AdrMode=ModReg8;
+ return;
+ END
+
+ /* 1a. 8-Bit-Haelften von IX/IY ? (nur Z380, sonst als Symbole zulassen) */
+
+ if ((MomCPU>=CPUZ380) OR (MomCPU==CPUZ80U))
+ for (z=0; z<Reg8XCnt; z++)
+ if (strcasecmp(Asc_O,Reg8XNames[z])==0)
+ BEGIN
+ AdrMode=ModReg8;
+ BAsmCode[PrefixCnt++]=(z<=1)?IXPrefix:IYPrefix;
+ AdrPart=4+(z & 1); /* = H /L */
+ return;
+ END
+
+ /* 2. 16-Bit-Register ? */
+
+ for (z=0; z<Reg16Cnt; z++)
+ if (strcasecmp(Asc_O,Reg16Names[z])==0)
+ BEGIN
+ AdrMode=ModReg16;
+ if (z<=3) AdrPart=z;
+ else
+ BEGIN
+ BAsmCode[PrefixCnt++]=(z==4)?IXPrefix:IYPrefix;
+ AdrPart=2; /* = HL */
+ END
+ return;
+ END
+
+ /* 3. 16-Bit-Register indirekt ? */
+
+ if ((strlen(Asc_O)>=4) AND (*Asc_O=='(') AND (Asc_O[strlen(Asc_O)-1]==')'))
+ for (z=0; z<Reg16Cnt; z++)
+ if ((strncasecmp(Asc_O+1,Reg16Names[z],2)==0)
+ AND (NOT IsSym(Asc_O[3])))
+ BEGIN
+ if (z<3)
+ BEGIN
+ if (strlen(Asc_O)!=4)
+ BEGIN
+ WrError(1350); return;
+ END
+ switch (z)
+ BEGIN
+ case 0:
+ case 1: /* BC,DE */
+ AdrMode=ModIndReg16; AdrPart=z;
+ break;
+ case 2: /* HL=M-Register */
+ AdrMode=ModReg8; AdrPart=6;
+ break;
+ END
+ END
+ else
+ BEGIN /* SP,IX,IY */
+ strmaxcpy(Asc,Asc_O+3,255); Asc[strlen(Asc)-1]='\0';
+ if (*Asc=='+') strcpy(Asc,Asc+1);
+ AdrLong=EvalIntExpression(Asc,(MomCPU>=CPUZ380)?SInt24:SInt8,&OK);
+ if (OK)
+ BEGIN
+ if (z==3) AdrMode=ModSPRel;
+ else
+ BEGIN
+ AdrMode=ModReg8; AdrPart=6;
+ BAsmCode[PrefixCnt++]=(z==4)?IXPrefix:IYPrefix;
+ END
+ AdrVals[AdrCnt++]=AdrLong & 0xff;
+ if ((AdrLong>=-0x80l) AND (AdrLong<=0x7fl));
+ else
+ BEGIN
+ AdrVals[AdrCnt++]=(AdrLong >> 8) & 0xff;
+ if ((AdrLong>=-0x8000l) AND (AdrLong<=0x7fffl)) ChangeDDPrefix("IB");
+ else
+ BEGIN
+ AdrVals[AdrCnt++]=(AdrLong >> 16) & 0xff;
+ ChangeDDPrefix("IW");
+ END
+ END
+ END
+ END
+ return;
+ END
+
+ /* absolut ? */
+
+ if (IsIndirect(Asc_O))
+ BEGIN
+ AdrLong=EvalAbsAdrExpression(Asc_O,&OK);
+ if (OK)
+ BEGIN
+ ChkSpace(SegCode);
+ AdrMode=ModAbs;
+ AdrVals[0]=AdrLong & 0xff;
+ AdrVals[1]=(AdrLong >> 8) & 0xff;
+ AdrCnt=2;
+#ifdef __STDC__
+ if ((AdrLong & 0xffff0000u)==0);
+#else
+ if ((AdrLong & 0xffff0000)==0);
+#endif
+ else
+ BEGIN
+ AdrVals[AdrCnt++]=((AdrLong >> 16) & 0xff);
+#ifdef __STDC__
+ if ((AdrLong & 0xff000000u)==0) ChangeDDPrefix("IB");
+#else
+ if ((AdrLong & 0xff000000)==0) ChangeDDPrefix("IB");
+#endif
+ else
+ BEGIN
+ AdrVals[AdrCnt++]=((AdrLong >> 24) & 0xff);
+ ChangeDDPrefix("IW");
+ END
+ END
+ END
+ return;
+ END
+
+ /* ...immediate */
+
+ switch (OpSize)
+ BEGIN
+ case 0xff:
+ WrError(1132);
+ break;
+ case 0:
+ AdrVals[0]=EvalIntExpression(Asc_O,Int8,&OK);
+ if (OK)
+ BEGIN
+ AdrMode=ModImm; AdrCnt=1;
+ END;
+ break;
+ case 1:
+ if (InLongMode())
+ BEGIN
+ AdrLong=EvalIntExpression(Asc_O,Int32,&OK);
+ if (OK)
+ BEGIN
+ AdrVals[0]=Lo(AdrLong); AdrVals[1]=Hi(AdrLong);
+ AdrMode=ModImm; AdrCnt=2;
+#ifdef __STDC__
+ if ((AdrLong & 0xffff0000u)==0);
+#else
+ if ((AdrLong & 0xffff0000)==0);
+#endif
+ else
+ BEGIN
+ AdrVals[AdrCnt++]=(AdrLong >> 16) & 0xff;
+#ifdef __STDC__
+ if ((AdrLong & 0xff000000u)==0) ChangeDDPrefix("IB");
+#else
+ if ((AdrLong & 0xff000000)==0) ChangeDDPrefix("IB");
+#endif
+ else
+ BEGIN
+ AdrVals[AdrCnt++]=(AdrLong >> 24) & 0xff;
+ ChangeDDPrefix("IW");
+ END
+ END
+ END
+ END
+ else
+ BEGIN
+ AdrInt=EvalIntExpression(Asc_O,Int16,&OK);
+ if (OK)
+ BEGIN
+ AdrVals[0]=Lo(AdrInt); AdrVals[1]=Hi(AdrInt);
+ AdrMode=ModImm; AdrCnt=2;
+ END
+ END
+ break;
+ END
+END
+
+/*-------------------------------------------------------------------------*/
+/* Bedingung entschluesseln */
+
+ static Boolean DecodeCondition(char *Name, int *Erg)
+BEGIN
+ int z;
+ String Name_N;
+
+ strmaxcpy(Name_N,Name,255); NLS_UpString(Name_N);
+
+ z=0;
+ while ((z<ConditionCnt) AND (strcmp(Conditions[z].Name,Name_N)!=0)) z++;
+ if (z>ConditionCnt) return False;
+ else
+ BEGIN
+ *Erg=Conditions[z].Code; return True;
+ END
+END
+
+/*-------------------------------------------------------------------------*/
+/* Sonderregister dekodieren */
+
+ static Boolean DecodeSFR(char *Inp, Byte *Erg)
+BEGIN
+ if (strcasecmp(Inp,"SR")==0) *Erg=1;
+ else if (strcasecmp(Inp,"XSR")==0) *Erg=5;
+ else if (strcasecmp(Inp,"DSR")==0) *Erg=6;
+ else if (strcasecmp(Inp,"YSR")==0) *Erg=7;
+ else return False;
+ return True;
+END
+
+/*=========================================================================*/
+
+ static Boolean DecodePseudo(void)
+BEGIN
+ if (Memo("PORT"))
+ BEGIN
+ CodeEquate(SegIO,0,PortEnd());
+ return True;
+ END
+
+ /* Kompatibilitaet zum M80 */
+
+ if (Memo("DEFB")) strmaxcpy(OpPart,"DB",255);
+ if (Memo("DEFW")) strmaxcpy(OpPart,"DW",255);
+
+ return False;
+END
+
+ static void DecodeLD(void)
+BEGIN
+ Byte AdrByte,HLen;
+ int z;
+ Byte HVals[5];
+
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if (AdrPart==7) /* LD A,... */
+ BEGIN
+ OpSize=0; DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8: /* LD A,R8/RX8/(HL)/(XY+D) */
+ BAsmCode[PrefixCnt]=0x78+AdrPart;
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ CodeLen=PrefixCnt+1+AdrCnt;
+ break;
+ case ModIndReg16: /* LD A,(BC)/(DE) */
+ BAsmCode[0]=0x0a+(AdrPart << 4); CodeLen=1;
+ break;
+ case ModImm: /* LD A,imm8 */
+ BAsmCode[0]=0x3e; BAsmCode[1]=AdrVals[0]; CodeLen=2;
+ break;
+ case ModAbs: /* LD a,(adr) */
+ BAsmCode[PrefixCnt]=0x3a;
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ CodeLen=PrefixCnt+1+AdrCnt;
+ break;
+ case ModRef: /* LD A,R */
+ BAsmCode[0]=0xed; BAsmCode[1]=0x5f;
+ CodeLen=2;
+ break;
+ case ModInt: /* LD A,I */
+ BAsmCode[0]=0xed; BAsmCode[1]=0x57;
+ CodeLen=2;
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ else if ((AdrPart!=6) AND (PrefixCnt==0)) /* LD R8,... */
+ BEGIN
+ AdrByte=AdrPart; OpSize=0; DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8: /* LD R8,R8/RX8/(HL)/(XY+D) */
+ if (((AdrByte==4) OR (AdrByte==5)) AND (PrefixCnt==1) AND (AdrCnt==0)) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[PrefixCnt]=0x40+(AdrByte << 3)+AdrPart;
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ CodeLen=PrefixCnt+1+AdrCnt;
+ END
+ break;
+ case ModImm: /* LD R8,imm8 */
+ BAsmCode[0]=0x06+(AdrByte << 3); BAsmCode[1]=AdrVals[0];
+ CodeLen=2;
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ else if ((AdrPart==4) OR (AdrPart==5)) /* LD RX8,... */
+ BEGIN
+ AdrByte=AdrPart; OpSize=0; DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8: /* LD RX8,R8/RX8 */
+ if (AdrPart==6) WrError(1350);
+ else if ((AdrPart>=4) AND (AdrPart<=5) AND (PrefixCnt!=2)) WrError(1350);
+ else if ((AdrPart>=4) AND (AdrPart<=5) AND (BAsmCode[0]!=BAsmCode[1])) WrError(1350);
+ else
+ BEGIN
+ if (PrefixCnt==2) PrefixCnt--;
+ BAsmCode[PrefixCnt]=0x40+(AdrByte << 3)+AdrPart;
+ CodeLen=PrefixCnt+1;
+ END
+ break;
+ case ModImm: /* LD RX8,imm8 */
+ BAsmCode[PrefixCnt]=0x06+(AdrByte << 3);
+ BAsmCode[PrefixCnt+1]=AdrVals[0];
+ CodeLen=PrefixCnt+2;
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ else /* LD (HL)/(XY+d),... */
+ BEGIN
+ HLen=AdrCnt; memcpy(HVals,AdrVals,AdrCnt); z=PrefixCnt;
+ if ((z==0) AND (Memo("LDW")))
+ BEGIN
+ OpSize=1; MayLW=True;
+ END
+ else OpSize=0;
+ DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8: /* LD (HL)/(XY+D),R8 */
+ if ((PrefixCnt!=z) OR (AdrPart==6)) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[PrefixCnt]=0x70+AdrPart;
+ memcpy(BAsmCode+PrefixCnt+1,HVals,HLen);
+ CodeLen=PrefixCnt+1+HLen;
+ END
+ break;
+ case ModImm: /* LD (HL)/(XY+D),imm8:16:32 */
+ if ((z==0) AND (Memo("LDW")))
+ if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ BAsmCode[PrefixCnt]=0xed; BAsmCode[PrefixCnt+1]=0x36;
+ memcpy(BAsmCode+PrefixCnt+2,AdrVals,AdrCnt);
+ CodeLen=PrefixCnt+2+AdrCnt;
+ END
+ else
+ BEGIN
+ BAsmCode[PrefixCnt]=0x36;
+ memcpy(BAsmCode+1+PrefixCnt,HVals,HLen);
+ BAsmCode[PrefixCnt+1+HLen]=AdrVals[0];
+ CodeLen=PrefixCnt+1+HLen+AdrCnt;
+ END
+ break;
+ case ModReg16: /* LD (HL)/(XY+D),R16/XY */
+ if (MomCPU<CPUZ380) WrError(1500);
+ else if (AdrPart==3) WrError(1350);
+ else if (HLen==0)
+ if (PrefixCnt==z) /* LD (HL),R16 */
+ BEGIN
+ if (AdrPart==2) AdrPart=3;
+ BAsmCode[0]=0xfd; BAsmCode[1]=0x0f+(AdrPart << 4);
+ CodeLen=2;
+ END
+ else /* LD (HL),XY */
+ BEGIN
+ CodeLen=PrefixCnt+1; BAsmCode[PrefixCnt]=0x31;
+ CodeLen=1+PrefixCnt;
+ END
+ else
+ if (PrefixCnt==z) /* LD (XY+D),R16 */
+ BEGIN
+ if (AdrPart==2) AdrPart=3;
+ BAsmCode[PrefixCnt]=0xcb;
+ memcpy(BAsmCode+PrefixCnt+1,HVals,HLen);
+ BAsmCode[PrefixCnt+1+HLen]=0x0b+(AdrPart << 4);
+ CodeLen=PrefixCnt+1+HLen+1;
+ END
+ else if (BAsmCode[0]==BAsmCode[1]) WrError(1350);
+ else
+ BEGIN
+ PrefixCnt--;
+ BAsmCode[PrefixCnt]=0xcb;
+ memcpy(BAsmCode+PrefixCnt+1,HVals,HLen);
+ BAsmCode[PrefixCnt+1+HLen]=0x2b;
+ CodeLen=PrefixCnt+1+HLen+1;
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ break;
+ case ModReg16:
+ if (AdrPart==3) /* LD SP,... */
+ BEGIN
+ OpSize=1; MayLW=True; DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg16: /* LD SP,HL/XY */
+ if (AdrPart!=2) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[PrefixCnt]=0xf9; CodeLen=PrefixCnt+1;
+ END
+ break;
+ case ModImm: /* LD SP,imm16:32 */
+ BAsmCode[PrefixCnt]=0x31;
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ CodeLen=PrefixCnt+1+AdrCnt;
+ break;
+ case ModAbs: /* LD SP,(adr) */
+ BAsmCode[PrefixCnt]=0xed; BAsmCode[PrefixCnt+1]=0x7b;
+ memcpy(BAsmCode+PrefixCnt+2,AdrVals,AdrCnt);
+ CodeLen=PrefixCnt+2+AdrCnt;
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ else if (PrefixCnt==0) /* LD R16,... */
+ BEGIN
+ AdrByte=(AdrPart==2) ? 3 : AdrPart;
+ OpSize=1; MayLW=True; DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModInt: /* LD HL,I */
+ if (MomCPU<CPUZ380) WrError(1500);
+ else if (AdrByte!=3) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0xdd; BAsmCode[1]=0x57; CodeLen=2;
+ END
+ break;
+ case ModReg8:
+ if (AdrPart!=6) WrError(1350);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else if (PrefixCnt==0) /* LD R16,(HL) */
+ BEGIN
+ BAsmCode[0]=0xdd; BAsmCode[1]=0x0f+(AdrByte << 4);
+ CodeLen=2;
+ END
+ else /* LD R16,(XY+d) */
+ BEGIN
+ BAsmCode[PrefixCnt]=0xcb;
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ BAsmCode[PrefixCnt+1+AdrCnt]=0x03+(AdrByte << 4);
+ CodeLen=PrefixCnt+1+AdrCnt+1;
+ END
+ break;
+ case ModReg16:
+ if (AdrPart==3) WrError(1350);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else if (PrefixCnt==0) /* LD R16,R16 */
+ BEGIN
+ if (AdrPart==2) AdrPart=3;
+ else if (AdrPart==0) AdrPart=2;
+ BAsmCode[0]=0xcd+(AdrPart << 4);
+ BAsmCode[1]=0x02+(AdrByte << 4);
+ CodeLen=2;
+ END
+ else /* LD R16,XY */
+ BEGIN
+ BAsmCode[PrefixCnt]=0x0b+(AdrByte << 4);
+ CodeLen=PrefixCnt+1;
+ END
+ break;
+ case ModIndReg16: /* LD R16,(R16) */
+ if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ CodeLen=2; BAsmCode[0]=0xdd;
+ BAsmCode[1]=0x0c+(AdrByte << 4)+AdrPart;
+ END
+ break;
+ case ModImm: /* LD R16,imm */
+ if (AdrByte==3) AdrByte=2;
+ CodeLen=PrefixCnt+1+AdrCnt;
+ BAsmCode[PrefixCnt]=0x01+(AdrByte << 4);
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ break;
+ case ModAbs: /* LD R16,(adr) */
+ if (AdrByte==3)
+ BEGIN
+ BAsmCode[PrefixCnt]=0x2a;
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ CodeLen=1+PrefixCnt+AdrCnt;
+ END
+ else
+ BEGIN
+ BAsmCode[PrefixCnt]=0xed;
+ BAsmCode[PrefixCnt+1]=0x4b+(AdrByte << 4);
+ memcpy(BAsmCode+PrefixCnt+2,AdrVals,AdrCnt);
+ CodeLen=PrefixCnt+2+AdrCnt;
+ END
+ break;
+ case ModSPRel: /* LD R16,(SP+D) */
+ if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ BAsmCode[PrefixCnt]=0xdd;
+ BAsmCode[PrefixCnt+1]=0xcb;
+ memcpy(BAsmCode+PrefixCnt+2,AdrVals,AdrCnt);
+ BAsmCode[PrefixCnt+2+AdrCnt]=0x01+(AdrByte << 4);
+ CodeLen=PrefixCnt+3+AdrCnt;
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ else /* LD XY,... */
+ BEGIN
+ OpSize=1; MayLW=True; DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if (AdrPart!=6) WrError(1350);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else if (AdrCnt==0) /* LD XY,(HL) */
+ BEGIN
+ BAsmCode[PrefixCnt]=0x33; CodeLen=PrefixCnt+1;
+ END
+ else if (BAsmCode[0]==BAsmCode[1]) WrError(1350);
+ else /* LD XY,(XY+D) */
+ BEGIN
+ BAsmCode[0]=BAsmCode[1]; PrefixCnt--;
+ BAsmCode[PrefixCnt]=0xcb;
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ BAsmCode[PrefixCnt+1+AdrCnt]=0x23;
+ CodeLen=PrefixCnt+1+AdrCnt+1;
+ END
+ break;
+ case ModReg16:
+ if (MomCPU<CPUZ380) WrError(1500);
+ else if (AdrPart==3) WrError(1350);
+ else if (PrefixCnt==1) /* LD XY,R16 */
+ BEGIN
+ if (AdrPart==2) AdrPart=3;
+ CodeLen=1+PrefixCnt;
+ BAsmCode[PrefixCnt]=0x07+(AdrPart << 4);
+ END
+ else if (BAsmCode[0]==BAsmCode[1]) WrError(1350);
+ else /* LD XY,XY */
+ BEGIN
+ BAsmCode[--PrefixCnt]=0x27;
+ CodeLen=1+PrefixCnt;
+ END
+ break;
+ case ModIndReg16:
+ if (MomCPU<CPUZ380) WrError(1500);
+ else /* LD XY,(R16) */
+ BEGIN
+ BAsmCode[PrefixCnt]=0x03+(AdrPart << 4);
+ CodeLen=PrefixCnt+1;
+ END
+ break;
+ case ModImm: /* LD XY,imm16:32 */
+ BAsmCode[PrefixCnt]=0x21;
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ CodeLen=PrefixCnt+1+AdrCnt;
+ break;
+ case ModAbs: /* LD XY,(adr) */
+ BAsmCode[PrefixCnt]=0x2a;
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ CodeLen=PrefixCnt+1+AdrCnt;
+ break;
+ case ModSPRel: /* LD XY,(SP+D) */
+ if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ BAsmCode[PrefixCnt]=0xcb;
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ BAsmCode[PrefixCnt+1+AdrCnt]=0x21;
+ CodeLen=PrefixCnt+1+AdrCnt+1;
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ break;
+ case ModIndReg16:
+ AdrByte=AdrPart;
+ if (Memo("LDW"))
+ BEGIN
+ OpSize=1; MayLW=True;
+ END
+ else OpSize=0;
+ DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8: /* LD (R16),A */
+ if (AdrPart!=7) WrError(1350);
+ else
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0x02+(AdrByte << 4);
+ END
+ break;
+ case ModReg16:
+ if (AdrPart==3) WrError(1350);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else if (PrefixCnt==0) /* LD (R16),R16 */
+ BEGIN
+ if (AdrPart==2) AdrPart=3;
+ BAsmCode[0]=0xfd; BAsmCode[1]=0x0c+AdrByte+(AdrPart << 4);
+ CodeLen=2;
+ END
+ else /* LD (R16),XY */
+ BEGIN
+ BAsmCode[PrefixCnt]=0x01+(AdrByte << 4);
+ CodeLen=PrefixCnt+1;
+ END
+ break;
+ case ModImm:
+ if (NOT Memo("LDW")) WrError(1350);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ BAsmCode[PrefixCnt]=0xed;
+ BAsmCode[PrefixCnt+1]=0x06+(AdrByte << 4);
+ memcpy(BAsmCode+PrefixCnt+2,AdrVals,AdrCnt);
+ CodeLen=PrefixCnt+2+AdrCnt;
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ break;
+ case ModAbs:
+ HLen=AdrCnt; memcpy(HVals,AdrVals,AdrCnt);
+ OpSize=0; DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8: /* LD (adr),A */
+ if (AdrPart!=7) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[PrefixCnt]=0x32;
+ memcpy(BAsmCode+PrefixCnt+1,HVals,HLen);
+ CodeLen=PrefixCnt+1+HLen;
+ END
+ break;
+ case ModReg16:
+ if (AdrPart==2) /* LD (adr),HL/XY */
+ BEGIN
+ BAsmCode[PrefixCnt]=0x22;
+ memcpy(BAsmCode+PrefixCnt+1,HVals,HLen);
+ CodeLen=PrefixCnt+1+HLen;
+ END
+ else /* LD (adr),R16 */
+ BEGIN
+ BAsmCode[PrefixCnt]=0xed;
+ BAsmCode[PrefixCnt+1]=0x43+(AdrPart << 4);
+ memcpy(BAsmCode+PrefixCnt+2,HVals,HLen);
+ CodeLen=PrefixCnt+2+HLen;
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ break;
+ case ModInt:
+ if (strcasecmp(ArgStr[2],"A")==0) /* LD I,A */
+ BEGIN
+ CodeLen=2; BAsmCode[0]=0xed; BAsmCode[1]=0x47;
+ END
+ else if (strcasecmp(ArgStr[2],"HL")==0) /* LD I,HL */
+ if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ CodeLen=2; BAsmCode[0]=0xdd; BAsmCode[1]=0x47;
+ END
+ else WrError(1350);
+ break;
+ case ModRef:
+ if (strcasecmp(ArgStr[2],"A")==0) /* LD R,A */
+ BEGIN
+ CodeLen=2; BAsmCode[0]=0xed; BAsmCode[1]=0x4f;
+ END
+ else WrError(1350);
+ break;
+ case ModSPRel:
+ if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ HLen=AdrCnt; memcpy(HVals,AdrVals,AdrCnt);
+ OpSize=0; DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg16:
+ if (AdrPart==3) WrError(1350);
+ else if (PrefixCnt==0) /* LD (SP+D),R16 */
+ BEGIN
+ if (AdrPart==2) AdrPart=3;
+ BAsmCode[PrefixCnt]=0xdd;
+ BAsmCode[PrefixCnt+1]=0xcb;
+ memcpy(BAsmCode+PrefixCnt+2,HVals,HLen);
+ BAsmCode[PrefixCnt+2+HLen]=0x09+(AdrPart << 4);
+ CodeLen=PrefixCnt+2+HLen+1;
+ END
+ else /* LD (SP+D),XY */
+ BEGIN
+ BAsmCode[PrefixCnt]=0xcb;
+ memcpy(BAsmCode+PrefixCnt+1,HVals,HLen);
+ BAsmCode[PrefixCnt+1+HLen]=0x29;
+ CodeLen=PrefixCnt+1+HLen+1;
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END /* outer switch */
+ END
+END
+
+ static Boolean ParPair(char *Name1, char *Name2)
+BEGIN
+ return (((strcasecmp(ArgStr[1],Name1)==0) AND (strcasecmp(ArgStr[2],Name2)==0)) OR
+ ((strcasecmp(ArgStr[1],Name2)==0) AND (strcasecmp(ArgStr[2],Name1)==0)));
+END
+
+ static Boolean ImmIs8(void)
+BEGIN
+ Word tmp;
+
+ if (AdrCnt<2) return True;
+
+ tmp=(Word) AdrVals[AdrCnt-2];
+
+ return ((tmp<=255) OR (tmp>=0xff80));
+END
+
+ static Boolean CodeAri(void)
+BEGIN
+ int z;
+ Byte AdrByte;
+ Boolean OK;
+
+ for (z=0; z<ALUOrderCnt; z++)
+ if (Memo(ALUOrders[z].Name))
+ BEGIN
+ if (ArgCnt==1)
+ BEGIN
+ strcpy(ArgStr[2],ArgStr[1]); strmaxcpy(ArgStr[1],"A",255); ArgCnt=2;
+ END
+ if (ArgCnt!=2) WrError(1110);
+ else if (strcasecmp(ArgStr[1],"HL")==0)
+ BEGIN
+ if (NOT Memo("SUB")) WrError(1350);
+ else
+ BEGIN
+ OpSize=1; DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModAbs:
+ BAsmCode[PrefixCnt]=0xed; BAsmCode[PrefixCnt+1]=0xd6;
+ memcpy(BAsmCode+PrefixCnt+2,AdrVals,AdrCnt);
+ CodeLen=PrefixCnt+2+AdrCnt;
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ END
+ else if (strcasecmp(ArgStr[1],"SP")==0)
+ BEGIN
+ if (NOT Memo("SUB")) WrError(1350);
+ else
+ BEGIN
+ OpSize=1; DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModImm:
+ BAsmCode[0]=0xed; BAsmCode[1]=0x92;
+ memcpy(BAsmCode+2,AdrVals,AdrCnt);
+ CodeLen=2+AdrCnt;
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ END
+ else if (strcasecmp(ArgStr[1],"A")!=0) WrError(1350);
+ else
+ BEGIN
+ OpSize=0; DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ CodeLen=PrefixCnt+1+AdrCnt;
+ BAsmCode[PrefixCnt]=0x80+(ALUOrders[z].Code << 3)+AdrPart;
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ break;
+ case ModImm:
+ if (NOT ImmIs8()) WrError(1320);
+ else
+ BEGIN
+ CodeLen=2;
+ BAsmCode[0]=0xc6+(ALUOrders[z].Code << 3);
+ BAsmCode[1]=AdrVals[0];
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ return True;
+ END
+ else if ((strncmp(ALUOrders[z].Name,OpPart,strlen(ALUOrders[z].Name))==0) AND (OpPart[strlen(OpPart)-1]=='W'))
+ BEGIN
+ if ((ArgCnt!=2) AND (ArgCnt!=1)) WrError(1110);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else if ((ArgCnt==2) AND (strcasecmp(ArgStr[1],"HL")!=0)) WrError(1350);
+ else
+ BEGIN
+ OpSize=1; DecodeAdr(ArgStr[ArgCnt]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg16:
+ if (PrefixCnt>0) /* wenn Register, dann nie DDIR! */
+ BEGIN
+ BAsmCode[PrefixCnt]=0x87+(ALUOrders[z].Code << 3);
+ CodeLen=1+PrefixCnt;
+ END
+ else if (AdrPart==3) WrError(1350);
+ else
+ BEGIN
+ if (AdrPart==2) AdrPart=3;
+ BAsmCode[0]=0xed; BAsmCode[1]=0x84+(ALUOrders[z].Code << 3)+AdrPart;
+ CodeLen=2;
+ END
+ break;
+ case ModReg8:
+ if ((AdrPart!=6) OR (AdrCnt==0)) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[PrefixCnt]=0xc6+(ALUOrders[z].Code << 3);
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ CodeLen=PrefixCnt+1+AdrCnt;
+ END
+ break;
+ case ModImm:
+ BAsmCode[0]=0xed; BAsmCode[1]=0x86+(ALUOrders[z].Code << 3);
+ memcpy(BAsmCode+2,AdrVals,AdrCnt); CodeLen=2+AdrCnt;
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ return True;
+ END
+
+ if (Memo("ADD"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if (AdrPart!=7) WrError(1350);
+ else
+ BEGIN
+ OpSize=0; DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ CodeLen=PrefixCnt+1+AdrCnt;
+ BAsmCode[PrefixCnt]=0x80+AdrPart;
+ memcpy(BAsmCode+1+PrefixCnt,AdrVals,AdrCnt);
+ break;
+ case ModImm:
+ CodeLen=PrefixCnt+1+AdrCnt;
+ BAsmCode[PrefixCnt]=0xc6;
+ memcpy(BAsmCode+1+PrefixCnt,AdrVals,AdrCnt);
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ break;
+ case ModReg16:
+ if (AdrPart==3) /* SP */
+ BEGIN
+ OpSize=1; DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModImm:
+ if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ BAsmCode[0]=0xed; BAsmCode[1]=0x82;
+ memcpy(BAsmCode+2,AdrVals,AdrCnt);
+ CodeLen=2+AdrCnt;
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ else if (AdrPart!=2) WrError(1350);
+ else
+ BEGIN
+ z=PrefixCnt; /* merkt, ob Indexregister */
+ OpSize=1; DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg16:
+ if ((AdrPart==2) AND (PrefixCnt!=0) AND ((PrefixCnt!=2) OR (BAsmCode[0]!=BAsmCode[1]))) WrError(1350);
+ else
+ BEGIN
+ if (PrefixCnt==2) PrefixCnt--; CodeLen=1+PrefixCnt;
+ BAsmCode[PrefixCnt]=0x09+(AdrPart << 4);
+ END
+ break;
+ case ModAbs:
+ if (z!=0) WrError(1350);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ BAsmCode[PrefixCnt]=0xed; BAsmCode[PrefixCnt+1]=0xc2;
+ memcpy(BAsmCode+PrefixCnt+2,AdrVals,AdrCnt);
+ CodeLen=PrefixCnt+2+AdrCnt;
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ return True;
+ END
+
+ if (Memo("ADDW"))
+ BEGIN
+ if ((ArgCnt!=2) AND (ArgCnt!=1)) WrError(1110);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else if ((ArgCnt==2) AND (strcasecmp(ArgStr[1],"HL")!=0)) WrError(1350);
+ else
+ BEGIN
+ OpSize=1; DecodeAdr(ArgStr[ArgCnt]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg16:
+ if (PrefixCnt>0) /* wenn Register, dann nie DDIR! */
+ BEGIN
+ BAsmCode[PrefixCnt]=0x87;
+ CodeLen=1+PrefixCnt;
+ END
+ else if (AdrPart==3) WrError(1350);
+ else
+ BEGIN
+ if (AdrPart==2) AdrPart=3;
+ BAsmCode[0]=0xed; BAsmCode[1]=0x84+AdrPart;
+ CodeLen=2;
+ END
+ break;
+ case ModReg8:
+ if ((AdrPart!=6) OR (AdrCnt==0)) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[PrefixCnt]=0xc6;
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ CodeLen=PrefixCnt+1+AdrCnt;
+ END
+ break;
+ case ModImm:
+ BAsmCode[0]=0xed; BAsmCode[1]=0x86;
+ memcpy(BAsmCode+2,AdrVals,AdrCnt); CodeLen=2+AdrCnt;
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ return True;
+ END
+
+ if ((Memo("ADC")) OR (Memo("SBC")))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if (AdrPart!=7) WrError(1350);
+ else
+ BEGIN
+ OpSize=0; DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ CodeLen=PrefixCnt+1+AdrCnt;
+ BAsmCode[PrefixCnt]=0x88+AdrPart;
+ memcpy(BAsmCode+1+PrefixCnt,AdrVals,AdrCnt);
+ break;
+ case ModImm:
+ CodeLen=PrefixCnt+1+AdrCnt;
+ BAsmCode[PrefixCnt]=0xce;
+ memcpy(BAsmCode+1+PrefixCnt,AdrVals,AdrCnt);
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ if ((Memo("SBC")) AND (CodeLen!=0)) BAsmCode[PrefixCnt]+=0x10;
+ END
+ break;
+ case ModReg16:
+ if ((AdrPart!=2) OR (PrefixCnt!=0)) WrError(1350);
+ else
+ BEGIN
+ OpSize=1; DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg16:
+ if (PrefixCnt!=0) WrError(1350);
+ else
+ BEGIN
+ CodeLen=2; BAsmCode[0]=0xed;
+ BAsmCode[1]=0x42+(AdrPart << 4);
+ if (Memo("ADC")) BAsmCode[1]+=8;
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ return True;
+ END
+
+ if ((Memo("ADCW")) OR (Memo("SBCW")))
+ BEGIN
+ if ((ArgCnt!=2) AND (ArgCnt!=1)) WrError(1110);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else if ((ArgCnt==2) AND (strcasecmp(ArgStr[1],"HL")!=0)) WrError(1350);
+ else
+ BEGIN
+ z=Ord(Memo("SBCW")) << 4;
+ OpSize=1; DecodeAdr(ArgStr[ArgCnt]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg16:
+ if (PrefixCnt>0) /* wenn Register, dann nie DDIR! */
+ BEGIN
+ BAsmCode[PrefixCnt]=0x8f+z;
+ CodeLen=1+PrefixCnt;
+ END
+ else if (AdrPart==3) WrError(1350);
+ else
+ BEGIN
+ if (AdrPart==2) AdrPart=3;
+ BAsmCode[0]=0xed; BAsmCode[1]=0x8c+z+AdrPart;
+ CodeLen=2;
+ END
+ break;
+ case ModReg8:
+ if ((AdrPart!=6) OR (AdrCnt==0)) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[PrefixCnt]=0xce + z; /* ANSI :-0 */
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ CodeLen=PrefixCnt+1+AdrCnt;
+ END
+ break;
+ case ModImm:
+ BAsmCode[0]=0xed; BAsmCode[1]=0x8e + z;
+ memcpy(BAsmCode+2,AdrVals,AdrCnt); CodeLen=2+AdrCnt;
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ return True;
+ END
+
+ if ((Memo("INC")) OR (Memo("DEC")) OR (Memo("INCW")) OR (Memo("DECW")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ z=Ord((Memo("DEC")) OR (Memo("DECW")));
+ DecodeAdr(ArgStr[1]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if (OpPart[strlen(OpPart)-1]=='W') WrError(1350);
+ else
+ BEGIN
+ CodeLen=PrefixCnt+1+AdrCnt;
+ BAsmCode[PrefixCnt]=0x04+(AdrPart << 3)+z;
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ END
+ break;
+ case ModReg16:
+ CodeLen=1+PrefixCnt;
+ BAsmCode[PrefixCnt]=0x03+(AdrPart << 4)+(z << 3);
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ return True;
+ END
+
+ for (z=0; z<ShiftOrderCnt; z++)
+ if (Memo(ShiftOrders[z]))
+ BEGIN
+ if ((ArgCnt==0) OR (ArgCnt>2)) WrError(1110);
+ else if ((z==6) AND (MomCPU!=CPUZ80U)) WrError(1500); /* SLIA undok. Z80 */
+ else
+ BEGIN
+ OpSize=0;
+ DecodeAdr(ArgStr[ArgCnt]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if ((PrefixCnt>0) AND (AdrPart!=6)) WrError(1350); /* IXL..IYU verbieten */
+ else
+ BEGIN
+ if (ArgCnt==1) OK=True;
+ else if (MomCPU!=CPUZ80U)
+ BEGIN
+ WrError(1500); OK=False;
+ END
+ else if ((AdrPart!=6) OR (PrefixCnt!=1) OR (NOT DecodeReg8(ArgStr[1],&AdrPart)))
+ BEGIN
+ WrError(1350); OK=False;
+ END
+ else OK=True;
+ if (OK)
+ BEGIN
+ CodeLen=PrefixCnt+1+AdrCnt+1;
+ BAsmCode[PrefixCnt]=0xcb;
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ BAsmCode[PrefixCnt+1+AdrCnt]=AdrPart+(z << 3);
+ if ((AdrPart==7) AND (z<4)) WrError(10);
+ END
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ return True;
+ END
+ else if ((strncmp(OpPart,ShiftOrders[z],strlen(ShiftOrders[z]))==0) AND (OpPart[strlen(OpPart)-1]=='W'))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if ((MomCPU<CPUZ380) OR (z==6)) WrError(1500);
+ else
+ BEGIN
+ OpSize=1; DecodeAdr(ArgStr[1]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg16:
+ if (PrefixCnt>0)
+ BEGIN
+ BAsmCode[2]=0x04+(z << 3)+((BAsmCode[0] >> 5) & 1);
+ BAsmCode[0]=0xed; BAsmCode[1]=0xcb;
+ CodeLen=3;
+ END
+ else if (AdrPart==3) WrError(1350);
+ else
+ BEGIN
+ if (AdrPart==2) AdrPart=3;
+ BAsmCode[0]=0xed; BAsmCode[1]=0xcb;
+ BAsmCode[2]=(z << 3)+AdrPart;
+ CodeLen=3;
+ END
+ break;
+ case ModReg8:
+ if (AdrPart!=6) WrError(1350);
+ else
+ BEGIN
+ if (AdrCnt==0)
+ BEGIN
+ BAsmCode[0]=0xed; PrefixCnt=1;
+ END
+ BAsmCode[PrefixCnt]=0xcb;
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ BAsmCode[PrefixCnt+1+AdrCnt]=0x02+(z << 3);
+ CodeLen=PrefixCnt+1+AdrCnt+1;
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ return True;
+ END
+
+ for (z=0; z<BitOrderCnt; z++)
+ if (Memo(BitOrders[z]))
+ BEGIN
+ if ((ArgCnt!=2) AND (ArgCnt!=3)) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[ArgCnt]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if ((AdrPart!=6) AND (PrefixCnt!=0)) WrError(1350);
+ else
+ BEGIN
+ AdrByte=EvalIntExpression(ArgStr[ArgCnt-1],UInt3,&OK);
+ if (OK)
+ BEGIN
+ if (ArgCnt==2) OK=True;
+ else if (MomCPU!=CPUZ80U)
+ BEGIN
+ WrError(1500); OK=False;
+ END
+ else if ((AdrPart!=6) OR (PrefixCnt!=1) OR (z==0) OR (NOT DecodeReg8(ArgStr[1],&AdrPart)))
+ BEGIN
+ WrError(1350); OK=False;
+ END
+ else OK=True;
+ if (OK)
+ BEGIN
+ CodeLen=PrefixCnt+2+AdrCnt;
+ BAsmCode[PrefixCnt]=0xcb;
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ BAsmCode[PrefixCnt+1+AdrCnt]=AdrPart+(AdrByte << 3)+((z+1) << 6);
+ END
+ END
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ return True;
+ END
+
+ if (Memo("MLT"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (MomCPU<CPUZ180) WrError(1500);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1]);
+ if ((AdrMode!=ModReg16) OR (PrefixCnt!=0)) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[CodeLen]=0xed; BAsmCode[CodeLen+1]=0x4c+(AdrPart << 4);
+ CodeLen=2;
+ END
+ END
+ return True;
+ END
+
+ if ((Memo("DIVUW")) OR (Memo("MULTW")) OR (Memo("MULTUW")))
+ BEGIN
+ if (ArgCnt==1)
+ BEGIN
+ strcpy(ArgStr[2],ArgStr[1]); strmaxcpy(ArgStr[1],"HL",255); ArgCnt=2;
+ END
+ if (MomCPU<CPUZ380) WrError(1500);
+ else if (ArgCnt!=2) WrError(1110);
+ else if (strcasecmp(ArgStr[1],"HL")!=0) WrError(1350);
+ else
+ BEGIN
+ AdrByte=Ord(*OpPart=='D');
+ z=Ord(OpPart[strlen(OpPart)-2]=='U');
+ OpSize=1; DecodeAdr(ArgStr[ArgCnt]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if ((AdrPart!=6) OR (PrefixCnt==0)) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[PrefixCnt]=0xcb;
+ memcpy(BAsmCode+PrefixCnt+1,AdrVals,AdrCnt);
+ BAsmCode[PrefixCnt+1+AdrCnt]=0x92+(z << 3)+(AdrByte << 5);
+ CodeLen=PrefixCnt+1+AdrCnt+1;
+ END
+ break;
+ case ModReg16:
+ if (AdrPart==3) WrError(1350);
+ else if (PrefixCnt==0)
+ BEGIN
+ if (AdrPart==2) AdrPart=3;
+ BAsmCode[0]=0xed; BAsmCode[1]=0xcb;
+ BAsmCode[2]=0x90+AdrPart+(z << 3)+(AdrByte << 5);
+ CodeLen=3;
+ END
+ else
+ BEGIN
+ BAsmCode[2]=0x94+((BAsmCode[0] >> 5) & 1)+(z << 3)+(AdrByte << 5);
+ BAsmCode[0]=0xed; BAsmCode[1]=0xcb;
+ CodeLen=3;
+ END
+ break;
+ case ModImm:
+ BAsmCode[0]=0xed; BAsmCode[1]=0xcb;
+ BAsmCode[2]=0x97+(z << 3)+(AdrByte << 5);
+ memcpy(BAsmCode+3,AdrVals,AdrCnt);
+ CodeLen=3+AdrCnt;
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ return True;
+ END
+
+ if (Memo("TST"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (MomCPU<CPUZ180) WrError(1500);
+ else
+ BEGIN
+ OpSize=0; DecodeAdr(ArgStr[1]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if (PrefixCnt!=0) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0xed; BAsmCode[1]=4+(AdrPart << 3);
+ CodeLen=2;
+ END
+ break;
+ case ModImm:
+ BAsmCode[0]=0xed; BAsmCode[1]=0x64; BAsmCode[2]=AdrVals[0];
+ CodeLen=3;
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ return True;
+ END
+
+ if (Memo("SWAP"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg16:
+ if (AdrPart==3) WrError(1350);
+ else if (PrefixCnt==0)
+ BEGIN
+ if (AdrPart==2) AdrPart=3;
+ BAsmCode[0]=0xed; BAsmCode[1]=0x0e + (AdrPart << 4); /*?*/
+ CodeLen=2;
+ END
+ else
+ BEGIN
+ BAsmCode[PrefixCnt]=0x3e; CodeLen=PrefixCnt+1;
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ return True;
+ END
+
+ return False;
+END
+
+ static void MakeCode_Z80(void)
+BEGIN
+ Boolean OK;
+ LongWord AdrLong;
+ LongInt AdrLInt;
+ Byte AdrByte;
+ int z;
+
+ CodeLen=0; DontPrint=False; PrefixCnt=0; OpSize=0xff; MayLW=False;
+
+ /* zu ignorierendes */
+
+ if (Memo("")) return;
+
+ /* Pseudoanweisungen */
+
+ if (DecodePseudo()) return;
+
+ /* letzten Praefix umkopieren */
+
+ LastPrefix=CurrPrefix; CurrPrefix=Pref_IN_N;
+
+ /* evtl. Datenablage */
+
+ if (DecodeIntelPseudo(False)) return;
+
+/*--------------------------------------------------------------------------*/
+/* Instruktionspraefix */
+
+ if (Memo("DDIR"))
+ BEGIN
+ if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ OK=True;
+ for (z=1; z<=ArgCnt; z++)
+ if (OK)
+ BEGIN
+ NLS_UpString(ArgStr[z]);
+ OK=ExtendPrefix(&CurrPrefix,ArgStr[z]);
+ if (NOT OK) WrError(1135);
+ END
+ if (OK)
+ BEGIN
+ GetPrefixCode(CurrPrefix,BAsmCode+0,BAsmCode+1);
+ CodeLen=2;
+ END
+ END
+ return;
+ END
+
+/*--------------------------------------------------------------------------*/
+/* mit Sicherheit am haeufigsten... */
+
+ if ((Memo("LD")) OR (Memo("LDW")))
+ BEGIN
+ DecodeLD();
+ return;
+ END
+
+/*--------------------------------------------------------------------------*/
+/* ohne Operanden */
+
+ for (z=0; z<FixedOrderCnt; z++)
+ if (Memo(FixedOrders[z].Name))
+ BEGIN
+ if (ArgCnt!=0) WrError(1110);
+ else if (MomCPU<FixedOrders[z].MinCPU) WrError(1500);
+ else
+ BEGIN
+ if ((CodeLen=FixedOrders[z].Len)==2)
+ BEGIN
+ BAsmCode[0]=Hi(FixedOrders[z].Code);
+ BAsmCode[1]=Lo(FixedOrders[z].Code);
+ END
+ else BAsmCode[0]=Lo(FixedOrders[z].Code);
+ END;
+ return;
+ END
+
+ /* nur Akku zugelassen */
+
+ for (z=0; z<AccOrderCnt; z++)
+ if (Memo(AccOrders[z].Name))
+ BEGIN
+ if (ArgCnt==0)
+ BEGIN
+ ArgCnt=1; strmaxcpy(ArgStr[1],"A",255);
+ END
+ if (ArgCnt!=1) WrError(1110);
+ else if (strcasecmp(ArgStr[1],"A")!=0) WrError(1350);
+ else if (MomCPU<AccOrders[z].MinCPU) WrError(1500);
+ else
+ BEGIN
+ if ((CodeLen=AccOrders[z].Len)==2)
+ BEGIN
+ BAsmCode[0]=Hi(AccOrders[z].Code);
+ BAsmCode[1]=Lo(AccOrders[z].Code);
+ END
+ else BAsmCode[0]=Lo(AccOrders[z].Code);
+ END
+ return;
+ END
+
+ for (z=0; z<HLOrderCnt; z++)
+ if (Memo(HLOrders[z].Name))
+ BEGIN
+ if (ArgCnt==0)
+ BEGIN
+ ArgCnt=1; strmaxcpy(ArgStr[1],"HL",255);
+ END;
+ if (ArgCnt!=1) WrError(1110);
+ else if (strcasecmp(ArgStr[1],"HL")!=0) WrError(1350);
+ else if (MomCPU<HLOrders[z].MinCPU) WrError(1500);
+ else
+ BEGIN
+ if ((CodeLen=HLOrders[z].Len)==2)
+ BEGIN
+ BAsmCode[0]=Hi(HLOrders[z].Code);
+ BAsmCode[1]=Lo(HLOrders[z].Code);
+ END
+ else BAsmCode[0]=Lo(HLOrders[z].Code);
+ END
+ return;
+ END
+
+/*-------------------------------------------------------------------------*/
+/* Datentransfer */
+
+ if ((Memo("PUSH")) OR (Memo("POP")))
+ BEGIN
+ z=Ord(Memo("PUSH")) << 2;
+ if (ArgCnt!=1) WrError(1110);
+ else if (strcasecmp(ArgStr[1],"SR")==0)
+ if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ CodeLen=2; BAsmCode[0]=0xed; BAsmCode[1]=0xc1+z;
+ END
+ else
+ BEGIN
+ if (strcasecmp(ArgStr[1],"SP")==0) strmaxcpy(ArgStr[1],"A",255);
+ if (strcasecmp(ArgStr[1],"AF")==0) strmaxcpy(ArgStr[1],"SP",255);
+ OpSize=1; MayLW=True;
+ DecodeAdr(ArgStr[1]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg16:
+ CodeLen=1+PrefixCnt;
+ BAsmCode[PrefixCnt]=0xc1+(AdrPart << 4)+z;
+ break;
+ case ModImm:
+ if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ BAsmCode[PrefixCnt]=0xfd; BAsmCode[PrefixCnt+1]=0xf5;
+ memcpy(BAsmCode+PrefixCnt+2,AdrVals,AdrCnt);
+ CodeLen=PrefixCnt+2+AdrCnt;
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ return;
+ END
+
+ if (Memo("EX"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (ParPair("DE","HL"))
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0xeb;
+ END
+ else if (ParPair("AF","AF\'"))
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0x08;
+ END
+ else if (ParPair("AF","AF`"))
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0x08;
+ END
+ else if (ParPair("(SP)","HL"))
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0xe3;
+ END
+ else if (ParPair("(SP)","IX"))
+ BEGIN
+ CodeLen=2; BAsmCode[0]=IXPrefix; BAsmCode[1]=0xe3;
+ END
+ else if (ParPair("(SP)","IY"))
+ BEGIN
+ CodeLen=2; BAsmCode[0]=IYPrefix; BAsmCode[1]=0xe3;
+ END
+ else if (ParPair("(HL)","A"))
+ BEGIN
+ if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ CodeLen=2; BAsmCode[0]=0xed; BAsmCode[1]=0x37;
+ END
+ END
+ else
+ BEGIN
+ if (ArgStr[2][strlen(ArgStr[2])-1]=='\'')
+ BEGIN
+ OK=True; ArgStr[2][strlen(ArgStr[2])-1]='\0';
+ END
+ else OK=False;
+ DecodeAdr(ArgStr[1]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if ((AdrPart==6) OR (PrefixCnt!=0)) WrError(1350);
+ else
+ BEGIN
+ AdrByte=AdrPart;
+ DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if ((AdrPart==6) OR (PrefixCnt!=0)) WrError(1350);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else if ((AdrByte==7) AND (NOT OK))
+ BEGIN
+ BAsmCode[0]=0xed; BAsmCode[1]=0x07+(AdrPart << 3);
+ CodeLen=2;
+ END
+ else if ((AdrPart==7) AND (NOT OK))
+ BEGIN
+ BAsmCode[0]=0xed; BAsmCode[1]=0x07+(AdrByte << 3);
+ CodeLen=2;
+ END
+ else if ((OK) AND (AdrPart==AdrByte))
+ BEGIN
+ BAsmCode[0]=0xcb; BAsmCode[1]=0x30+AdrPart;
+ CodeLen=2;
+ END
+ else WrError(1350);
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ break;
+ case ModReg16:
+ if (AdrPart==3) WrError(1350);
+ else if (PrefixCnt==0) /* EX R16,... */
+ BEGIN
+ if (AdrPart==2) AdrByte=3; else AdrByte=AdrPart;
+ DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg16:
+ if (AdrPart==3) WrError(1350);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else if (OK)
+ BEGIN
+ if (AdrPart==2) AdrPart=3;
+ if ((PrefixCnt!=0) OR (AdrPart!=AdrByte)) WrError(1350);
+ else
+ BEGIN
+ CodeLen=3; BAsmCode[0]=0xed; BAsmCode[1]=0xcb;
+ BAsmCode[2]=0x30+AdrByte;
+ END
+ END
+ else if (PrefixCnt==0)
+ BEGIN
+ if (AdrByte==0)
+ BEGIN
+ if (AdrPart==2) AdrPart=3;
+ BAsmCode[0]=0xed; BAsmCode[1]=0x01+(AdrPart << 2);
+ CodeLen=2;
+ END
+ else if (AdrPart==0)
+ BEGIN
+ BAsmCode[0]=0xed; BAsmCode[1]=0x01+(AdrByte << 2);
+ CodeLen=2;
+ END
+ END
+ else
+ BEGIN
+ if (AdrPart==2) AdrPart=3;
+ BAsmCode[1]=0x03+((BAsmCode[0] >> 2) & 8)+(AdrByte << 4);
+ BAsmCode[0]=0xed;
+ CodeLen=2;
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ else /* EX XY,... */
+ BEGIN
+ DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg16:
+ if (AdrPart==3) WrError(1350);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else if (OK)
+ if ((PrefixCnt!=2) OR (BAsmCode[0]!=BAsmCode[1])) WrError(1350);
+ else
+ BEGIN
+ CodeLen=3; BAsmCode[2]=((BAsmCode[0] >> 5) & 1)+0x34;
+ BAsmCode[0]=0xed; BAsmCode[1]=0xcb;
+ END
+ else if (PrefixCnt==1)
+ BEGIN
+ if (AdrPart==2) AdrPart=3;
+ BAsmCode[1]=((BAsmCode[0] >> 2) & 8)+3+(AdrPart << 4);
+ BAsmCode[0]=0xed;
+ CodeLen=2;
+ END
+ else if (BAsmCode[0]==BAsmCode[1]) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0xed; BAsmCode[1]=0x2b; CodeLen=2;
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ return;
+ END
+
+/*-------------------------------------------------------------------------*/
+/* Arithmetik */
+
+ if (CodeAri()) return;
+
+/*-------------------------------------------------------------------------*/
+/* Ein/Ausgabe */
+
+ if (Memo("TSTI"))
+ BEGIN
+ if (MomCPU!=CPUZ80U) WrError(1500);
+ else if (ArgCnt!=0) WrError(1110);
+ else
+ BEGIN
+ BAsmCode[0]=0xed; BAsmCode[1]=0x70; CodeLen=2;
+ END
+ return;
+ END
+
+ if ((Memo("IN")) OR (Memo("OUT")))
+ BEGIN
+ if ((ArgCnt==1) AND (Memo("IN")))
+ BEGIN
+ if (MomCPU!=CPUZ80U) WrError(1500);
+ else if (strcasecmp(ArgStr[1],"(C)")!=0) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0xed; BAsmCode[1]=0x70; CodeLen=2;
+ END
+ END
+ else if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ if (Memo("OUT"))
+ BEGIN
+ strcpy(ArgStr[3],ArgStr[1]); strcpy(ArgStr[1],ArgStr[2]); strcpy(ArgStr[2],ArgStr[3]);
+ END
+ if (strcasecmp(ArgStr[2],"(C)")==0)
+ BEGIN
+ OpSize=0; DecodeAdr(ArgStr[1]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if ((AdrPart==6) OR (PrefixCnt!=0)) WrError(1350);
+ else
+ BEGIN
+ CodeLen=2;
+ BAsmCode[0]=0xed; BAsmCode[1]=0x40+(AdrPart << 3);
+ if (Memo("OUT")) BAsmCode[1]++;
+ END
+ break;
+ case ModImm:
+ if (Memo("IN")) WrError(1350);
+ else if ((MomCPU==CPUZ80U) AND (AdrVals[0]==0))
+ BEGIN
+ BAsmCode[0]=0xed; BAsmCode[1]=0x71; CodeLen=2;
+ END
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ BAsmCode[0]=0xed; BAsmCode[1]=0x71; BAsmCode[2]=AdrVals[0];
+ CodeLen=3;
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ else if (strcasecmp(ArgStr[1],"A")!=0) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[1]=EvalIntExpression(ArgStr[2],UInt8,&OK);
+ if (OK)
+ BEGIN
+ ChkSpace(SegIO);
+ CodeLen=2;
+ BAsmCode[0]=(Memo("OUT")) ? 0xd3 : 0xdb;
+ END
+ END
+ END
+ return;
+ END
+
+ if ((Memo("INW")) OR (Memo("OUTW")))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ if (Memo("OUTW"))
+ BEGIN
+ strcpy(ArgStr[3],ArgStr[1]); strcpy(ArgStr[1],ArgStr[2]); strcpy(ArgStr[2],ArgStr[3]);
+ END;
+ if (strcasecmp(ArgStr[2],"(C)")!=0) WrError(1350);
+ else
+ BEGIN
+ OpSize=1; DecodeAdr(ArgStr[1]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg16:
+ if ((AdrPart==3) OR (PrefixCnt>0)) WrError(1350);
+ else
+ BEGIN
+ switch (AdrPart)
+ BEGIN
+ case 1: AdrPart=2; break;
+ case 2: AdrPart=7; break;
+ END
+ BAsmCode[0]=0xdd; BAsmCode[1]=0x40+(AdrPart << 3);
+ if (Memo("OUTW")) BAsmCode[1]++;
+ CodeLen=2;
+ END
+ break;
+ case ModImm:
+ if (Memo("INW")) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0xfd; BAsmCode[1]=0x79;
+ memcpy(BAsmCode+2,AdrVals,AdrCnt);
+ CodeLen=2+AdrCnt;
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ END
+ return;
+ END
+
+ if ((Memo("IN0")) OR (Memo("OUT0")))
+ BEGIN
+ if ((ArgCnt!=2) AND (ArgCnt!=1)) WrError(1110);
+ else if ((ArgCnt==1) AND (Memo("OUT0"))) WrError(1110);
+ else if (MomCPU<CPUZ180) WrError(1500);
+ else
+ BEGIN
+ if (Memo("OUT0"))
+ BEGIN
+ strcpy(ArgStr[3],ArgStr[1]); strcpy(ArgStr[1],ArgStr[2]); strcpy(ArgStr[2],ArgStr[3]);
+ END
+ OpSize=0;
+ if (ArgCnt==1)
+ BEGIN
+ AdrPart=6; OK=True;
+ END
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1]);
+ if ((AdrMode==ModReg8) AND (AdrPart!=6) AND (PrefixCnt==0)) OK=True;
+ else
+ BEGIN
+ OK=False; if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ if (OK)
+ BEGIN
+ BAsmCode[2]=EvalIntExpression(ArgStr[ArgCnt],UInt8,&OK);
+ if (OK)
+ BEGIN
+ BAsmCode[0]=0xed; BAsmCode[1]=AdrPart << 3;
+ if (Memo("OUT0")) BAsmCode[1]++;
+ CodeLen=3;
+ END
+ END
+ END
+ return;
+ END
+
+ if ((Memo("INA")) OR (Memo("INAW")) OR (Memo("OUTA")) OR (Memo("OUTAW")))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ if (*OpPart=='O')
+ BEGIN
+ strcpy(ArgStr[3],ArgStr[1]); strcpy(ArgStr[1],ArgStr[2]); strcpy(ArgStr[2],ArgStr[3]);
+ END
+ OpSize=Ord(OpPart[strlen(OpPart)-1]=='W');
+ if (((OpSize==0) AND (strcasecmp(ArgStr[1],"A")!=0))
+ OR ((OpSize==1) AND (strcasecmp(ArgStr[1],"HL")!=0))) WrError(1350);
+ else
+ BEGIN
+ AdrLong=EvalIntExpression(ArgStr[2],ExtFlag?Int32:UInt8,&OK);
+ if (OK)
+ BEGIN
+ ChkSpace(SegIO);
+ if (AdrLong>0xffffff) ChangeDDPrefix("IW");
+ else if (AdrLong>0xffff) ChangeDDPrefix("IB");
+ BAsmCode[PrefixCnt]=0xed+(OpSize << 4);
+ BAsmCode[PrefixCnt+1]=0xd3+(Ord(*OpPart=='I') << 3);
+ BAsmCode[PrefixCnt+2]=AdrLong & 0xff;
+ BAsmCode[PrefixCnt+3]=(AdrLong >> 8) & 0xff;
+ CodeLen=PrefixCnt+4;
+ if (AdrLong>0xffff)
+ BAsmCode[CodeLen++]=(AdrLong >> 16) & 0xff;
+ if (AdrLong>0xffffff)
+ BAsmCode[CodeLen++]=(AdrLong >> 24) & 0xff;
+ END
+ END
+ END
+ return;
+ END
+
+ if (Memo("TSTIO"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (MomCPU<CPUZ180) WrError(1500);
+ else
+ BEGIN
+ BAsmCode[2]=EvalIntExpression(ArgStr[1],Int8,&OK);
+ if (OK)
+ BEGIN
+ BAsmCode[0]=0xed; BAsmCode[1]=0x74;
+ CodeLen=3;
+ END
+ END
+ return;
+ END
+
+/*-------------------------------------------------------------------------*/
+/* Spruenge */
+
+ if (Memo("RET"))
+ BEGIN
+ if (ArgCnt==0)
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0xc9;
+ END
+ else if (ArgCnt!=1) WrError(1110);
+ else if (NOT DecodeCondition(ArgStr[1],&z)) WrError(1360);
+ else
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0xc0+(z << 3);
+ END
+ return;
+ END
+
+ if (Memo("JP"))
+ BEGIN
+ if (ArgCnt==1)
+ BEGIN
+ if (strcasecmp(ArgStr[1],"(HL)")==0)
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0xe9; OK=False;
+ END
+ else if (strcasecmp(ArgStr[1],"(IX)")==0)
+ BEGIN
+ CodeLen=2; BAsmCode[0]=IXPrefix; BAsmCode[1]=0xe9; OK=False;
+ END
+ else if (strcasecmp(ArgStr[1],"(IY)")==0)
+ BEGIN
+ CodeLen=2; BAsmCode[0]=IYPrefix; BAsmCode[1]=0xe9; OK=False;
+ END
+ else
+ BEGIN
+ z=1; OK=True;
+ END
+ END
+ else if (ArgCnt==2)
+ BEGIN
+ OK=DecodeCondition(ArgStr[1],&z);
+ if (OK) z<<=3; else WrError(1360);
+ END
+ else
+ BEGIN
+ WrError(1110); OK=False;
+ END
+ if (OK)
+ BEGIN
+ AdrLong=EvalAbsAdrExpression(ArgStr[ArgCnt],&OK);
+ if (OK)
+#ifdef __STDC__
+ if ((AdrLong & 0xffff0000u)==0)
+#else
+ if ((AdrLong & 0xffff0000)==0)
+#endif
+ BEGIN
+ CodeLen=3; BAsmCode[0]=0xc2+z;
+ BAsmCode[1]=Lo(AdrLong); BAsmCode[2]=Hi(AdrLong);
+ END
+#ifdef __STDC__
+ else if ((AdrLong & 0xff000000u)==0)
+#else
+ else if ((AdrLong & 0xff000000)==0)
+#endif
+ BEGIN
+ ChangeDDPrefix("IB");
+ CodeLen=4+PrefixCnt; BAsmCode[PrefixCnt]=0xc2+z;
+ BAsmCode[PrefixCnt+1]=Lo(AdrLong);
+ BAsmCode[PrefixCnt+2]=Hi(AdrLong);
+ BAsmCode[PrefixCnt+3]=Hi(AdrLong >> 8);
+ END
+ else
+ BEGIN
+ ChangeDDPrefix("IW");
+ CodeLen=5+PrefixCnt; BAsmCode[PrefixCnt]=0xc2+z;
+ BAsmCode[PrefixCnt+1]=Lo(AdrLong);
+ BAsmCode[PrefixCnt+2]=Hi(AdrLong);
+ BAsmCode[PrefixCnt+3]=Hi(AdrLong >> 8);
+ BAsmCode[PrefixCnt+4]=Hi(AdrLong >> 16);
+ END
+ END
+ return;
+ END
+
+ if (Memo("CALL"))
+ BEGIN
+ if (ArgCnt==1)
+ BEGIN
+ z=9; OK=True;
+ END
+ else if (ArgCnt==2)
+ BEGIN
+ OK=DecodeCondition(ArgStr[1],&z);
+ if (OK) z<<=3; else WrError(1360);
+ END
+ else
+ BEGIN
+ WrError(1110); OK=False;
+ END
+ if (OK)
+ BEGIN
+ AdrLong=EvalAbsAdrExpression(ArgStr[ArgCnt],&OK);
+ if (OK)
+#ifdef __STDC__
+ if ((AdrLong & 0xffff0000u)==0)
+#else
+ if ((AdrLong & 0xffff0000)==0)
+#endif
+ BEGIN
+ CodeLen=3; BAsmCode[0]=0xc4+z;
+ BAsmCode[1]=Lo(AdrLong); BAsmCode[2]=Hi(AdrLong);
+ END
+#ifdef __STDC__
+ else if ((AdrLong & 0xff000000u)==0)
+#else
+ else if ((AdrLong & 0xff000000)==0)
+#endif
+ BEGIN
+ ChangeDDPrefix("IB");
+ CodeLen=4+PrefixCnt; BAsmCode[PrefixCnt]=0xc4+z;
+ BAsmCode[PrefixCnt+1]=Lo(AdrLong);
+ BAsmCode[PrefixCnt+2]=Hi(AdrLong);
+ BAsmCode[PrefixCnt+3]=Hi(AdrLong >> 8);
+ END
+ else
+ BEGIN
+ ChangeDDPrefix("IW");
+ CodeLen=5+PrefixCnt; BAsmCode[PrefixCnt]=0xc4+z;
+ BAsmCode[PrefixCnt+1]=Lo(AdrLong);
+ BAsmCode[PrefixCnt+2]=Hi(AdrLong);
+ BAsmCode[PrefixCnt+3]=Hi(AdrLong >> 8);
+ BAsmCode[PrefixCnt+4]=Hi(AdrLong >> 16);
+ END
+ END
+ return;
+ END
+
+ if (Memo("JR"))
+ BEGIN
+ if (ArgCnt==1)
+ BEGIN
+ z=3; OK=True;
+ END
+ else if (ArgCnt==2)
+ BEGIN
+ OK=DecodeCondition(ArgStr[1],&z);
+ if ((OK) AND (z>3)) OK=False;
+ if (OK) z+=4; else WrError(1360);
+ END
+ else
+ BEGIN
+ WrError(1110); OK=False;
+ END
+ if (OK)
+ BEGIN
+ AdrLInt=EvalAbsAdrExpression(ArgStr[ArgCnt],&OK);
+ if (OK)
+ BEGIN
+ AdrLInt-=EProgCounter()+2;
+ if ((AdrLInt<=0x7fl) AND (AdrLInt>=-0x80l))
+ BEGIN
+ CodeLen=2; BAsmCode[0]=z << 3;
+ BAsmCode[1]=AdrLInt & 0xff;
+ END
+ else
+ if (MomCPU<CPUZ380) WrError(1370);
+ else
+ BEGIN
+ AdrLInt-=2;
+ if ((AdrLInt<=0x7fffl) AND (AdrLInt>=-0x8000l))
+ BEGIN
+ CodeLen=4; BAsmCode[0]=0xdd; BAsmCode[1]=z << 3;
+ BAsmCode[2]=AdrLInt & 0xff;
+ BAsmCode[3]=(AdrLInt >> 8) & 0xff;
+ END
+ else
+ BEGIN
+ AdrLInt--;
+ if ((AdrLInt<=0x7fffffl) AND (AdrLInt>=-0x800000l))
+ BEGIN
+ CodeLen=5; BAsmCode[0]=0xfd; BAsmCode[1]=z << 3;
+ BAsmCode[2]=AdrLInt & 0xff;
+ BAsmCode[3]=(AdrLInt >> 8) & 0xff;
+ BAsmCode[4]=(AdrLInt >> 16) & 0xff;
+ END
+ else WrError(1370);
+ END
+ END
+ END
+ END
+ return;
+ END
+
+ if (Memo("CALR"))
+ BEGIN
+ if (ArgCnt==1)
+ BEGIN
+ z=9; OK=True;
+ END
+ else if (ArgCnt==2)
+ BEGIN
+ OK=DecodeCondition(ArgStr[1],&z);
+ if (OK) z<<=3; else WrError(1360);
+ END
+ else
+ BEGIN
+ WrError(1110); OK=False;
+ END
+ if (OK)
+ if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ AdrLInt=EvalAbsAdrExpression(ArgStr[ArgCnt],&OK);
+ if (OK)
+ BEGIN
+ AdrLInt-=EProgCounter()+3;
+ if ((AdrLInt<=0x7fl) AND (AdrLInt>=-0x80l))
+ BEGIN
+ CodeLen=3; BAsmCode[0]=0xed; BAsmCode[1]=0xc4+z;
+ BAsmCode[2]=AdrLInt & 0xff;
+ END
+ else
+ BEGIN
+ AdrLInt--;
+ if ((AdrLInt<=0x7fffl) AND (AdrLInt>=-0x8000l))
+ BEGIN
+ CodeLen=4; BAsmCode[0]=0xdd; BAsmCode[1]=0xc4+z;
+ BAsmCode[2]=AdrLInt & 0xff;
+ BAsmCode[3]=(AdrLInt >> 8) & 0xff;
+ END
+ else
+ BEGIN
+ AdrLInt--;
+ if ((AdrLInt<=0x7fffffl) AND (AdrLInt>=-0x800000l))
+ BEGIN
+ CodeLen=5; BAsmCode[0]=0xfd; BAsmCode[1]=0xc4+z;
+ BAsmCode[2]=AdrLInt & 0xff;
+ BAsmCode[3]=(AdrLInt >> 8) & 0xff;
+ BAsmCode[4]=(AdrLInt >> 16) & 0xff;
+ END
+ else WrError(1370);
+ END
+ END
+ END
+ END
+ return;
+ END
+
+ if (Memo("DJNZ"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ AdrLInt=EvalAbsAdrExpression(ArgStr[1],&OK);
+ if (OK)
+ BEGIN
+ AdrLInt-=EProgCounter()+2;
+ if ((AdrLInt<=0x7fl) AND (AdrLInt>=-0x80l))
+ BEGIN
+ CodeLen=2; BAsmCode[0]=0x10; BAsmCode[1]=Lo(AdrLInt);
+ END
+ else if (MomCPU<CPUZ380) WrError(1370);
+ else
+ BEGIN
+ AdrLInt-=2;
+ if ((AdrLInt<=0x7fffl) AND (AdrLInt>=-0x8000l))
+ BEGIN
+ CodeLen=4; BAsmCode[0]=0xdd; BAsmCode[1]=0x10;
+ BAsmCode[2]=AdrLInt & 0xff;
+ BAsmCode[3]=(AdrLInt >> 8) & 0xff;
+ END
+ else
+ BEGIN
+ AdrLInt--;
+ if ((AdrLInt<=0x7fffffl) AND (AdrLInt>=-0x800000l))
+ BEGIN
+ CodeLen=5; BAsmCode[0]=0xfd; BAsmCode[1]=0x10;
+ BAsmCode[2]=AdrLInt & 0xff;
+ BAsmCode[3]=(AdrLInt >> 8) & 0xff;
+ BAsmCode[4]=(AdrLInt >> 16) & 0xff;
+ END
+ else WrError(1370);
+ END
+ END
+ END
+ END
+ return;
+ END
+
+ if (Memo("RST"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ FirstPassUnknown=False;
+ AdrByte=EvalIntExpression(ArgStr[1],Int8,&OK);
+ if (FirstPassUnknown) AdrByte=AdrByte & 0x38;
+ if (OK)
+ if ((AdrByte>0x38) OR ((AdrByte & 7)!=0)) WrError(1320);
+ else
+ BEGIN
+ CodeLen=1; BAsmCode[0]=0xc7+AdrByte;
+ END
+ END
+ return;
+ END
+
+/*-------------------------------------------------------------------------*/
+/* Sonderbefehle */
+
+ if ((Memo("EI")) OR (Memo("DI")))
+ BEGIN
+ if (ArgCnt==0)
+ BEGIN
+ BAsmCode[0]=0xf3+(Ord(Memo("EI")) << 3);
+ CodeLen=1;
+ END
+ else if (ArgCnt!=1) WrError(1110);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ BAsmCode[2]=EvalIntExpression(ArgStr[1],UInt8,&OK);
+ if (OK)
+ BEGIN
+ BAsmCode[0]=0xdd; BAsmCode[1]=0xf3+(Ord(Memo("EI")) << 3);
+ CodeLen=3;
+ END
+ END
+ return;
+ END
+
+ if (Memo("IM"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else
+ BEGIN
+ AdrByte=EvalIntExpression(ArgStr[1],UInt2,&OK);
+ if (OK)
+ if (AdrByte>3) WrError(1320);
+ else if ((AdrByte==3) AND (MomCPU<CPUZ380)) WrError(1500);
+ else
+ BEGIN
+ if (AdrByte==3) AdrByte=1;
+ else if (AdrByte>=1) AdrByte++;
+ CodeLen=2; BAsmCode[0]=0xed; BAsmCode[1]=0x46+(AdrByte << 3);
+ END
+ END
+ return;
+ END
+
+ if (Memo("LDCTL"))
+ BEGIN
+ OpSize=0;
+ if (ArgCnt!=2) WrError(1110);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else if (DecodeSFR(ArgStr[1],&AdrByte))
+ BEGIN
+ DecodeAdr(ArgStr[2]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if (AdrPart!=7) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0xcd+((AdrByte & 3) << 4);
+ BAsmCode[1]=0xc8+((AdrByte & 4) << 2);
+ CodeLen=2;
+ END
+ break;
+ case ModReg16:
+ if ((AdrByte!=1) OR (AdrPart!=2) OR (PrefixCnt!=0)) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0xed; BAsmCode[1]=0xc8; CodeLen=2;
+ END
+ break;
+ case ModImm:
+ BAsmCode[0]=0xcd+((AdrByte & 3) << 4);
+ BAsmCode[1]=0xca+((AdrByte & 4) << 2);
+ BAsmCode[2]=AdrVals[0];
+ CodeLen=3;
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ else if (DecodeSFR(ArgStr[2],&AdrByte))
+ BEGIN
+ DecodeAdr(ArgStr[1]);
+ switch (AdrMode)
+ BEGIN
+ case ModReg8:
+ if ((AdrPart!=7) OR (AdrByte==1)) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0xcd+((AdrByte & 3) << 4);
+ BAsmCode[1]=0xd0;
+ CodeLen=2;
+ END
+ break;
+ case ModReg16:
+ if ((AdrByte!=1) OR (AdrPart!=2) OR (PrefixCnt!=0)) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0xed; BAsmCode[1]=0xc0; CodeLen=2;
+ END
+ break;
+ default: if (AdrMode!=ModNone) WrError(1350);
+ END
+ END
+ else WrError(1350);
+ return;
+ END
+
+ if ((Memo("RESC")) OR (Memo("SETC")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (MomCPU<CPUZ380) WrError(1500);
+ else
+ BEGIN
+ AdrByte=0xff; NLS_UpString(ArgStr[1]);
+ if (strcmp(ArgStr[1],"LW")==0) AdrByte=1;
+ else if (strcmp(ArgStr[1],"LCK")==0) AdrByte=2;
+ else if (strcmp(ArgStr[1],"XM")==0) AdrByte=3;
+ else WrError(1440);
+ if (AdrByte!=0xff)
+ BEGIN
+ CodeLen=2; BAsmCode[0]=0xcd+(AdrByte << 4);
+ BAsmCode[1]=0xf7+(Ord(Memo("RESC")) << 3);
+ END
+ END
+ return;
+ END
+
+ WrXError(1200,OpPart);
+END
+
+ static void InitCode_Z80(void)
+BEGIN
+ SaveInitProc();
+ SetFlag(&ExtFlag,ExtFlagName,False);
+ SetFlag(&LWordFlag,LWordFlagName,False);
+END
+
+ static Boolean IsDef_Z80(void)
+BEGIN
+ return Memo("PORT");
+END
+
+ static void SwitchFrom_Z80(void)
+BEGIN
+ DeinitFields(); ClearONOFF();
+END
+
+ static void SwitchTo_Z80(void)
+BEGIN
+ TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=True;
+
+ PCSymbol="$"; HeaderID=0x51; NOPCode=0x00;
+ DivideChars=","; HasAttrs=False;
+
+ ValidSegs=(1<<SegCode)+(1<<SegIO);
+ Grans[SegCode]=1; ListGrans[SegCode]=1; SegInits[SegCode]=0;
+ SegLimits[SegCode] = CodeEnd();
+ Grans[SegIO ]=1; ListGrans[SegIO ]=1; SegInits[SegIO ]=0;
+ SegLimits[SegIO ] = PortEnd();
+
+ MakeCode=MakeCode_Z80; IsDef=IsDef_Z80;
+ SwitchFrom=SwitchFrom_Z80; InitFields();
+
+ /* erweiterte Modi nur bei Z380 */
+
+ if (MomCPU>=CPUZ380)
+ BEGIN
+ AddONOFF("EXTMODE", &ExtFlag , ExtFlagName ,False);
+ AddONOFF("LWORDMODE", &LWordFlag , LWordFlagName ,False);
+ END
+ SetFlag(&ExtFlag,ExtFlagName,False);
+ SetFlag(&LWordFlag,LWordFlagName,False);
+END
+
+ void codez80_init(void)
+BEGIN
+ CPUZ80 =AddCPU("Z80" ,SwitchTo_Z80);
+ CPUZ80U=AddCPU("Z80UNDOC",SwitchTo_Z80);
+ CPUZ180=AddCPU("Z180",SwitchTo_Z80);
+ CPUZ380=AddCPU("Z380",SwitchTo_Z80);
+
+ SaveInitProc=InitPassProc; InitPassProc=InitCode_Z80;
+END