/* code370.c */ /*****************************************************************************/ /* AS-Portierung */ /* */ /* Codegenerator 370-Familie */ /* */ /* Historie: 10.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; #define ModNone (-1) #define ModAccA 0 #define MModAccA (1 << ModAccA) /* A */ #define ModAccB 1 #define MModAccB (1 << ModAccB) /* B */ #define ModReg 2 #define MModReg (1 << ModReg) /* Rn */ #define ModPort 3 #define MModPort (1 << ModPort) /* Pn */ #define ModAbs 4 #define MModAbs (1 << ModAbs) /* nnnn */ #define ModBRel 5 #define MModBRel (1 << ModBRel) /* nnnn(B) */ #define ModSPRel 6 #define MModSPRel (1 << ModSPRel) /* nn(SP) */ #define ModIReg 7 #define MModIReg (1 << ModIReg) /* @Rn */ #define ModRegRel 8 #define MModRegRel (1 << ModRegRel) /* nn(Rn) */ #define ModImm 9 #define MModImm (1 << ModImm) /* #nn */ #define ModImmBRel 10 #define MModImmBRel (1 << ModImmBRel) /* #nnnn(B) */ #define ModImmRegRel 11 #define MModImmRegRel (1 << ModImmRegRel) /* #nn(Rm) */ #define FixedOrderCount 12 #define Rel8OrderCount 18 #define ALU1OrderCount 7 #define ALU2OrderCount 5 #define JmpOrderCount 4 #define ABRegOrderCount 14 #define BitOrderCount 5 static CPUVar CPU37010,CPU37020,CPU37030,CPU37040,CPU37050; static Byte OpSize; static ShortInt AdrType; static Byte AdrVals[2]; static Boolean AddrRel; static FixedOrder *FixedOrders; static FixedOrder *Rel8Orders; static FixedOrder *ALU1Orders; static FixedOrder *ALU2Orders; static FixedOrder *JmpOrders; static FixedOrder *ABRegOrders; static FixedOrder *BitOrders; /****************************************************************************/ static void InitFixed(char *NName, Word NCode) BEGIN if (InstrZ>=FixedOrderCount) exit(255); FixedOrders[InstrZ].Name=NName; FixedOrders[InstrZ++].Code=NCode; END static void InitRel8(char *NName, Word NCode) BEGIN if (InstrZ>=Rel8OrderCount) exit(255); Rel8Orders[InstrZ].Name=NName; Rel8Orders[InstrZ++].Code=NCode; END static void InitALU1(char *NName, Word NCode) BEGIN if (InstrZ>=ALU1OrderCount) exit(255); ALU1Orders[InstrZ].Name=NName; ALU1Orders[InstrZ++].Code=NCode; END static void InitALU2(char *NName, Word NCode) BEGIN if (InstrZ>=ALU2OrderCount) exit(255); ALU2Orders[InstrZ].Name=NName; ALU2Orders[InstrZ++].Code=NCode; END static void InitJmp(char *NName, Word NCode) BEGIN if (InstrZ>=JmpOrderCount) exit(255); JmpOrders[InstrZ].Name=NName; JmpOrders[InstrZ++].Code=NCode; END static void InitABReg(char *NName, Word NCode) BEGIN if (InstrZ>=ABRegOrderCount) exit(255); ABRegOrders[InstrZ].Name=NName; ABRegOrders[InstrZ++].Code=NCode; END static void InitBit(char *NName, Word NCode) BEGIN if (InstrZ>=BitOrderCount) exit(255); BitOrders[InstrZ].Name=NName; BitOrders[InstrZ++].Code=NCode; END static void InitFields(void) BEGIN FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCount); InstrZ=0; InitFixed("CLRC" ,0x00b0); InitFixed("DINT" ,0xf000); InitFixed("EINT" ,0xf00c); InitFixed("EINTH",0xf004); InitFixed("EINTL",0xf008); InitFixed("IDLE" ,0x00f6); InitFixed("LDSP" ,0x00fd); InitFixed("NOP" ,0x00ff); InitFixed("RTI" ,0x00fa); InitFixed("RTS" ,0x00f9); InitFixed("SETC" ,0x00f8); InitFixed("STSP" ,0x00fe); Rel8Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*Rel8OrderCount); InstrZ=0; InitRel8("JMP",0x00); InitRel8("JC" ,0x03); InitRel8("JEQ",0x02); InitRel8("JG" ,0x0e); InitRel8("JGE",0x0d); InitRel8("JHS",0x0b); InitRel8("JL" ,0x09); InitRel8("JLE",0x0a); InitRel8("JLO",0x0f); InitRel8("JN" ,0x01); InitRel8("JNC",0x07); InitRel8("JNE",0x06); InitRel8("JNV",0x0c); InitRel8("JNZ",0x06); InitRel8("JP" ,0x04); InitRel8("JPZ",0x05); InitRel8("JV" ,0x08); InitRel8("JZ" ,0x02); ALU1Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*ALU1OrderCount); InstrZ=0; InitALU1("ADC", 9); InitALU1("ADD", 8); InitALU1("DAC",14); InitALU1("DSB",15); InitALU1("SBB",11); InitALU1("SUB",10); InitALU1("MPY",12); ALU2Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*ALU2OrderCount); InstrZ=0; InitALU2("AND" , 3); InitALU2("BTJO", 6); InitALU2("BTJZ", 7); InitALU2("OR" , 4); InitALU2("XOR", 5); JmpOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*JmpOrderCount); InstrZ=0; InitJmp("BR" ,12); InitJmp("CALL" ,14); InitJmp("JMPL", 9); InitJmp("CALLR",15); ABRegOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*ABRegOrderCount); InstrZ=0; InitABReg("CLR" , 5); InitABReg("COMPL",11); InitABReg("DEC" , 2); InitABReg("INC" , 3); InitABReg("INV" , 4); InitABReg("POP" , 9); InitABReg("PUSH" , 8); InitABReg("RL" ,14); InitABReg("RLC" ,15); InitABReg("RR" ,12); InitABReg("RRC" ,13); InitABReg("SWAP" , 7); InitABReg("XCHB" , 6); InitABReg("DJNZ" ,10); BitOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*BitOrderCount); InstrZ=0; InitBit("CMPBIT", 5); InitBit("JBIT0" , 7); InitBit("JBIT1" , 6); InitBit("SBIT0" , 3); InitBit("SBIT1" , 4); END static void DeinitFields(void) BEGIN free(FixedOrders); free(Rel8Orders); free(ALU1Orders); free(ALU2Orders); free(JmpOrders); free(ABRegOrders); free(BitOrders); END static void ChkAdr(Word Mask) BEGIN if ((AdrType!=-1) AND ((Mask & (1 << AdrType))==0)) BEGIN WrError(1350); AdrType=ModNone; AdrCnt=0; END 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 (p127) WrError(1320); else if (HVal<-128) WrError(1315); else BEGIN AdrVals[0]=HVal & 0xff; AdrCnt=1; AdrType=ModSPRel; END END else if (HVal>127) WrError(1320); else if (HVal<-128) WrError(1315); else BEGIN AdrVals[0]=HVal & 0xff; AdrVals[1]=EvalIntExpression(p,Int8,&OK); if (OK) BEGIN AdrCnt=2; AdrType=ModRegRel; END END END ChkAdr(Mask); return; END END static Boolean DecodePseudo(void) BEGIN Boolean OK; Byte Bit; Word Adr; if (Memo("DBIT")) BEGIN if (ArgCnt!=2) WrError(1110); else BEGIN FirstPassUnknown=False; Bit=EvalIntExpression(ArgStr[1],UInt3,&OK); if ((OK) AND (NOT FirstPassUnknown)) BEGIN if ((strcasecmp(ArgStr[2],"A")==0) OR (strcasecmp(ArgStr[2],"B")==0)) BEGIN Adr=(*ArgStr[2])-'A'; OK=True; END else Adr=EvalIntExpression(ArgStr[2],Int16,&OK); if ((OK) AND (NOT FirstPassUnknown)) BEGIN PushLocHandle(-1); EnterIntSymbol(LabPart,(((LongInt)Bit) << 16)+Adr,SegNone,False); sprintf(ListLine,"=%s:%c",HexString(Adr,0),Bit+'0'); PopLocHandle(); END END END return True; END return False; END static void PutCode(Word Code) BEGIN if (Hi(Code)==0) BEGIN CodeLen=1; BAsmCode[0]=Code; END else BEGIN CodeLen=2; BAsmCode[0]=Hi(Code); BAsmCode[1]=Lo(Code); END END static void MakeCode_370(void) BEGIN int z; Integer AdrInt; LongInt Bit; Boolean OK,Rela; CodeLen=0; DontPrint=False; OpSize=0; AddrRel=False; /* zu ignorierendes */ if (Memo("")) return; /* Pseudoanweisungen */ if (DecodePseudo()) return; if (DecodeIntelPseudo(True)) return; for (z=0; z127) OR (AdrInt<-128))) WrError(1370); else BEGIN CodeLen=2; BAsmCode[0]=Rel8Orders[z].Code; BAsmCode[1]=AdrInt & 0xff; END END return; END if (Memo("CMP")) BEGIN if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[2],MModAccA+MModAccB+MModReg); switch (AdrType) BEGIN case ModAccA: DecodeAdr(ArgStr[1],MModAbs+MModIReg+MModBRel+MModRegRel+MModSPRel+MModAccB+MModReg+MModImm); switch (AdrType) BEGIN case ModAbs: BAsmCode[0]=0x8d; memcpy(BAsmCode+1,AdrVals,2); CodeLen=3; break; case ModIReg: BAsmCode[0]=0x9d; BAsmCode[1]=AdrVals[0]; CodeLen=2; break; case ModBRel: BAsmCode[0]=0xad; memcpy(BAsmCode+1,AdrVals,2); CodeLen=3; break; case ModRegRel: BAsmCode[0]=0xf4; BAsmCode[1]=0xed; memcpy(BAsmCode+2,AdrVals,2); CodeLen=4; break; case ModSPRel: BAsmCode[0]=0xf3; BAsmCode[1]=AdrVals[0]; CodeLen=2; break; case ModAccB: BAsmCode[0]=0x6d; CodeLen=1; break; case ModReg: BAsmCode[0]=0x1d; BAsmCode[1]=AdrVals[0]; CodeLen=2; break; case ModImm: BAsmCode[0]=0x2d; BAsmCode[1]=AdrVals[0]; CodeLen=2; break; END break; case ModAccB: DecodeAdr(ArgStr[1],MModReg+MModImm); switch (AdrType) BEGIN case ModReg: BAsmCode[0]=0x3d; BAsmCode[1]=AdrVals[0]; CodeLen=2; break; case ModImm: BAsmCode[0]=0x5d; BAsmCode[1]=AdrVals[0]; CodeLen=2; break; END break; case ModReg: BAsmCode[2]=AdrVals[0]; DecodeAdr(ArgStr[1],MModReg+MModImm); switch (AdrType) BEGIN case ModReg: BAsmCode[0]=0x4d; BAsmCode[1]=AdrVals[0]; CodeLen=3; break; case ModImm: BAsmCode[0]=0x7d; BAsmCode[1]=AdrVals[0]; CodeLen=3; break; END break; END END return; END for (z=0; z127) OR (AdrInt<-128))) BEGIN WrError(1370); CodeLen=0; END else BAsmCode[CodeLen++]=AdrInt & 0xff; END END return; END for (z=0; z127) OR (AdrInt<-128))) BEGIN WrError(1370); CodeLen=0; END else BAsmCode[CodeLen++]=AdrInt & 0xff; END END return; END for (z=0; z> 16) & 7); BAsmCode[2]=Lo(Bit); switch (Hi(Bit)) BEGIN case 0: BAsmCode[0]=0x70+BitOrders[z].Code; CodeLen=3; break; case 16: BAsmCode[0]=0xa0+BitOrders[z].Code; CodeLen=3; break; default: WrError(1350); END if ((CodeLen!=0) AND (Rela)) BEGIN AdrInt=EvalIntExpression(ArgStr[2],Int16,&OK)-(EProgCounter()+CodeLen+1); if (NOT OK) CodeLen=0; else if ((NOT FirstPassUnknown) AND ((AdrInt>127) OR (AdrInt<-128))) BEGIN WrError(1370); CodeLen=0; END else BAsmCode[CodeLen++]=AdrInt & 0xff; END END END return; END if (Memo("DIV")) BEGIN if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[2],MModAccA); if (AdrType!=ModNone) BEGIN DecodeAdr(ArgStr[1],MModReg); if (AdrType!=ModNone) BEGIN BAsmCode[0]=0xf4; BAsmCode[1]=0xf8; BAsmCode[2]=AdrVals[0]; CodeLen=3; END END END return; END if (Memo("INCW")) BEGIN if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[2],MModReg); if (AdrType!=ModNone) BEGIN BAsmCode[2]=AdrVals[0]; DecodeAdr(ArgStr[1],MModImm); if (AdrType!=ModNone) BEGIN BAsmCode[0]=0x70; BAsmCode[1]=AdrVals[0]; CodeLen=3; END END END return; END if (Memo("LDST")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN DecodeAdr(ArgStr[1],MModImm); if (AdrType!=ModNone) BEGIN BAsmCode[0]=0xf0; BAsmCode[1]=AdrVals[0]; CodeLen=2; END END return; END if (Memo("TRAP")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN BAsmCode[0]=EvalIntExpression(ArgStr[1],Int4,&OK); if (OK) BEGIN BAsmCode[0]=0xef-BAsmCode[0]; CodeLen=1; END END return; END if (Memo("TST")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN DecodeAdr(ArgStr[1],MModAccA+MModAccB); switch (AdrType) BEGIN case ModAccA: BAsmCode[0]=0xb0; CodeLen=1; break; case ModAccB: BAsmCode[0]=0xc6; CodeLen=1; break; END END return; END WrXError(1200,OpPart); END static Boolean IsDef_370(void) BEGIN return (Memo("DBIT")); END static void InternSymbol_370(char *Asc, TempResult*Erg) BEGIN Boolean err; String h; Erg->Typ=TempNone; if ((strlen(Asc)<2) OR ((toupper(*Asc)!='R') AND (toupper(*Asc)!='P'))) return; strcpy(h,Asc+1); if ((*h=='0') AND (strlen(h)>1)) *h='$'; Erg->Contents.Int=ConstLongInt(h,&err); if ((NOT err) OR (Erg->Contents.Int<0) OR (Erg->Contents.Int>255)) return; Erg->Typ=TempInt; if (toupper(*Asc)=='P') Erg->Contents.Int+=0x1000; END static void SwitchFrom_370(void) BEGIN DeinitFields(); END static void SwitchTo_370(void) BEGIN TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False; PCSymbol="$"; HeaderID=0x49; NOPCode=0xff; DivideChars=","; HasAttrs=False; ValidSegs=1<