/* code48.c */ /*****************************************************************************/ /* AS-Portierung */ /* */ /* Codegeneratormodul MCS-48-Familie */ /* */ /* Historie: 16. 5.1996 Grundsteinlegung */ /* 2. 1.1999 ChkPC-Anpassung */ /* */ /*****************************************************************************/ #include "stdinc.h" #include #include #include "nls.h" #include "strutil.h" #include "stringlists.h" #include "asmdef.h" #include "asmsub.h" #include "asmpars.h" #include "codepseudo.h" #include "codevars.h" typedef struct { char *Name; Byte Code; Byte May2X; Byte UPIFlag; } CondOrder; typedef struct { char *Name; Byte Code; } AccOrder; typedef struct { char *Name; Byte Code; Boolean Is22; Boolean IsNUPI; } SelOrder; #define ModImm 0 #define ModReg 1 #define ModInd 2 #define ModAcc 3 #define ModNone (-1) #define ClrCplCnt 4 #define CondOrderCnt 22 #define AccOrderCnt 6 #define SelOrderCnt 6 #define D_CPU8021 0 #define D_CPU8022 1 #define D_CPU8039 2 #define D_CPU8048 3 #define D_CPU80C39 4 #define D_CPU80C48 5 #define D_CPU8041 6 #define D_CPU8042 7 static ShortInt AdrMode; static Byte AdrVal; static CPUVar CPU8021,CPU8022,CPU8039,CPU8048,CPU80C39,CPU80C48,CPU8041,CPU8042; static char **ClrCplVals; static Byte *ClrCplCodes; static CondOrder *CondOrders; static AccOrder *AccOrders; static SelOrder *SelOrders; /****************************************************************************/ static void AddAcc(char *Name, Byte Code) BEGIN if (InstrZ==AccOrderCnt) exit(255); AccOrders[InstrZ].Name=Name; AccOrders[InstrZ++].Code=Code; END static void AddCond(char *Name, Byte Code, Byte May2X, Byte UPIFlag) BEGIN if (InstrZ==CondOrderCnt) exit(255); CondOrders[InstrZ].Name=Name; CondOrders[InstrZ].Code=Code; CondOrders[InstrZ].May2X=May2X; CondOrders[InstrZ++].UPIFlag=UPIFlag; END static void AddSel(char *Name, Byte Code, Byte Is22, Byte IsNUPI) BEGIN if (InstrZ==SelOrderCnt) exit(255); SelOrders[InstrZ].Name=Name; SelOrders[InstrZ].Code=Code; SelOrders[InstrZ].Is22=Is22; SelOrders[InstrZ++].IsNUPI=IsNUPI; END static void InitFields(void) BEGIN ClrCplVals=(char **) malloc(sizeof(char *)*ClrCplCnt); ClrCplCodes=(Byte *) malloc(sizeof(Byte)*ClrCplCnt); ClrCplVals[0]="A"; ClrCplVals[1]="C"; ClrCplVals[2]="F0"; ClrCplVals[3]="F1"; ClrCplCodes[0]=0x27; ClrCplCodes[1]=0x97; ClrCplCodes[2]=0x85; ClrCplCodes[3]=0xa5; CondOrders=(CondOrder *) malloc(sizeof(CondOrder)*CondOrderCnt); InstrZ=0; AddCond("JTF" ,0x16, 2, 3); AddCond("JNI" ,0x86, 0, 2); AddCond("JC" ,0xf6, 2, 3); AddCond("JNC" ,0xe6, 2, 3); AddCond("JZ" ,0xc6, 2, 3); AddCond("JNZ" ,0x96, 2, 3); AddCond("JT0" ,0x36, 1, 3); AddCond("JNT0" ,0x26, 1, 3); AddCond("JT1" ,0x56, 2, 3); AddCond("JNT1" ,0x46, 2, 3); AddCond("JF0" ,0xb6, 0, 3); AddCond("JF1" ,0x76, 0, 3); AddCond("JNIBF",0xd6, 2, 1); AddCond("JOBF" ,0x86, 2, 1); AddCond("JB0" ,0x12, 0, 3); AddCond("JB1" ,0x32, 0, 3); AddCond("JB2" ,0x52, 0, 3); AddCond("JB3" ,0x72, 0, 3); AddCond("JB4" ,0x92, 0, 3); AddCond("JB5" ,0xb2, 0, 3); AddCond("JB6" ,0xd2, 0, 3); AddCond("JB7" ,0xf2, 0, 3); AccOrders=(AccOrder *) malloc(sizeof(AccOrder)*AccOrderCnt); InstrZ=0; AddAcc("DA" ,0x57); AddAcc("RL" ,0xe7); AddAcc("RLC" ,0xf7); AddAcc("RR" ,0x77); AddAcc("RRC" ,0x67); AddAcc("SWAP",0x47); SelOrders=(SelOrder *) malloc(sizeof(SelOrder)*SelOrderCnt); InstrZ=0; AddSel("MB0" ,0xe5, False, True ); AddSel("MB1" ,0xf5, False, True ); AddSel("RB0" ,0xc5, False, False); AddSel("RB1" ,0xd5, False, False); AddSel("AN0" ,0x95, True , False); AddSel("AN1" ,0x85, True , False); END static void DeinitFields(void) BEGIN free(ClrCplVals); free(ClrCplCodes); free(CondOrders); free(AccOrders); free(SelOrders); END /****************************************************************************/ static void DecodeAdr(char *Asc_O) BEGIN Boolean OK; String Asc; strmaxcpy(Asc,Asc_O,255); AdrMode=ModNone; if (*Asc=='\0') return; if (strcasecmp(Asc,"A")==0) AdrMode=ModAcc; else if (*Asc=='#') BEGIN AdrVal=EvalIntExpression(Asc+1,Int8,&OK); if (OK) BEGIN AdrMode=ModImm; BAsmCode[1]=AdrVal; END END else if ((strlen(Asc)==2) AND (toupper(*Asc)=='R')) BEGIN if ((Asc[1]>='0') AND (Asc[1]<='7')) BEGIN AdrMode=ModReg; AdrVal=Asc[1]-'0'; END END else if ((strlen(Asc)==3) AND (*Asc=='@') AND (toupper(Asc[1])=='R')) BEGIN if ((Asc[2]>='0') AND (Asc[2]<='1')) BEGIN AdrMode=ModInd; AdrVal=Asc[2]-'0'; END END END static void ChkN802X(void) BEGIN if (CodeLen==0) return; if ((MomCPU==CPU8021) OR (MomCPU==CPU8022)) BEGIN WrError(1500); CodeLen=0; END END static void Chk802X(void) BEGIN if (CodeLen==0) return; if ((MomCPU!=CPU8021) AND (MomCPU!=CPU8022)) BEGIN WrError(1500); CodeLen=0; END END static void ChkNUPI(void) BEGIN if (CodeLen==0) return; if ((MomCPU==CPU8041) OR (MomCPU==CPU8042)) BEGIN WrError(1500); CodeLen=0; END END static void ChkUPI(void) BEGIN if (CodeLen==0) return; if ((MomCPU!=CPU8041) AND (MomCPU!=CPU8042)) BEGIN WrError(1500); CodeLen=0; END END static void ChkExt(void) BEGIN if (CodeLen==0) return; if ((MomCPU==CPU8039) OR (MomCPU==CPU80C39)) BEGIN WrError(1500); CodeLen=0; END END static Boolean DecodePseudo(void) BEGIN return False; END void MakeCode_48(void) BEGIN Boolean OK; Word AdrWord; int z; CodeLen=0; DontPrint=False; /* zu ignorierendes */ if (Memo("")) return; /* Pseudoanweisungen */ if (DecodePseudo()) return; if (DecodeIntelPseudo(False)) return; if ((Memo("ADD")) OR (Memo("ADDC"))) BEGIN if (ArgCnt!=2) WrError(1110); else if (strcasecmp(ArgStr[1],"A")!=0) WrError(1135); else BEGIN DecodeAdr(ArgStr[2]); if ((AdrMode==ModNone) OR (AdrMode==ModAcc)) WrError(1350); else BEGIN switch (AdrMode) BEGIN case ModImm: CodeLen=2; BAsmCode[0]=0x03; break; case ModReg: CodeLen=1; BAsmCode[0]=0x68+AdrVal; break; case ModInd: CodeLen=1; BAsmCode[0]=0x60+AdrVal; break; END if (strlen(OpPart)==4) BAsmCode[0]+=0x10; END END return; END if ((Memo("ANL")) OR (Memo("ORL")) OR (Memo("XRL"))) BEGIN if (ArgCnt!=2) WrError(1110); else if (strcasecmp(ArgStr[1],"A")==0) BEGIN DecodeAdr(ArgStr[2]); if ((AdrMode==-1) OR (AdrMode==ModAcc)) WrError(1350); else BEGIN switch (AdrMode) BEGIN case ModImm: CodeLen=2; BAsmCode[0]=0x43; break; case ModReg: CodeLen=1; BAsmCode[0]=0x48+AdrVal; break; case ModInd: CodeLen=1; BAsmCode[0]=0x40+AdrVal; break; END if (Memo("ANL")) BAsmCode[0]+=0x10; else if (Memo("XRL")) BAsmCode[0]+=0x90; END END else if ((strcasecmp(ArgStr[1],"BUS")==0) OR (strcmp(ArgStr[1],"P1")==0) OR (strcmp(ArgStr[1],"P2")==0)) BEGIN if (Memo("XRL")) WrError(1350); else BEGIN DecodeAdr(ArgStr[2]); if (AdrMode!=ModImm) WrError(1350); else BEGIN CodeLen=2; BAsmCode[0]=0x88; if (toupper(*ArgStr[1])=='P') BAsmCode[0]+=ArgStr[1][1]-'0'; if (Memo("ANL")) BAsmCode[0]+=0x10; if (strcasecmp(ArgStr[1],"BUS")==0) BEGIN ChkExt(); ChkNUPI(); END ChkN802X(); END END END else WrError(1350); return; END if ((Memo("CALL")) OR (Memo("JMP"))) BEGIN if (ArgCnt!=1) WrError(1110); else if ((EProgCounter()&0x7fe)==0x7fe) WrError(1900); else BEGIN AdrWord=EvalIntExpression(ArgStr[1],Int16,&OK); if (OK) if (AdrWord>0xfff) WrError(1320); else BEGIN if ((EProgCounter()&0x800)!=(AdrWord&0x800)) BEGIN BAsmCode[0]=0xe5+((AdrWord&0x800)>>7); CodeLen=1; END BAsmCode[CodeLen+1]=AdrWord&0xff; BAsmCode[CodeLen]=0x04+((AdrWord&0x700)>>3); if (Memo("CALL")) BAsmCode[CodeLen]+=0x10; CodeLen+=2; ChkSpace(SegCode); END END return; END if ((Memo("CLR")) OR (Memo("CPL"))) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN z=0; OK=False; NLS_UpString(ArgStr[1]); do BEGIN if (strcmp(ClrCplVals[z],ArgStr[1])==0) BEGIN CodeLen=1; BAsmCode[0]=ClrCplCodes[z]; OK=True; if (*ArgStr[1]=='F') ChkN802X(); END z++; END while ((z'7')) WrError(1320); else BEGIN CodeLen=1; BAsmCode[0]=0x0c+ArgStr[1][1]-'4'; if (Memo("ANLD")) BAsmCode[0]+=0x90; else if (Memo("ORLD")) BAsmCode[0]+=0x80; else if (NOT OK) BAsmCode[0]+=0x30; ChkN802X(); END END return; END if ((Memo("MOVP")) OR (Memo("MOVP3"))) BEGIN if (ArgCnt!=2) WrError(1110); else if ((strcasecmp(ArgStr[1],"A")!=0) OR (strcasecmp(ArgStr[2],"@A")!=0)) WrError(1350); else BEGIN CodeLen=1; BAsmCode[0]=0xa3; if (Memo("MOVP3")) BAsmCode[0]+=0x40; ChkN802X(); END return; END if (Memo("MOVX")) BEGIN if (ArgCnt!=2) WrError(1110); else BEGIN OK=False; if (strcasecmp(ArgStr[2],"A")==0) BEGIN strcpy(ArgStr[2],ArgStr[1]); strmaxcpy(ArgStr[1],"A",255); OK=True; END if (strcasecmp(ArgStr[1],"A")!=0) WrError(1350); else BEGIN DecodeAdr(ArgStr[2]); if (AdrMode!=ModInd) WrError(1350); else BEGIN CodeLen=1; BAsmCode[0]=0x80+AdrVal; if (OK) BAsmCode[0]+=0x10; ChkN802X(); ChkNUPI(); END END END return; END if (Memo("NOP")) BEGIN if (ArgCnt!=0) WrError(1110); else BEGIN CodeLen=1; BAsmCode[0]=0x00; END return; END if (Memo("OUT")) BEGIN if (ArgCnt!=2) WrError(1110); else if (strcasecmp(ArgStr[1],"DBB")!=0) WrError(1350); else if (strcasecmp(ArgStr[2],"A")!=0) WrError(1350); else BEGIN BAsmCode[0]=0x02; CodeLen=1; ChkUPI(); END return; END if (Memo("OUTL")) BEGIN NLS_UpString(ArgStr[1]); if (ArgCnt!=2) WrError(1110); else BEGIN NLS_UpString(ArgStr[1]); if (strcasecmp(ArgStr[2],"A")!=0) WrError(1350); else if (strcmp(ArgStr[1],"BUS")==0) BEGIN CodeLen=1; BAsmCode[0]=0x02; ChkN802X(); ChkExt(); ChkNUPI(); END else if (strcmp(ArgStr[1],"P0")==0) BEGIN CodeLen=1; BAsmCode[0]=0x90; END else if ((strcmp(ArgStr[1],"P1")==0) OR (strcmp(ArgStr[1],"P2")==0)) BEGIN CodeLen=1; BAsmCode[0]=0x38+ArgStr[1][1]-'0'; END else WrError(1350); END return; END if ((Memo("RET")) OR (Memo("RETR"))) BEGIN if (ArgCnt!=0) WrError(1110); else BEGIN CodeLen=1; BAsmCode[0]=0x83; if (strlen(OpPart)==4) BEGIN BAsmCode[0]+=0x10; ChkN802X(); END END return; END if (Memo("SEL")) BEGIN if (ArgCnt!=1) WrError(1110); else if (MomCPU==CPU8021) WrError(1500); else BEGIN OK=False; NLS_UpString(ArgStr[1]); for (z=0; z