/* code3201x.c */ /*****************************************************************************/ /* AS-Portierung */ /* */ /* Codegenerator TMS3201x-Familie */ /* */ /* Historie: 28.11.1996 Grundsteinlegung */ /* 7. 7.1998 Fix Zugriffe auf CharTransTable wg. signed chars */ /* 18. 8.1992 BookKeeping-Aufruf in RES */ /* 2. 1.1999 ChkPC-Anpassung */ /* */ /*****************************************************************************/ #include "stdinc.h" #include #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" typedef struct { char *Name; Word Code; } FixedOrder; typedef struct { char *Name; Word Code; Boolean Must1; } AdrOrder; typedef struct { char *Name; Word Code; Word AllowShifts; } AdrShiftOrder; typedef struct { char *Name; Word Code; Integer Min,Max; Word Mask; } ImmOrder; #define FixedOrderCnt 14 #define JmpOrderCnt 11 #define AdrOrderCnt 21 #define AdrShiftOrderCnt 5 #define ImmOrderCnt 3 static Word AdrMode; static Boolean AdrOK; static CPUVar CPU32010,CPU32015; static FixedOrder *FixedOrders; static FixedOrder *JmpOrders; static AdrOrder *AdrOrders; static AdrShiftOrder *AdrShiftOrders; static ImmOrder *ImmOrders; /*----------------------------------------------------------------------------*/ static void AddFixed(char *NName, Word NCode) BEGIN if (InstrZ>=FixedOrderCnt) exit(255); FixedOrders[InstrZ].Name=NName; FixedOrders[InstrZ++].Code=NCode; END static void AddJmp(char *NName, Word NCode) BEGIN if (InstrZ>=JmpOrderCnt) exit(255); JmpOrders[InstrZ].Name=NName; JmpOrders[InstrZ++].Code=NCode; END static void AddAdr(char *NName, Word NCode, Word NMust1) BEGIN if (InstrZ>=AdrOrderCnt) exit(255); AdrOrders[InstrZ].Name=NName; AdrOrders[InstrZ].Code=NCode; AdrOrders[InstrZ++].Must1=NMust1; END static void AddAdrShift(char *NName, Word NCode, Word NAllow) BEGIN if (InstrZ>=AdrShiftOrderCnt) exit(255); AdrShiftOrders[InstrZ].Name=NName; AdrShiftOrders[InstrZ].Code=NCode; AdrShiftOrders[InstrZ++].AllowShifts=NAllow; END static void AddImm(char *NName, Word NCode, Integer NMin, Integer NMax, Word NMask) BEGIN if (InstrZ>=ImmOrderCnt) exit(255); ImmOrders[InstrZ].Name=NName; ImmOrders[InstrZ].Code=NCode; ImmOrders[InstrZ].Min=NMin; ImmOrders[InstrZ].Max=NMax; ImmOrders[InstrZ++].Mask=NMask; END static void InitFields(void) BEGIN FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); InstrZ=0; AddFixed("ABS" , 0x7f88); AddFixed("APAC" , 0x7f8f); AddFixed("CALA" , 0x7f8c); AddFixed("DINT" , 0x7f81); AddFixed("EINT" , 0x7f82); AddFixed("NOP" , 0x7f80); AddFixed("PAC" , 0x7f8e); AddFixed("POP" , 0x7f9d); AddFixed("PUSH" , 0x7f9c); AddFixed("RET" , 0x7f8d); AddFixed("ROVM" , 0x7f8a); AddFixed("SOVM" , 0x7f8b); AddFixed("SPAC" , 0x7f90); AddFixed("ZAC" , 0x7f89); JmpOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*JmpOrderCnt); InstrZ=0; AddJmp("B" , 0xf900); AddJmp("BANZ" , 0xf400); AddJmp("BGEZ" , 0xfd00); AddJmp("BGZ" , 0xfc00); AddJmp("BIOZ" , 0xf600); AddJmp("BLEZ" , 0xfb00); AddJmp("BLZ" , 0xfa00); AddJmp("BNZ" , 0xfe00); AddJmp("BV" , 0xf500); AddJmp("BZ" , 0xff00); AddJmp("CALL" , 0xf800); AdrOrders=(AdrOrder *) malloc(sizeof(AdrOrder)*AdrOrderCnt); InstrZ=0; AddAdr("ADDH" , 0x6000, False); AddAdr("ADDS" , 0x6100, False); AddAdr("AND" , 0x7900, False); AddAdr("DMOV" , 0x6900, False); AddAdr("LDP" , 0x6f00, False); AddAdr("LST" , 0x7b00, False); AddAdr("LT" , 0x6a00, False); AddAdr("LTA" , 0x6c00, False); AddAdr("LTD" , 0x6b00, False); AddAdr("MAR" , 0x6800, False); AddAdr("MPY" , 0x6d00, False); AddAdr("OR" , 0x7a00, False); AddAdr("SST" , 0x7c00, True ); AddAdr("SUBC" , 0x6400, False); AddAdr("SUBH" , 0x6200, False); AddAdr("SUBS" , 0x6300, False); AddAdr("TBLR" , 0x6700, False); AddAdr("TBLW" , 0x7d00, False); AddAdr("XOR" , 0x7800, False); AddAdr("ZALH" , 0x6500, False); AddAdr("ZALS" , 0x6600, False); AdrShiftOrders=(AdrShiftOrder *) malloc(sizeof(AdrShiftOrder)*AdrShiftOrderCnt); InstrZ=0; AddAdrShift("ADD" , 0x0000, 0xffff); AddAdrShift("LAC" , 0x2000, 0xffff); AddAdrShift("SACH" , 0x5800, 0x0013); AddAdrShift("SACL" , 0x5000, 0x0001); AddAdrShift("SUB" , 0x1000, 0xffff); ImmOrders=(ImmOrder *) malloc(sizeof(ImmOrder)*ImmOrderCnt); InstrZ=0; AddImm("LACK", 0x7e00, 0, 255, 0xff); AddImm("LDPK", 0x6e00, 0, 1, 0x1); AddImm("MPYK", 0x8000, -4096, 4095, 0x1fff); END static void DeinitFields(void) BEGIN free(FixedOrders); free(JmpOrders); free(AdrOrders); free(AdrShiftOrders); free(ImmOrders); END /*----------------------------------------------------------------------------*/ static Word EvalARExpression(char *Asc, Boolean *OK) BEGIN *OK=True; if (strcasecmp(Asc,"AR0")==0) return 0; if (strcasecmp(Asc,"AR1")==0) return 1; return EvalIntExpression(Asc,UInt1,OK); END static void DecodeAdr(char *Arg, int Aux, Boolean Must1) BEGIN Byte h; char *p; AdrOK=False; if ((strcmp(Arg,"*")==0) OR (strcmp(Arg,"*-")==0) OR (strcmp(Arg,"*+")==0)) BEGIN AdrMode=0x88; if (strlen(Arg)==2) AdrMode+=(Arg[1]=='+') ? 0x20 : 0x10; if (Aux<=ArgCnt) BEGIN h=EvalARExpression(ArgStr[Aux],&AdrOK); if (AdrOK) BEGIN AdrMode&=0xf7; AdrMode+=h; END END else AdrOK=True; END else if (Aux<=ArgCnt) WrError(1110); else BEGIN h=0; if ((strlen(Arg)>3) AND (strncasecmp(Arg,"DAT",3)==0)) BEGIN AdrOK=True; for (p=Arg+3; *p!='\0'; p++) if ((*p>'9') OR (*p<'0')) AdrOK=False; if (AdrOK) h=EvalIntExpression(Arg+3,UInt8,&AdrOK); END if (NOT AdrOK) h=EvalIntExpression(Arg,Int8,&AdrOK); if (AdrOK) if ((Must1) AND (h<0x80) AND (NOT FirstPassUnknown)) BEGIN WrError(1315); AdrOK=False; END else BEGIN AdrMode=h & 0x7f; ChkSpace(SegData); END END END static Boolean DecodePseudo(void) BEGIN Word Size; int z,z2; char *p; TempResult t; Boolean OK; if (Memo("PORT")) BEGIN CodeEquate(SegIO,0,7); return True; END if (Memo("RES")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN FirstPassUnknown=False; Size=EvalIntExpression(ArgStr[1],Int16,&OK); if (FirstPassUnknown) WrError(1820); if ((OK) AND (NOT FirstPassUnknown)) BEGIN DontPrint=True; CodeLen=Size; BookKeeping(); END END return True; END if (Memo("DATA")) BEGIN if (ArgCnt==0) WrError(1110); else BEGIN OK=True; for (z=1; z<=ArgCnt; z++) if (OK) BEGIN EvalExpression(ArgStr[z],&t); switch (t.Typ) BEGIN case TempInt: if ((t.Contents.Int<-32768) OR (t.Contents.Int>0xffff)) BEGIN WrError(1320); OK=False; END else WAsmCode[CodeLen++]=t.Contents.Int; break; case TempFloat: WrError(1135); OK=False; break; case TempString: for (p=t.Contents.Ascii,z2=0; *p!='\0'; p++,z2++) BEGIN if ((z2&1)==0) WAsmCode[CodeLen]=CharTransTable[((usint)*p)&0xff]; else WAsmCode[CodeLen++]+=((Word) CharTransTable[((usint)*p)&0xff]) << 8; END if ((z2&1)==0) CodeLen++; break; default: OK=False; END END if (NOT OK) CodeLen=0; END return True; END return False; END static void MakeCode_3201X(void) BEGIN Boolean OK,HasSh; Word AdrWord; LongInt AdrLong; int z,Cnt; CodeLen=0; DontPrint=False; /* zu ignorierendes */ if (Memo("")) return; /* Pseudoanweisungen */ if (DecodePseudo()) return; /* kein Argument */ for (z=0; z2)) WrError(1110); else BEGIN DecodeAdr(ArgStr[1],2,AdrOrders[z].Must1); if (AdrOK) BEGIN CodeLen=1; WAsmCode[0]=AdrOrders[z].Code+AdrMode; END END return; END /* Adresse & schieben */ for (z=0; z3)) WrError(1110); else BEGIN if (*ArgStr[1]=='*') if (ArgCnt==2) if (strncasecmp(ArgStr[2],"AR",2)==0) BEGIN HasSh=False; Cnt=2; END else BEGIN HasSh=True; Cnt=3; END else BEGIN HasSh=True; Cnt=3; END else BEGIN Cnt=3; HasSh=(ArgCnt==2); END DecodeAdr(ArgStr[1],Cnt,False); if (AdrOK) BEGIN if (NOT HasSh) BEGIN OK=True; AdrWord=0; END else BEGIN AdrWord=EvalIntExpression(ArgStr[2],Int4,&OK); if ((OK) AND (FirstPassUnknown)) AdrWord=0; END if (OK) if ((AdrShiftOrders[z].AllowShifts & (1 << AdrWord))==0) WrError(1380); else BEGIN CodeLen=1; WAsmCode[0]=AdrShiftOrders[z].Code+AdrMode+(AdrWord << 8); END END END return; END /* Ein/Ausgabe */ if ((Memo("IN")) OR (Memo("OUT"))) BEGIN if ((ArgCnt<2) OR (ArgCnt>3)) WrError(1110); else BEGIN DecodeAdr(ArgStr[1],3,False); if (AdrOK) BEGIN AdrWord=EvalIntExpression(ArgStr[2],UInt3,&OK); if (OK) BEGIN ChkSpace(SegIO); CodeLen=1; WAsmCode[0]=0x4000+AdrMode+(AdrWord << 8); if (Memo("OUT")) WAsmCode[0]+=0x800; END END END return; END /* konstantes Argument */ for (z=0; zImmOrders[z].Max) WrError(1320); else BEGIN CodeLen=1; WAsmCode[0]=ImmOrders[z].Code+(AdrLong & ImmOrders[z].Mask); END END END return; END /* mit Hilfsregistern */ if (Memo("LARP")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN AdrWord=EvalARExpression(ArgStr[1],&OK); if (OK) BEGIN CodeLen=1; WAsmCode[0]=0x6880+AdrWord; END END return; END if ((Memo("LAR")) OR (Memo("SAR"))) BEGIN if ((ArgCnt<2) OR (ArgCnt>3)) WrError(1110); else BEGIN AdrWord=EvalARExpression(ArgStr[1],&OK); if (OK) BEGIN DecodeAdr(ArgStr[2],3,False); if (AdrOK) BEGIN CodeLen=1; WAsmCode[0]=0x3000+AdrMode+(AdrWord << 8); if (Memo("LAR")) WAsmCode[0]+=0x800; END END END return; END if (Memo("LARK")) BEGIN if (ArgCnt!=2) WrError(1110); else BEGIN AdrWord=EvalARExpression(ArgStr[1],&OK); if (OK) BEGIN WAsmCode[0]=EvalIntExpression(ArgStr[2],Int8,&OK); if (OK) BEGIN CodeLen=1; WAsmCode[0]=Lo(WAsmCode[0])+0x7000+(AdrWord << 8); END END END return; END WrXError(1200,OpPart); END static Boolean IsDef_3201X(void) BEGIN return (Memo("PORT")); END static void SwitchFrom_3201X(void) BEGIN DeinitFields(); END static void SwitchTo_3201X(void) BEGIN TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False; PCSymbol="$"; HeaderID=0x74; NOPCode=0x7f80; DivideChars=","; HasAttrs=False; ValidSegs=(1<