/* code9900.h */ /*****************************************************************************/ /* AS-Portierung */ /* */ /* Codegenerator TMS99xx */ /* */ /* Historie: 9. 3.1997 Grundsteinlegung */ /* 18. 8.1998 BookKeeping-Aufruf bei BSS */ /* 2. 1.1999 ChkPC angepasst */ /* */ /*****************************************************************************/ #include "stdinc.h" #include #include #include "strutil.h" #include "endian.h" #include "bpemu.h" #include "nls.h" #include "chunks.h" #include "asmdef.h" #include "asmsub.h" #include "asmpars.h" #include "asmallg.h" #include "codepseudo.h" #include "codevars.h" #define TwoOrderCount 6 #define OneOrderCount 6 #define SingOrderCount 16 #define SBitOrderCount 3 #define JmpOrderCount 13 #define ShiftOrderCount 4 #define ImmOrderCount 5 #define RegOrderCount 4 #define FixedOrderCount 6 typedef struct { char *Name; int NameLen; Word Code; } FixedOrder; typedef struct { char *Name; int NameLen; Word Code; Boolean MustSup; } SupOrder; static CPUVar CPU9900; static Boolean IsWord; static Word AdrVal,AdrPart; static FixedOrder *TwoOrders; static FixedOrder *OneOrders; static SupOrder *SingOrders; static FixedOrder *SBitOrders; static FixedOrder *JmpOrders; static FixedOrder *ShiftOrders; static FixedOrder *ImmOrders; static FixedOrder *RegOrders; static SupOrder *FixedOrders; /*-------------------------------------------------------------------------*/ /* dynamische Belegung/Freigabe Codetabellen */ static void AddTwo(char *NName, Word NCode) BEGIN if (InstrZ>=TwoOrderCount) exit(255); TwoOrders[InstrZ].Name=NName; TwoOrders[InstrZ].Code=NCode; TwoOrders[InstrZ++].NameLen=strlen(NName); END static void AddOne(char *NName, Word NCode) BEGIN if (InstrZ>=OneOrderCount) exit(255); OneOrders[InstrZ].Name=NName; OneOrders[InstrZ++].Code=NCode; END static void AddSing(char *NName, Word NCode,Boolean NSup) BEGIN if (InstrZ>=SingOrderCount) exit(255); SingOrders[InstrZ].Name=NName; SingOrders[InstrZ].MustSup=NSup; SingOrders[InstrZ++].Code=NCode; END static void AddSBit(char *NName, Word NCode) BEGIN if (InstrZ>=SBitOrderCount) exit(255); SBitOrders[InstrZ].Name=NName; SBitOrders[InstrZ++].Code=NCode; END static void AddJmp(char *NName, Word NCode) BEGIN if (InstrZ>=JmpOrderCount) exit(255); JmpOrders[InstrZ].Name=NName; JmpOrders[InstrZ++].Code=NCode; END static void AddShift(char *NName, Word NCode) BEGIN if (InstrZ>=ShiftOrderCount) exit(255); ShiftOrders[InstrZ].Name=NName; ShiftOrders[InstrZ++].Code=NCode; END static void AddImm(char *NName, Word NCode) BEGIN if (InstrZ>=ImmOrderCount) exit(255); ImmOrders[InstrZ].Name=NName; ImmOrders[InstrZ++].Code=NCode; END static void AddReg(char *NName, Word NCode) BEGIN if (InstrZ>=RegOrderCount) exit(255); RegOrders[InstrZ].Name=NName; RegOrders[InstrZ++].Code=NCode; END static void AddFixed(char *NName, Word NCode, Boolean NSup) BEGIN if (InstrZ>=FixedOrderCount) exit(255); FixedOrders[InstrZ].Name=NName; FixedOrders[InstrZ].MustSup=NSup; FixedOrders[InstrZ++].Code=NCode; END static void InitFields(void) BEGIN TwoOrders=(FixedOrder *) malloc(TwoOrderCount*sizeof(FixedOrder)); InstrZ=0; AddTwo("A" ,5); AddTwo("C" ,4); AddTwo("S" ,3); AddTwo("SOC" ,7); AddTwo("SZC" ,2); AddTwo("MOV" ,6); OneOrders=(FixedOrder *) malloc(OneOrderCount*sizeof(FixedOrder)); InstrZ=0; AddOne("COC" ,0x08); AddOne("CZC" ,0x09); AddOne("XOR" ,0x0a); AddOne("MPY" ,0x0e); AddOne("DIV" ,0x0f); AddOne("XOP" ,0x0b); SingOrders=(SupOrder *) malloc(SingOrderCount*sizeof(SupOrder)); InstrZ=0; AddSing("B" ,0x0440,False); AddSing("BL" ,0x0680,False); AddSing("BLWP",0x0400,False); AddSing("CLR" ,0x04c0,False); AddSing("SETO",0x0700,False); AddSing("INV" ,0x0540,False); AddSing("NEG" ,0x0500,False); AddSing("ABS" ,0x0740,False); AddSing("SWPB",0x06c0,False); AddSing("INC" ,0x0580,False); AddSing("INCT",0x05c0,False); AddSing("DEC" ,0x0600,False); AddSing("DECT",0x0640,True ); AddSing("X" ,0x0480,False); AddSing("LDS" ,0x0780,True ); AddSing("LDD" ,0x07c0,True ); SBitOrders=(FixedOrder *) malloc(SBitOrderCount*sizeof(FixedOrder)); InstrZ=0; AddSBit("SBO" ,0x1d); AddSBit("SBZ",0x1e); AddSBit("TB" ,0x1f); JmpOrders=(FixedOrder *) malloc(JmpOrderCount*sizeof(FixedOrder)); InstrZ=0; AddJmp("JEQ",0x13); AddJmp("JGT",0x15); AddJmp("JH" ,0x1b); AddJmp("JHE",0x14); AddJmp("JL" ,0x1a); AddJmp("JLE",0x12); AddJmp("JLT",0x11); AddJmp("JMP",0x10); AddJmp("JNC",0x17); AddJmp("JNE",0x16); AddJmp("JNO",0x19); AddJmp("JOC",0x18); AddJmp("JOP",0x1c); ShiftOrders=(FixedOrder *) malloc(ShiftOrderCount*sizeof(FixedOrder)); InstrZ=0; AddShift("SLA",0x0a); AddShift("SRA",0x08); AddShift("SRC",0x0b); AddShift("SRL",0x09); ImmOrders=(FixedOrder *) malloc(ImmOrderCount*sizeof(FixedOrder)); InstrZ=0; AddImm("AI" ,0x011); AddImm("ANDI",0x012); AddImm("CI" ,0x014); AddImm("LI" ,0x010); AddImm("ORI" ,0x013); RegOrders=(FixedOrder *) malloc(RegOrderCount*sizeof(FixedOrder)); InstrZ=0; AddReg("STST",0x02c); AddReg("LST",0x008); AddReg("STWP",0x02a); AddReg("LWP",0x009); FixedOrders=(SupOrder *) malloc(FixedOrderCount*sizeof(SupOrder)); InstrZ=0; AddFixed("RTWP",0x0380,False); AddFixed("IDLE",0x0340,True ); AddFixed("RSET",0x0360,True ); AddFixed("CKOF",0x03c0,True ); AddFixed("CKON",0x03a0,True ); AddFixed("LREX",0x03e0,True ); END static void DeinitFields(void) BEGIN free(TwoOrders); free(OneOrders); free(SingOrders); free(SBitOrders); free(JmpOrders); free(ShiftOrders); free(ImmOrders); free(RegOrders); free(FixedOrders); END /*-------------------------------------------------------------------------*/ /* Adressparser */ static Boolean DecodeReg(char *Asc, Word *Erg) BEGIN Boolean OK; *Erg=EvalIntExpression(Asc,UInt4,&OK); return OK; END static char *HasDisp(char *Asc) BEGIN char *p; int Lev; if (Asc[strlen(Asc)-1]==')') BEGIN p=Asc+strlen(Asc)-2; Lev=0; while ((p>=Asc) AND (Lev!=-1)) BEGIN switch (*p) BEGIN case '(': Lev--; break; case ')': Lev++; break; END if (Lev!=-1) p--; END if (Lev!=-1) BEGIN WrError(1300); p=Nil; END END else p=Nil; return p; END static Boolean DecodeAdr(char *Asc) BEGIN Boolean IncFlag; String Reg; Boolean OK; char *p; AdrCnt=0; if (*Asc=='*') BEGIN Asc++; if (Asc[strlen(Asc)-1]=='+') BEGIN IncFlag=True; Asc[strlen(Asc)-1]='\0'; END else IncFlag=False; if (DecodeReg(Asc,&AdrPart)) BEGIN AdrPart+=0x10+(Ord(IncFlag) << 5); return True; END return False; END if (*Asc=='@') BEGIN Asc++; p=HasDisp(Asc); if (p==Nil) BEGIN FirstPassUnknown=False; AdrVal=EvalIntExpression(Asc,UInt16,&OK); if (OK) BEGIN AdrPart=0x20; AdrCnt=1; if ((NOT FirstPassUnknown) AND (IsWord) AND (Odd(AdrVal))) WrError(180); return True; END END else BEGIN strmaxcpy(Reg,p+1,255); Reg[strlen(Reg)-1]='\0'; if (DecodeReg(Reg,&AdrPart)) if (AdrPart==0) WrXError(1445,Reg); else BEGIN *p='\0'; AdrVal=EvalIntExpression(Asc,Int16,&OK); if (OK) BEGIN AdrPart+=0x20; AdrCnt=1; return True; END END END return False; END if (DecodeReg(Asc,&AdrPart)) return True; else BEGIN WrError(1350); return False; END END /*-------------------------------------------------------------------------*/ static void PutByte(Byte Value) BEGIN if (((CodeLen&1)==1) AND (NOT BigEndian)) BEGIN BAsmCode[CodeLen]=BAsmCode[CodeLen-1]; BAsmCode[CodeLen-1]=Value; END else BEGIN BAsmCode[CodeLen]=Value; END CodeLen++; END static Boolean DecodePseudo(void) BEGIN int z; char *p; Boolean OK; TempResult t; Word HVal16; if (Memo("BYTE")) BEGIN if (ArgCnt==0) WrError(1110); else BEGIN z=1; OK=True; do BEGIN KillBlanks(ArgStr[z]); FirstPassUnknown=False; EvalExpression(ArgStr[z],&t); switch (t.Typ) BEGIN case TempInt: if (FirstPassUnknown) t.Contents.Int&=0xff; if (NOT RangeCheck(t.Contents.Int,Int8)) WrError(1320); else if (CodeLen==MaxCodeLen) BEGIN WrError(1920); OK=False; END else PutByte(t.Contents.Int); break; case TempFloat: WrError(1135); OK=False; break; case TempString: if (strlen(t.Contents.Ascii)+CodeLen>=MaxCodeLen) BEGIN WrError(1920); OK=False; END else BEGIN TranslateString(t.Contents.Ascii); for (p=t.Contents.Ascii; *p!='\0'; PutByte(*(p++))); END break; case TempNone: OK=False; break; END z++; END while ((z<=ArgCnt) AND (OK)); if (NOT OK) CodeLen=0; else if ((Odd(CodeLen)) AND (DoPadding)) PutByte(0); END return True; END if (Memo("WORD")) BEGIN if (ArgCnt==0) WrError(1110); else BEGIN z=1; OK=True; do BEGIN HVal16=EvalIntExpression(ArgStr[z],Int16,&OK); if (OK) BEGIN WAsmCode[CodeLen >> 1]=HVal16; CodeLen+=2; END z++; END while ((z<=ArgCnt) AND (OK)); if (NOT OK) CodeLen=0; END return True; END if (Memo("BSS")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN FirstPassUnknown=False; HVal16=EvalIntExpression(ArgStr[1],Int16,&OK); if (FirstPassUnknown) WrError(1820); else if (OK) BEGIN if ((DoPadding) AND (Odd(HVal16))) HVal16++; DontPrint=True; CodeLen=HVal16; BookKeeping(); END END return True; END return False; END static void MakeCode_9900(void) BEGIN Word HPart; Integer AdrInt; int z; Boolean OK; CodeLen=0; DontPrint=False; IsWord=False; /* zu ignorierendes */ if (Memo("")) return; /* Pseudoanweisungen */ if (DecodePseudo()) return; /* zwei Operanden */ for (z=0; z254))) WrError(1370); else BEGIN WAsmCode[0]=((AdrInt>>1) & 0xff) | (JmpOrders[z].Code << 8); CodeLen=2; END END; return; END if ((Memo("LWPI")) OR (Memo("LIMI"))) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN WAsmCode[1]=EvalIntExpression(ArgStr[1],UInt16,&OK); if (OK) BEGIN WAsmCode[0]=(0x017+Ord(Memo("LIMI"))) << 5; CodeLen=4; END END return; END /* kein Operand */ for (z=0; zTyp=TempNone; if ((strlen(Asc)>=2) AND (toupper(*Asc)=='R')) h=Asc+1; else if ((strlen(Asc)>=3) AND (toupper(*Asc)=='W') AND (toupper(Asc[1])=='R')) h=Asc+2; Erg->Contents.Int=ConstLongInt(h,&err); if ((NOT err) OR (Erg->Contents.Int<0) OR (Erg->Contents.Int>15)) return; Erg->Typ=TempInt; END static void SwitchTo_9900() BEGIN TurnWords=True; ConstMode=ConstModeIntel; SetIsOccupied=False; PCSymbol="$"; HeaderID=0x48; NOPCode=0x0000; DivideChars=","; HasAttrs=False; ValidSegs=1<