/* codecop8.c */ /*****************************************************************************/ /* AS-Portierung */ /* */ /* Codegeneratormodul COP8-Familie */ /* */ /* Historie: 7.10.1996 Grundsteinlegung */ /* 18. 8.1998 BookKeeping-Aufruf bei DSx */ /* 2. 1.1998 ChkPC umgebaut */ /* 14. 8.1999 Maskierung in ChkAdr falsch */ /* */ /*****************************************************************************/ #include "stdinc.h" #include #include "bpemu.h" #include "strutil.h" #include "chunks.h" #include "asmdef.h" #include "asmsub.h" #include "asmpars.h" #include "codepseudo.h" #include "codevars.h" #define ModNone (-1) #define ModAcc 0 #define MModAcc (1 << ModAcc) #define ModBInd 1 #define MModBInd (1 << ModBInd) #define ModBInc 2 #define MModBInc (1 << ModBInc) #define ModBDec 3 #define MModBDec (1 << ModBDec) #define ModXInd 4 #define MModXInd (1 << ModXInd) #define ModXInc 5 #define MModXInc (1 << ModXInc) #define ModXDec 6 #define MModXDec (1 << ModXDec) #define ModDir 7 #define MModDir (1 << ModDir) #define ModImm 8 #define MModImm (1 << ModImm) #define DirPrefix 0xbd #define BReg 0xfe #define FixedOrderCnt 13 #define AccOrderCnt 9 #define AccMemOrderCnt 7 #define BitOrderCnt 3 typedef struct { char *Name; Byte Code; } FixedOrder; static CPUVar CPUCOP87L84; static FixedOrder *FixedOrders; static FixedOrder *AccOrders; static FixedOrder *AccMemOrders; static FixedOrder *BitOrders; static ShortInt AdrMode; static Byte AdrVal; static Boolean BigFlag; /*---------------------------------------------------------------------------*/ static void AddFixed(char *NName, Byte NCode) BEGIN if (InstrZ>=FixedOrderCnt) exit(255); FixedOrders[InstrZ].Name=NName; FixedOrders[InstrZ++].Code=NCode; END static void AddAcc(char *NName, Byte NCode) BEGIN if (InstrZ>=AccOrderCnt) exit(255); AccOrders[InstrZ].Name=NName; AccOrders[InstrZ++].Code=NCode; END static void AddAccMem(char *NName, Byte NCode) BEGIN if (InstrZ>=AccMemOrderCnt) exit(255); AccMemOrders[InstrZ].Name=NName; AccMemOrders[InstrZ++].Code=NCode; END static void AddBit(char *NName, Byte NCode) BEGIN if (InstrZ>=BitOrderCnt) exit(255); BitOrders[InstrZ].Name=NName; BitOrders[InstrZ++].Code=NCode; END static void InitFields(void) BEGIN FixedOrders=(FixedOrder *) malloc(FixedOrderCnt*sizeof(FixedOrder)); InstrZ=0; AddFixed("LAID" ,0xa4); AddFixed("SC" ,0xa1); AddFixed("RC" ,0xa0); AddFixed("IFC" ,0x88); AddFixed("IFNC" ,0x89); AddFixed("VIS" ,0xb4); AddFixed("JID" ,0xa5); AddFixed("RET" ,0x8e); AddFixed("RETSK",0x8d); AddFixed("RETI" ,0x8f); AddFixed("INTR" ,0x00); AddFixed("NOP" ,0xb8); AddFixed("RPND" ,0xb5); AccOrders=(FixedOrder *) malloc(AccOrderCnt*sizeof(FixedOrder)); InstrZ=0; AddAcc("CLR" ,0x64); AddAcc("INC" ,0x8a); AddAcc("DEC" ,0x8b); AddAcc("DCOR" ,0x66); AddAcc("RRC" ,0xb0); AddAcc("RLC" ,0xa8); AddAcc("SWAP" ,0x65); AddAcc("POP" ,0x8c); AddAcc("PUSH" ,0x67); AccMemOrders=(FixedOrder *) malloc(AccMemOrderCnt*sizeof(FixedOrder)); InstrZ=0; AddAccMem("ADD" ,0x84); AddAccMem("ADC" ,0x80); AddAccMem("SUBC" ,0x81); AddAccMem("AND" ,0x85); AddAccMem("OR" ,0x87); AddAccMem("XOR" ,0x86); AddAccMem("IFGT" ,0x83); BitOrders=(FixedOrder *) malloc(BitOrderCnt*sizeof(FixedOrder)); InstrZ=0; AddBit("IFBIT",0x70); AddBit("SBIT",0x78); AddBit("RBIT",0x68); END static void DeinitFields(void) BEGIN free(FixedOrders); free(AccOrders); free(AccMemOrders); free(BitOrders); END /*---------------------------------------------------------------------------*/ static void ChkAdr(Word Mask) BEGIN if ((AdrMode!=ModNone) AND ((Mask & (1 << AdrMode))==0)) BEGIN AdrMode=ModNone; WrError(1350); END END static void DecodeAdr(char *Asc, Word Mask) BEGIN static char *ModStrings[ModXDec+1]= {"A","[B]","[B+]","[B-]","[X]","[X+]","[X-]"}; int z; Boolean OK; AdrMode=ModNone; /* indirekt/Akku */ for (z=ModAcc; z<=ModXDec; z++) if (strcasecmp(Asc,ModStrings[z])==0) BEGIN AdrMode=z; ChkAdr(Mask); return; END /* immediate */ if (*Asc=='#') BEGIN AdrVal=EvalIntExpression(Asc+1,Int8,&OK); if (OK) AdrMode=ModImm; ChkAdr(Mask); return; END /* direkt */ AdrVal=EvalIntExpression(Asc,Int8,&OK); if (OK) BEGIN AdrMode=ModDir; ChkSpace(SegData); END ChkAdr(Mask); END /*---------------------------------------------------------------------------*/ static Boolean DecodePseudo(void) BEGIN Boolean ValOK; Word Size,Value,t,z; if (Memo("SFR")) BEGIN CodeEquate(SegData,0,0xff); return True; END; if (Memo("ADDR")) BEGIN strcpy(OpPart,"DB"); BigFlag=True; END if (Memo("ADDRW")) BEGIN strcpy(OpPart,"DW"); BigFlag=True; END if (Memo("BYTE")) strcpy(OpPart,"DB"); if (Memo("WORD")) strcpy(OpPart,"DW"); if ((Memo("DSB")) OR (Memo("DSW"))) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN FirstPassUnknown=False; Size=EvalIntExpression(ArgStr[1],UInt16,&ValOK); if (FirstPassUnknown) WrError(1820); if ((ValOK) AND (NOT FirstPassUnknown)) BEGIN DontPrint=True; if (Memo("DSW")) Size+=Size; CodeLen=Size; BookKeeping(); END END return True; END if (Memo("FB")) BEGIN if (ArgCnt!=2) WrError(1110); else BEGIN FirstPassUnknown=False; Size=EvalIntExpression(ArgStr[1],UInt16,&ValOK); if (FirstPassUnknown) WrError(1820); if ((ValOK) AND (NOT FirstPassUnknown)) if (Size>MaxCodeLen) WrError(1920); else BEGIN BAsmCode[0]=EvalIntExpression(ArgStr[2],Int8,&ValOK); if (ValOK) BEGIN CodeLen=Size; memset(BAsmCode+1,BAsmCode[0],Size-1); END END END return True; END if (Memo("FW")) BEGIN if (ArgCnt!=2) WrError(1110); else BEGIN FirstPassUnknown=False; Size=EvalIntExpression(ArgStr[1],UInt16,&ValOK); if (FirstPassUnknown) WrError(1820); if ((ValOK) AND (NOT FirstPassUnknown)) if ((Size << 1)>MaxCodeLen) WrError(1920); else BEGIN Value=EvalIntExpression(ArgStr[2],Int16,&ValOK); if (ValOK) BEGIN CodeLen=Size << 1; t=0; for (z=0; z=0xf0) BEGIN BAsmCode[0]=HReg-0x20; BAsmCode[1]=AdrVal; CodeLen=2; END else BEGIN BAsmCode[0]=0xbc; BAsmCode[1]=HReg; BAsmCode[2]=AdrVal; CodeLen=3; END break; case ModBInd: DecodeAdr(ArgStr[2],MModImm); if (AdrMode!=ModNone) BEGIN BAsmCode[0]=0x9e; BAsmCode[1]=AdrVal; CodeLen=2; END break; case ModBInc: DecodeAdr(ArgStr[2],MModImm); if (AdrMode!=ModNone) BEGIN BAsmCode[0]=0x9a; BAsmCode[1]=AdrVal; CodeLen=2; END break; case ModBDec: DecodeAdr(ArgStr[2],MModImm); if (AdrMode!=ModNone) BEGIN BAsmCode[0]=0x9b; BAsmCode[1]=AdrVal; CodeLen=2; END break; END END return; END if (Memo("X")) BEGIN if (ArgCnt!=2) WrError(1110); else BEGIN if (strcasecmp(ArgStr[1],"A")!=0) BEGIN strcpy(ArgStr[3],ArgStr[1]); strcpy(ArgStr[1],ArgStr[2]); strcpy(ArgStr[2],ArgStr[3]); END DecodeAdr(ArgStr[1],MModAcc); if (AdrMode!=ModNone) BEGIN DecodeAdr(ArgStr[2],MModDir+MModBInd+MModXInd+MModBInc+MModXInc+MModBDec+MModXDec); switch (AdrMode) BEGIN case ModDir: BAsmCode[0]=0x9c; BAsmCode[1]=AdrVal; CodeLen=2; break; case ModBInd: BAsmCode[0]=0xa6; CodeLen=1; break; case ModBInc: BAsmCode[0]=0xa2; CodeLen=1; break; case ModBDec: BAsmCode[0]=0xa3; CodeLen=1; break; case ModXInd: BAsmCode[0]=0xb6; CodeLen=1; break; case ModXInc: BAsmCode[0]=0xb2; CodeLen=1; break; case ModXDec: BAsmCode[0]=0xb3; CodeLen=1; break; END END END return; END /* Arithmetik */ for (z=0; z> 12)!=(AdrWord >> 12)) WrError(1910); else BEGIN ChkSpace(SegCode); BAsmCode[0]=0x20+(Ord(Memo("JSR")) << 4)+((AdrWord >> 8) & 15); BAsmCode[1]=Lo(AdrWord); CodeLen=2; END END return; END if ((Memo("JMPL")) OR (Memo("JSRL"))) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN AdrWord=EvalIntExpression(ArgStr[1],UInt16,&OK); if (OK) BEGIN ChkSpace(SegCode); BAsmCode[0]=0xac+Ord(Memo("JSRL")); BAsmCode[1]=Hi(AdrWord); BAsmCode[2]=Lo(AdrWord); CodeLen=3; END END return; END if (Memo("JP")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN AdrInt=EvalIntExpression(ArgStr[1],UInt16,&OK)-(EProgCounter()+1); if (OK) if (AdrInt==0) BEGIN BAsmCode[0]=NOPCode; CodeLen=1; WrError(60); END else if (((AdrInt>31) OR (AdrInt<-32)) AND (NOT SymbolQuestionable)) WrError(1370); else BEGIN BAsmCode[0]=AdrInt & 0xff; CodeLen=1; END END return; END if (Memo("DRSZ")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN FirstPassUnknown=False; DecodeAdr(ArgStr[1],MModDir); if (FirstPassUnknown) AdrVal|=0xf0; if (AdrVal<0xf0) WrError(1315); else BEGIN BAsmCode[0]=AdrVal-0x30; CodeLen=1; END END return; END WrXError(1200,OpPart); END static Boolean IsDef_COP8(void) BEGIN return (Memo("SFR")); END static void SwitchFrom_COP8(void) BEGIN DeinitFields(); END static void SwitchTo_COP8(void) BEGIN TurnWords=False; ConstMode=ConstModeC; SetIsOccupied=False; PCSymbol="."; HeaderID=0x6f; NOPCode=0xb8; DivideChars=","; HasAttrs=False; ValidSegs=(1<