/* code75k0.c */ /*****************************************************************************/ /* AS-Portierung */ /* */ /* Codegenerator NEC 75K0 */ /* */ /* Historie: 31.12.1996 Grundsteinlegung */ /* 3. 1.1999 ChkPC-Anpassung */ /* */ /*****************************************************************************/ #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" #define ModNone (-1) #define ModReg4 0 #define MModReg4 (1 << ModReg4) #define ModReg8 1 #define MModReg8 (1 << ModReg8) #define ModImm 2 #define MModImm (1 << ModImm) #define ModInd 3 #define MModInd (1 << ModInd) #define ModAbs 4 #define MModAbs (1 << ModAbs) #define FixedOrderCount 6 #define AriOrderCount 3 #define LogOrderCount 3 typedef struct { char *Name; Word Code; } FixedOrder; static SimpProc SaveInitProc; static FixedOrder *FixedOrders; static char **AriOrders; static char **LogOrders; static LongInt MBSValue,MBEValue; static Boolean MinOneIs0; static CPUVar CPU75402,CPU75004,CPU75006,CPU75008, CPU75268,CPU75304,CPU75306,CPU75308, CPU75312,CPU75316,CPU75328,CPU75104, CPU75106,CPU75108,CPU75112,CPU75116, CPU75206,CPU75208,CPU75212,CPU75216, CPU75512,CPU75516; static Word ROMEnd; static ShortInt OpSize; static Byte AdrPart; static ShortInt AdrMode; /*-------------------------------------------------------------------------*/ /* dynamische Codetabellenverwaltung */ static void AddFixed(char *NewName, Word NewCode) BEGIN if (InstrZ>=FixedOrderCount) exit(255); FixedOrders[InstrZ].Name=NewName; FixedOrders[InstrZ++].Code=NewCode; END static void InitFields(void) BEGIN Boolean Err; ROMEnd=ConstLongInt(MomCPUName+3,&Err); if (ROMEnd>2) ROMEnd%=10; ROMEnd=(ROMEnd << 10)-1; FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCount); InstrZ=0; AddFixed("RET" ,0x00ee); AddFixed("RETS",0x00e0); AddFixed("RETI",0x00ef); AddFixed("HALT",0xa39d); AddFixed("STOP",0xb39d); AddFixed("NOP" ,0x0060); AriOrders=(char **) malloc(sizeof(char *)*AriOrderCount); InstrZ=0; AriOrders[InstrZ++]="ADDC"; AriOrders[InstrZ++]="SUBS"; AriOrders[InstrZ++]="SUBC"; LogOrders=(char **) malloc(sizeof(char *)*LogOrderCount); InstrZ=0; LogOrders[InstrZ++]="AND"; LogOrders[InstrZ++]="OR"; LogOrders[InstrZ++]="XOR"; END static void DeinitFields(void) BEGIN free(FixedOrders); free(AriOrders); free(LogOrders); END /*-------------------------------------------------------------------------*/ /* Untermengen von Befehlssatz abpruefen */ static void CheckCPU(CPUVar MinCPU) BEGIN if (MomCPU0x7f) AND (Adr<0xf80)) WrError(110); break; case 1: if (Hi(Adr)!=MBSValue) WrError(110); break; END END static void ChkAdr(Byte Mask) BEGIN if ((AdrMode!=ModNone) AND ((Mask & (1 << AdrMode))==0)) BEGIN WrError(1350); AdrMode=ModNone; END END static void DecodeAdr(char *Asc, Byte Mask) BEGIN static char *RegNames="XAHLDEBC"; char *p; int pos; Boolean OK; String s; AdrMode=ModNone; /* Register ? */ memcpy(s,Asc,2); s[2]='\0'; NLS_UpString(s); p=strstr(RegNames,s); if (p!=Nil) BEGIN pos=p-RegNames; /* 8-Bit-Register ? */ if (strlen(Asc)==1) BEGIN AdrPart=pos ^ 1; if (SetOpSize(0)) if ((AdrPart>4) AND (MomCPU2) AND (MomCPU> 4) & 0xf00)+Lo(*Erg)); return OK; END *p='\0'; strmaxcpy(bpart,p+1,255); if (strcasecmp(bpart,"@L")==0) BEGIN FirstPassUnknown=False; Adr=EvalIntExpression(Asc,UInt12,&OK); if (FirstPassUnknown) Adr=(Adr & 0xffc) | 0xfc0; if (OK) BEGIN ChkSpace(SegData); if ((Adr & 3)!=0) WrError(1325); else if (Adr<0xfc0) WrError(1315); else if (MomCPU> 2); sprintf(BName,"%sH.@L",HexString(Adr,3)); return True; END END END else BEGIN Num=EvalIntExpression(bpart,UInt2,&OK); if (OK) if (strncasecmp(Asc,"@H",2)==0) BEGIN Adr=EvalIntExpression(Asc+2,UInt4,&OK); if (OK) if (MomCPU=0xfb0) AND (Adr<0xfc0)) *Erg=0x80+(Num << 4)+(Adr & 15); else if (Adr>=0xff0) *Erg=0xc0+(Num << 4)+(Adr & 15); else *Erg=0x400+(((Word)Num) << 8)+Lo(Adr)+(Hi(Adr) << 12); sprintf(BName,"%sH.%c",HexString(Adr,3),'0'+Num); return True; END END END return False; END static Boolean DecodeIntName(char *Asc, Byte *Erg) BEGIN Word HErg; Byte LPart; String Asc_N; strmaxcpy(Asc_N,Asc,255); NLS_UpString(Asc_N); Asc=Asc_N; if (MomCPU<=CPU75402) LPart=0; else if (MomCPULPart) return False; else BEGIN *Erg=Lo(HErg); return True; END END /*-------------------------------------------------------------------------*/ static Boolean DecodePseudo(void) BEGIN #define ASSUME75Count 2 static ASSUMERec ASSUME75s[ASSUME75Count]= {{"MBS", &MBSValue, 0, 0x0f, 0x10}, {"MBE", &MBEValue, 0, 0x01, 0x01}}; Word BErg; if (Memo("ASSUME")) BEGIN CodeASSUME(ASSUME75s,ASSUME75Count); if ((MomCPU==CPU75402) AND (MBEValue!=0)) BEGIN MBEValue=0; WrError(1440); END return True; END if (Memo("SFR")) BEGIN CodeEquate(SegData,0,0xfff); return True; END if (Memo("BIT")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN FirstPassUnknown=False; if (DecodeBitAddr(ArgStr[1],&BErg)) if (NOT FirstPassUnknown) BEGIN PushLocHandle(-1); EnterIntSymbol(LabPart,BErg,SegNone,False); sprintf(ListLine,"=%s",BName); PopLocHandle(); END END return True; END return False; END static void PutCode(Word Code) BEGIN BAsmCode[0]=Lo(Code); if (Hi(Code)==0) CodeLen=1; else BEGIN BAsmCode[1]=Hi(Code); CodeLen=2; END END static void MakeCode_75K0(void) BEGIN Integer AdrInt,Dist; int z; Byte HReg; Word BVal; Boolean OK,BrRel,BrLong; CodeLen=0; DontPrint=False; OpSize=(-1); MinOneIs0=False; /* zu ignorierendes */ if (Memo("")) return; /* Pseudoanweisungen */ if (DecodePseudo()) return; if (DecodeIntelPseudo(True)) return; /* ohne Argument */ for (z=0; z0) BEGIN strcpy(ArgStr[3],ArgStr[2]); strcpy(ArgStr[2],ArgStr[1]); strcpy(ArgStr[1],ArgStr[3]); END if (strncasecmp(ArgStr[1],"PORT",4)!=0) WrError(1350); else BEGIN BAsmCode[1]=0xf0+EvalIntExpression(ArgStr[1]+4,UInt4,&OK); if (OK) BEGIN DecodeAdr(ArgStr[2],MModReg8+MModReg4); switch (AdrMode) BEGIN case ModReg4: if (AdrPart!=0) WrError(1350); else BEGIN BAsmCode[0]=0x93+(z << 4); CodeLen=2; END break; case ModReg8: if (AdrPart!=0) WrError(1350); else BEGIN BAsmCode[0]=0x92+(z << 4); CodeLen=2; CheckCPU(CPU75004); END break; END END END END return; END /* Arithmetik */ if (Memo("ADDS")) BEGIN if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[1],MModReg4+MModReg8); switch (AdrMode) BEGIN case ModReg4: if (AdrPart!=0) WrError(1350); else BEGIN DecodeAdr(ArgStr[2],MModImm+MModInd); switch (AdrMode) BEGIN case ModImm: PutCode(0x60+AdrPart); break; case ModInd: if (AdrPart==1) PutCode(0xd2); else WrError(1350); break; END END break; case ModReg8: if (AdrPart==0) BEGIN DecodeAdr(ArgStr[2],MModReg8+MModImm); switch (AdrMode) BEGIN case ModReg8: PutCode(0xc8aa+(((Word)AdrPart) << 8)); CheckCPU(CPU75104); break; case ModImm: BAsmCode[0]=0xb9; BAsmCode[1]=AdrPart; CodeLen=2; CheckCPU(CPU75104); break; END END else if (strcasecmp(ArgStr[2],"XA")!=0) WrError(1350); else BEGIN PutCode(0xc0aa+(((Word)AdrPart) << 8)); CheckCPU(CPU75104); END break; END END return; END for (z=0; z> 2) & 3)-1],&BVal)) if (Hi(BVal)!=0) WrError(1350); else BEGIN BAsmCode[0]=z; BAsmCode[1]=BVal; CodeLen=2; CheckCPU(CPU75104); END END return; END if ((Memo("SET1")) OR (Memo("CLR1"))) BEGIN OK=Memo("SET1"); if (ArgCnt!=1) WrError(1110); else if (strcasecmp(ArgStr[1],"CY")==0) PutCode(0xe6+Ord(OK)); else if (DecodeBitAddr(ArgStr[1],&BVal)) if (Hi(BVal)!=0) BEGIN BAsmCode[0]=0x84+Ord(OK)+(Hi(BVal & 0x300) << 4); BAsmCode[1]=Lo(BVal); CodeLen=2; END else BEGIN BAsmCode[0]=0x9c+Ord(OK); BAsmCode[1]=BVal; CodeLen=2; END return; END if ((Memo("SKT")) OR (Memo("SKF"))) BEGIN OK=Memo("SKT"); if (ArgCnt!=1) WrError(1110); else if (strcasecmp(ArgStr[1],"CY")==0) if (Memo("SKT")) PutCode(0xd7); else WrError(1350); else if (DecodeBitAddr(ArgStr[1],&BVal)) if (Hi(BVal)!=0) BEGIN BAsmCode[0]=0x86+Ord(OK)+(Hi(BVal & 0x300) << 4); BAsmCode[1]=Lo(BVal); CodeLen=2; END else BEGIN BAsmCode[0]=0xbe + Ord(OK); /* ANSI :-0 */ BAsmCode[1]=BVal; CodeLen=2; END return; END if (Memo("NOT1")) BEGIN if (ArgCnt!=1) WrError(1110); else if (strcasecmp(ArgStr[1],"CY")!=0) WrError(1350); else PutCode(0xd6); return; END if (Memo("SKTCLR")) BEGIN if (ArgCnt!=1) WrError(1110); else if (DecodeBitAddr(ArgStr[1],&BVal)) if (Hi(BVal)!=0) WrError(1350); else BEGIN BAsmCode[0]=0x9f; BAsmCode[1]=BVal; CodeLen=2; END return; END if (OpPart[strlen(OpPart)-1]=='1') for (z=0; z=-15) AND (Dist!=0))) BEGIN if (Dist>0) BEGIN Dist--; if ((Dist>15) AND (NOT SymbolQuestionable)) WrError(1370); else PutCode(0x00+Dist); END else BEGIN if ((Dist<-15) AND (NOT SymbolQuestionable)) WrError(1370); else PutCode(0xf0+15+Dist); END END else if ((NOT BrLong) AND ((AdrInt >> 12)==(EProgCounter() >> 12)) AND ((EProgCounter() & 0xfff)<0xffe)) BEGIN BAsmCode[0]=0x50+((AdrInt >> 8) & 15); BAsmCode[1]=Lo(AdrInt); CodeLen=2; END else BEGIN BAsmCode[0]=0xab; BAsmCode[1]=Hi(AdrInt & 0x3fff); BAsmCode[2]=Lo(AdrInt); CodeLen=3; CheckCPU(CPU75004); END ChkSpace(SegCode); END END return; END if (Memo("BRCB")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN AdrInt=EvalIntExpression(ArgStr[1],UInt16,&OK); if (OK) if ((AdrInt >> 12)!=(EProgCounter() >> 12)) WrError(1910); else if ((EProgCounter() & 0xfff)>=0xffe) WrError(1905); else BEGIN BAsmCode[0]=0x50+((AdrInt >> 8) & 15); BAsmCode[1]=Lo(AdrInt); CodeLen=2; ChkSpace(SegCode); END END return; END if (Memo("CALL")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN if (*ArgStr[1]=='!') BEGIN strcpy(ArgStr[1],ArgStr[1]+1); BrLong=True; END else BrLong=False; FirstPassUnknown=False; AdrInt=EvalIntExpression(ArgStr[1],UInt16,&OK); if (FirstPassUnknown) AdrInt&=0x7ff; if (OK) BEGIN if ((BrLong) OR (AdrInt>0x7ff)) BEGIN BAsmCode[0]=0xab; BAsmCode[1]=0x40+Hi(AdrInt & 0x3fff); BAsmCode[2]=Lo(AdrInt); CodeLen=3; CheckCPU(CPU75004); END else BEGIN BAsmCode[0]=0x40+Hi(AdrInt & 0x7ff); BAsmCode[1]=Lo(AdrInt); CodeLen=2; END ChkSpace(SegCode); END END return; END if (Memo("CALLF")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN if (*ArgStr[1]=='!') strcpy(ArgStr[1],ArgStr[1]+1); AdrInt=EvalIntExpression(ArgStr[1],UInt11,&OK); if (OK) BEGIN BAsmCode[0]=0x40+Hi(AdrInt); BAsmCode[1]=Lo(AdrInt); CodeLen=2; ChkSpace(SegCode); END END return; END if (Memo("GETI")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN BAsmCode[0]=EvalIntExpression(ArgStr[1],UInt6,&OK); CodeLen=Ord(OK); CheckCPU(CPU75004); END return; END /* Steueranweisungen */ if ((Memo("EI")) OR (Memo("DI"))) BEGIN OK=Memo("EI"); if (ArgCnt==0) PutCode(0xb29c+Ord(OK)); else if (ArgCnt!=1) WrError(1110); else if (DecodeIntName(ArgStr[1],&HReg)) PutCode(0x989c+Ord(OK)+(((Word)HReg) << 8)); else WrError(1440); return; END if (Memo("SEL")) BEGIN BAsmCode[0]=0x99; if (ArgCnt!=1) WrError(1110); else if (strncasecmp(ArgStr[1],"RB",2)==0) BEGIN BAsmCode[1]=0x20+EvalIntExpression(ArgStr[1]+2,UInt2,&OK); if (OK) BEGIN CodeLen=2; CheckCPU(CPU75104); END END else if (strncasecmp(ArgStr[1],"MB",2)==0) BEGIN BAsmCode[1]=0x10+EvalIntExpression(ArgStr[1]+2,UInt4,&OK); if (OK) BEGIN CodeLen=2; CheckCPU(CPU75004); END END else WrError(1350); return; END WrXError(1200,OpPart); END static void InitCode_75K0(void) BEGIN SaveInitProc(); MBSValue=0; MBEValue=0; END static Boolean IsDef_75K0(void) BEGIN return ((Memo("SFR")) OR (Memo("BIT"))); END static void SwitchFrom_75K0(void) BEGIN DeinitFields(); END static void SwitchTo_75K0(void) BEGIN TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False; PCSymbol="PC"; HeaderID=0x7b; NOPCode=0x60; DivideChars=","; HasAttrs=False; ValidSegs=(1<