/* codez8.c */ /*****************************************************************************/ /* AS-Portierung */ /* */ /* Codegenerator Zilog Z8 */ /* */ /* Historie: 8.11.1996 Grundsteinlegung */ /* 2. 1.1998 ChkPC ersetzt */ /* */ /*****************************************************************************/ #include "stdinc.h" #include #include #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=CondCnt) WrError(1360); END if (z127) 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) WrError(1360); END if (z0x70) 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<