/* code78c10.c */ /*****************************************************************************/ /* AS-Portierung */ /* */ /* Codegenerator NEC uPD78(C)1x */ /* */ /* Historie: 29.12.1996 Grundsteinlegung */ /* 2. 1.1999 ChkPC-Anpassung */ /* */ /*****************************************************************************/ #include "stdinc.h" #include #include #include "bpemu.h" #include "strutil.h" #include "asmdef.h" #include "asmsub.h" #include "asmpars.h" #include "codepseudo.h" #include "codevars.h" /*---------------------------------------------------------------------------*/ typedef struct { char *Name; Word Code; } FixedOrder; typedef struct { char *Name; Byte Code; } SReg; #define FixedOrderCnt 23 #define ALUOrderCnt 15 #define AbsOrderCnt 10 #define Reg2OrderCnt 10 #define WorkOrderCnt 4 #define EAOrderCnt 4 #define SRegCnt 28 static LongInt WorkArea; static SimpProc SaveInitProc; static CPUVar CPU7810,CPU78C10; static FixedOrder *FixedOrders; static Byte *ALUOrderCodes; static char **ALUOrderImmOps,**ALUOrderRegOps,**ALUOrderEAOps; static FixedOrder *AbsOrders; static FixedOrder *Reg2Orders; static FixedOrder *WorkOrders; static FixedOrder *EAOrders; static SReg *SRegs; /*--------------------------------------------------------------------------------*/ static void AddFixed(char *NName, Word NCode) BEGIN if (InstrZ>=FixedOrderCnt) exit(255); FixedOrders[InstrZ].Name=NName; FixedOrders[InstrZ++].Code=NCode; END static void AddSReg(char *NName, Word NCode) BEGIN if (InstrZ>=SRegCnt) exit(255); SRegs[InstrZ].Name=NName; SRegs[InstrZ++].Code=NCode; END static void AddALU(Byte NCode, char *NName1, char *NName2, char *NName3) BEGIN if (InstrZ>=ALUOrderCnt) exit(255); ALUOrderCodes[InstrZ]=NCode; ALUOrderImmOps[InstrZ]=NName1; ALUOrderRegOps[InstrZ]=NName2; ALUOrderEAOps[InstrZ++]=NName3; END static void AddAbs(char *NName, Word NCode) BEGIN if (InstrZ>=AbsOrderCnt) exit(255); AbsOrders[InstrZ].Name=NName; AbsOrders[InstrZ++].Code=NCode; END static void AddReg2(char *NName, Word NCode) BEGIN if (InstrZ>=Reg2OrderCnt) exit(255); Reg2Orders[InstrZ].Name=NName; Reg2Orders[InstrZ++].Code=NCode; END static void AddWork(char *NName, Word NCode) BEGIN if (InstrZ>=WorkOrderCnt) exit(255); WorkOrders[InstrZ].Name=NName; WorkOrders[InstrZ++].Code=NCode; END static void AddEA(char *NName, Word NCode) BEGIN if (InstrZ>=EAOrderCnt) exit(255); EAOrders[InstrZ].Name=NName; EAOrders[InstrZ++].Code=NCode; END static void InitFields(void) BEGIN FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); InstrZ=0; AddFixed("EXX" , 0x0011); AddFixed("EXA" , 0x0010); AddFixed("EXH" , 0x0050); AddFixed("BLOCK", 0x0031); AddFixed("TABLE", 0x48a8); AddFixed("DAA" , 0x0061); AddFixed("STC" , 0x482b); AddFixed("CLC" , 0x482a); AddFixed("NEGA" , 0x483a); AddFixed("RLD" , 0x4838); AddFixed("RRD" , 0x4839); AddFixed("JB" , 0x0021); AddFixed("JEA" , 0x4828); AddFixed("CALB" , 0x4829); AddFixed("SOFTI", 0x0072); AddFixed("RET" , 0x00b8); AddFixed("RETS" , 0x00b9); AddFixed("RETI" , 0x0062); AddFixed("NOP" , 0x0000); AddFixed("EI" , 0x00aa); AddFixed("DI" , 0x00ba); AddFixed("HLT" , 0x483b); AddFixed("STOP" , 0x48bb); SRegs=(SReg *) malloc(sizeof(SReg)*SRegCnt); InstrZ=0; AddSReg("PA" , 0x00); AddSReg("PB" , 0x01); AddSReg("PC" , 0x02); AddSReg("PD" , 0x03); AddSReg("PF" , 0x05); AddSReg("MKH" , 0x06); AddSReg("MKL" , 0x07); AddSReg("ANM" , 0x08); AddSReg("SMH" , 0x09); AddSReg("SML" , 0x0a); AddSReg("EOM" , 0x0b); AddSReg("ETNM", 0x0c); AddSReg("TMM" , 0x0d); AddSReg("MM" , 0x10); AddSReg("MCC" , 0x11); AddSReg("MA" , 0x12); AddSReg("MB" , 0x13); AddSReg("MC" , 0x14); AddSReg("MF" , 0x17); AddSReg("TXB" , 0x18); AddSReg("RXB" , 0x19); AddSReg("TM0" , 0x1a); AddSReg("TM1" , 0x1b); AddSReg("CR0" , 0x20); AddSReg("CR1" , 0x21); AddSReg("CR2" , 0x22); AddSReg("CR3" , 0x23); AddSReg("ZCM" , 0x28); ALUOrderCodes=(Byte *) malloc(sizeof(Byte)*ALUOrderCnt); ALUOrderImmOps=(char **) malloc(sizeof(char *)*ALUOrderCnt); ALUOrderRegOps=(char **) malloc(sizeof(char *)*ALUOrderCnt); ALUOrderEAOps=(char **) malloc(sizeof(char *)*ALUOrderCnt); InstrZ=0; AddALU(10,"ACI" ,"ADC" ,"DADC" ); AddALU( 4,"ADINC","ADDNC","DADDNC"); AddALU( 8,"ADI" ,"ADD" ,"DADD" ); AddALU( 1,"ANI" ,"ANA" ,"DAN" ); AddALU(15,"EQI" ,"EQA" ,"DEQ" ); AddALU( 5,"GTI" ,"GTA" ,"DGT" ); AddALU( 7,"LTI" ,"LTA" ,"DLT" ); AddALU(13,"NEI" ,"NEA" ,"DNE" ); AddALU(11,"OFFI" ,"OFFA" ,"DOFF" ); AddALU( 9,"ONI" ,"ONA" ,"DON" ); AddALU( 3,"ORI" ,"ORA" ,"DOR" ); AddALU(14,"SBI" ,"SBB" ,"DSBB" ); AddALU( 6,"SUINB","SUBNB","DSUBNB"); AddALU(12,"SUI" ,"SUB" ,"DSUB" ); AddALU( 2,"XRI" ,"XRA" ,"DXR" ); AbsOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*AbsOrderCnt); InstrZ=0; AddAbs("CALL", 0x0040); AddAbs("JMP" , 0x0054); AddAbs("LBCD", 0x701f); AddAbs("LDED", 0x702f); AddAbs("LHLD", 0x703f); AddAbs("LSPD", 0x700f); AddAbs("SBCD", 0x701e); AddAbs("SDED", 0x702e); AddAbs("SHLD", 0x703e); AddAbs("SSPD", 0x700e); Reg2Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*Reg2OrderCnt); InstrZ=0; AddReg2("DCR" , 0x0050); AddReg2("DIV" , 0x483c); AddReg2("INR" , 0x0040); AddReg2("MUL" , 0x482c); AddReg2("RLL" , 0x4834); AddReg2("RLR" , 0x4830); AddReg2("SLL" , 0x4824); AddReg2("SLR" , 0x4820); AddReg2("SLLC", 0x4804); AddReg2("SLRC", 0x4800); WorkOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*WorkOrderCnt); InstrZ=0; AddWork("DCRW", 0x33); AddWork("INRW", 0x20); AddWork("LDAW", 0x01); AddWork("STAW", 0x63); EAOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*EAOrderCnt); InstrZ=0; AddEA("DRLL", 0x48b4); AddEA("DRLR", 0x48b0); AddEA("DSLL", 0x48a4); AddEA("DSLR", 0x48a0); END static void DeinitFields(void) BEGIN free(FixedOrders); free(ALUOrderCodes); free(ALUOrderImmOps); free(ALUOrderRegOps); free(ALUOrderEAOps); free(AbsOrders); free(Reg2Orders); free(WorkOrders); free(EAOrders); free(SRegs); END /*--------------------------------------------------------------------------------*/ static Boolean Decode_r(char *Asc, ShortInt *Erg) BEGIN static char *Names="VABCDEHL"; char *p; if (strlen(Asc)!=1) return False; p=strchr(Names,toupper(*Asc)); if (p==Nil) return False; *Erg=p-Names; return True;; END static Boolean Decode_r1(char *Asc, ShortInt *Erg) BEGIN if (strcasecmp(Asc,"EAL")==0) *Erg=1; else if (strcasecmp(Asc,"EAH")==0) *Erg=0; else BEGIN if (NOT Decode_r(Asc,Erg)) return False; return (*Erg>1); END return True; END static Boolean Decode_r2(char *Asc, ShortInt *Erg) BEGIN if (NOT Decode_r(Asc,Erg)) return False; return ((*Erg>0) AND (*Erg<4)); END static Boolean Decode_rp2(char *Asc, ShortInt *Erg) BEGIN #define RegCnt 5 static char *Regs[RegCnt]={"SP","B","D","H","EA"}; for (*Erg=0; *Erg0)); END static Boolean Decode_rpa2(char *Asc, ShortInt *Erg, ShortInt *Disp) BEGIN #define OpCnt 13 static char *OpNames[OpCnt]={"B","D","H","D+","H+","D-","H-", "H+A","A+H","H+B","B+H","H+EA","EA+H"}; static Byte OpCodes[OpCnt]={1,2,3,4,5,6,7,12,12,13,13,14,14}; int z; char *p,*pm; Boolean OK; for (z=0; z=8)); END return True; END static Boolean Decode_f(char *Asc, ShortInt *Erg) BEGIN #define FlagCnt 3 static char *Flags[FlagCnt]={"CY","HC","Z"}; for (*Erg=0; *Erg=0) AND (*Erg<=9)) OR (*Erg==11) OR (*Erg==13) OR (*Erg==25) OR ((*Erg>=32) AND (*Erg<=35))); END static Boolean Decode_sr(char *Asc, ShortInt *Erg) BEGIN if (NOT Decode_sr0(Asc,Erg)) return False; return (((*Erg>=0) AND (*Erg<=24)) OR (*Erg==26) OR (*Erg==27) OR (*Erg==40)); END static Boolean Decode_sr2(char *Asc, ShortInt *Erg) BEGIN if (NOT Decode_sr0(Asc,Erg)) return False; return (((*Erg>=0) AND (*Erg<=9)) OR (*Erg==11) OR (*Erg==13)); END static Boolean Decode_sr3(char *Asc, ShortInt *Erg) BEGIN if (strcasecmp(Asc,"ETM0")==0) *Erg=0; else if (strcasecmp(Asc,"ETM1")==0) *Erg=1; else return False; return True; END static Boolean Decode_sr4(char *Asc, ShortInt *Erg) BEGIN if (strcasecmp(Asc,"ECNT")==0) *Erg=0; else if (strcasecmp(Asc,"ECPT")==0) *Erg=1; else return False; return True; END static Boolean Decode_irf(char *Asc, ShortInt *Erg) BEGIN #undef FlagCnt #define FlagCnt 18 static char *FlagNames[FlagCnt]= {"NMI" ,"FT0" ,"FT1" ,"F1" ,"F2" ,"FE0" , "FE1" ,"FEIN","FAD" ,"FSR" ,"FST" ,"ER" , "OV" ,"AN4" ,"AN5" ,"AN6" ,"AN7" ,"SB" }; static ShortInt FlagCodes[FlagCnt]= {0,1,2,3,4,5,6,7,8,9,10,11,12,16,17,18,19,20}; for (*Erg=0; *Erg=FlagCnt) return False; *Erg=FlagCodes[*Erg]; return True; END static Boolean Decode_wa(char *Asc, Byte *Erg) BEGIN Word Adr; Boolean OK; FirstPassUnknown=False; Adr=EvalIntExpression(Asc,Int16,&OK); if (NOT OK) return False; if ((FirstPassUnknown) AND (Hi(Adr)!=WorkArea)) WrError(110); *Erg=Lo(Adr); return True; END static Boolean HasDisp(ShortInt Mode) BEGIN return ((Mode & 11)==11); END /*--------------------------------------------------------------------------*/ static Boolean DecodePseudo(void) BEGIN #define ASSUME78C10Count 1 static ASSUMERec ASSUME78C10s[ASSUME78C10Count]= {{"V" , &WorkArea, 0, 0xff, 0x100}}; if (Memo("ASSUME")) BEGIN CodeASSUME(ASSUME78C10s,ASSUME78C10Count); return True; END return False; END static void MakeCode_78C10(void) BEGIN int z; Integer AdrInt; ShortInt HVal8,HReg; Boolean OK; CodeLen=0; DontPrint=False; /* zu ignorierendes */ if (Memo("")) return; /* Pseudoanweisungen */ if (DecodePseudo()) return; if (DecodeIntelPseudo(False)) return; /* ohne Argument */ for (z=0; z> 1) << 4); END END return; END for (z=0; z31))) WrError(1370); else BEGIN CodeLen=1; BAsmCode[0]=0xc0+(AdrInt & 0x3f); END else if ((NOT SymbolQuestionable) AND ((AdrInt<-256) OR (AdrInt>255))) WrError(1370); else BEGIN if ((AdrInt>=-32) AND (AdrInt<=31)) WrError(20); CodeLen=2; BAsmCode[0]=0x4e + (Hi(AdrInt) & 1); /* ANSI :-O */ BAsmCode[1]=Lo(AdrInt); END END return; END if (Memo("CALF")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN FirstPassUnknown=False; AdrInt=EvalIntExpression(ArgStr[1],Int16,&OK); if (OK) if ((NOT FirstPassUnknown) AND ((AdrInt >> 11)!=1)) WrError(1905); else BEGIN CodeLen=2; BAsmCode[0]=Hi(AdrInt)+0x70; BAsmCode[1]=Lo(AdrInt); END END return; END if (Memo("CALT")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN FirstPassUnknown=False; AdrInt=EvalIntExpression(ArgStr[1],Int16,&OK); if (OK) if ((NOT FirstPassUnknown) AND ((AdrInt & 0xffc1)!=0x80)) WrError(1905); else BEGIN CodeLen=1; BAsmCode[0]=0x80+((AdrInt & 0x3f) >> 1); END END return; END if (Memo("BIT")) BEGIN if (ArgCnt!=2) WrError(1110); else BEGIN HReg=EvalIntExpression(ArgStr[1],UInt3,&OK); if (OK) if (Decode_wa(ArgStr[2],BAsmCode+1)) BEGIN CodeLen=2; BAsmCode[0]=0x58+HReg; END END return; END for (z=0; z