/* code51.c */ /*****************************************************************************/ /* AS-Portierung */ /* */ /* Codegenerator fuer MCS-51/252 Prozessoren */ /* */ /* Historie: 5. 6.1996 Grundsteinlegung */ /* 9. 8.1998 kurze 8051-Bitadressen wurden im 80251-Sourcemodus */ /* immer lang gemacht */ /* 24. 8.1998 Kodierung fuer MOV dir8,Rm war falsch (Fehler im */ /* Manual!) */ /* 2. 1.1998 ChkPC-Routine entfernt */ /* */ /*****************************************************************************/ #include "stdinc.h" #include #include #include "bpemu.h" #include "strutil.h" #include "chunks.h" #include "asmdef.h" #include "asmsub.h" #include "asmpars.h" #include "asmallg.h" #include "codepseudo.h" #include "codevars.h" #include "asmitree.h" /*-------------------------------------------------------------------------*/ /* Daten */ typedef struct { CPUVar MinCPU; Word Code; } FixedOrder; #define ModNone (-1) #define ModReg 1 #define MModReg (1<=2) AND (toupper(*Asc)=='R')) BEGIN Start=Asc+1; *Size=0; END else if ((MomCPU>=CPU80251) AND (alen>=3) AND (toupper(*Asc)=='W') AND (toupper(Asc[1])=='R')) BEGIN Start=Asc+2; *Size=1; END else if ((MomCPU>=CPU80251) AND (alen>=3) AND (toupper(*Asc)=='D') AND (toupper(Asc[1])=='R')) BEGIN Start=Asc+2; *Size=2; END else return False; *Erg=ConstLongInt(Start,&IO); if (NOT IO) return False; else if (((*Erg) & Masks[*Size])!=0) return False; else BEGIN (*Erg) >>= (*Size); switch (*Size) BEGIN case 0: return (((*Erg)<8) OR ((MomCPU>=CPU80251) AND ((*Erg)<16))); case 1: return ((*Erg)<16); case 2: return (((*Erg)<8) OR ((*Erg)==14) OR ((*Erg)==15)); default: return False; END END END static void ChkMask(Word Mask, Word ExtMask) BEGIN if ((AdrMode!=ModNone) AND ((Mask & (1 << AdrMode))==0)) BEGIN if ((ExtMask & (1 << AdrMode))==0) WrError(1350); else WrError(1505); AdrCnt=0; AdrMode=ModNone; END END static void DecodeAdr(char *Asc_O, Word Mask) BEGIN Boolean OK,FirstFlag; Byte HSize; Word H16; int SegType; char *PPos,*MPos,*DispPos,Save='\0'; LongWord H32; String Asc,Part; Word ExtMask; strmaxcpy(Asc,Asc_O,255); AdrMode=ModNone; AdrCnt=0; ExtMask=MMod251 & Mask; if (MomCPU> 8) & 0xff; H32 >>= 16; if (H32==0) AdrMode=ModImm; else if ((H32==1) OR (H32==0xffff)) AdrMode=ModImmEx; else WrError(1132); if (AdrMode!=ModNone) AdrCnt=2; END break; END ChkMask(Mask,ExtMask); return; END if (DecodeReg(Asc,&AdrPart,&HSize)) BEGIN if ((MomCPU>=CPU80251) AND ((Mask & MModReg)==0)) if ((HSize==0) AND (AdrPart==AccReg)) AdrMode=ModAcc; else AdrMode=ModReg; else AdrMode=ModReg; SetOpSize(HSize); ChkMask(Mask,ExtMask); return; END if (*Asc=='@') BEGIN PPos=strchr(Asc,'+'); MPos=strchr(Asc,'-'); if ((MPos!=Nil) AND ((MPos1) OR (H32!=0)) WrError(1350); else AdrMode=ModIReg8; break; case 1: if (H32==0) BEGIN AdrMode=ModIReg; AdrSize=0; END else BEGIN AdrMode=ModInd; AdrSize=0; AdrVals[1] = H32 & 0xff; AdrVals[0] = (H32 >> 8) & 0xff; AdrCnt=2; END break; case 2: if (H32==0) BEGIN AdrMode=ModIReg; AdrSize=2; END else BEGIN AdrMode=ModInd; AdrSize=2; AdrVals[1] = H32 & 0xff; AdrVals[0] = (H32 >> 8) & 0xff; AdrCnt=2; END break; END END else WrError(1350); if (PPos!=Nil) *PPos=Save; ChkMask(Mask,ExtMask); return; END FirstFlag=False; SegType=(-1); PPos=QuotPos(Asc,':'); if (PPos!=Nil) if (MomCPU=0) H32 += ((LongWord)SegType) << 16; if (FirstFlag) if ((MomCPU0xffff)) WrError(1925); else BEGIN AdrMode=ModDir16; AdrCnt=2; AdrVals[1] = H32 & 0xff; AdrVals[0] = (H32 >> 8) & 0xff; END END ChkMask(Mask,ExtMask); END static ShortInt DecodeBitAdr(char *Asc, LongInt *Erg, Boolean MayShorten) BEGIN Boolean OK; char *PPos,Save; if (MomCPU>24); return ModBit51; END else if (((*Erg)&0xf0)==0x20) BEGIN *Erg=(((*Erg)&0x0f)<<3)+((*Erg)>>24); return ModBit51; END else return ModBit251; else return ModBit251; END END static Boolean Chk504(LongInt Adr) BEGIN return ((MomCPU==CPU80504) AND ((Adr & 0x7ff)==0x7fe)); END static Boolean NeedsPrefix(Word Opcode) BEGIN return (((Opcode&0x0f)>=6) AND ((SrcMode!=0)!=((Hi(Opcode)!=0)!=0))); END static void PutCode(Word Opcode) BEGIN if (((Opcode&0x0f)<6) OR ((SrcMode!=0)!=((Hi(Opcode)==0)!=0))) BEGIN BAsmCode[0]=Lo(Opcode); CodeLen=1; END else BEGIN BAsmCode[0]=0xa5; BAsmCode[1]=Lo(Opcode); CodeLen=2; END END /*-------------------------------------------------------------------------*/ /* Einzelfaelle */ static void DecodeMOV(Word Index) BEGIN LongInt AdrLong; Byte HSize,HReg; Integer AdrInt; if (ArgCnt!=2) WrError(1110); else if ((strcasecmp(ArgStr[1],"C")==0) OR (strcasecmp(ArgStr[1],"CY")==0)) BEGIN switch (DecodeBitAdr(ArgStr[2],&AdrLong,True)) BEGIN case ModBit51: PutCode(0xa2); BAsmCode[CodeLen] = AdrLong & 0xff; CodeLen++; break; case ModBit251: PutCode(0x1a9); BAsmCode[CodeLen ] = 0xa0 +(AdrLong >> 24); BAsmCode[CodeLen+1] = AdrLong & 0xff; CodeLen+=2; break; END END else if ((strcasecmp(ArgStr[2],"C")==0) OR (strcasecmp(ArgStr[2],"CY")==0)) BEGIN switch (DecodeBitAdr(ArgStr[1],&AdrLong,True)) BEGIN case ModBit51: PutCode(0x92); BAsmCode[CodeLen] = AdrLong & 0xff; CodeLen++; break; case ModBit251: PutCode(0x1a9); BAsmCode[CodeLen ] = 0x90 + (AdrLong >> 24); BAsmCode[CodeLen+1] = AdrLong & 0xff; CodeLen+=2; break; END END else if (strcasecmp(ArgStr[1],"DPTR")==0) BEGIN SetOpSize(1); DecodeAdr(ArgStr[2],MModImm); switch (AdrMode) BEGIN case ModImm: PutCode(0x90); memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt); CodeLen+=AdrCnt; break; END END else BEGIN DecodeAdr(ArgStr[1],MModAcc+MModReg+MModIReg8+MModIReg+MModInd+MModDir8+MModDir16); switch (AdrMode) BEGIN case ModAcc: DecodeAdr(ArgStr[2],MModReg+MModIReg8+MModIReg+MModInd+MModDir8+MModDir16+MModImm); switch (AdrMode) BEGIN case ModReg: if ((AdrPart<8) AND (NOT SrcMode)) PutCode(0xe8+AdrPart); else if (MomCPU>24); BAsmCode[CodeLen++] = AdrLong & 0xff; break; END END END else BEGIN z=(Index << 4)+0x40; DecodeAdr(ArgStr[1],MModAcc+MModReg+MModDir8); switch (AdrMode) BEGIN case ModAcc: DecodeAdr(ArgStr[2],MModReg+MModIReg8+MModIReg+MModDir8+MModDir16+MModImm); switch (AdrMode) BEGIN case ModReg: if ((AdrPart<8) AND (NOT SrcMode)) PutCode(z+8+AdrPart); else BEGIN PutCode(z+0x10c); BAsmCode[CodeLen++] = AdrPart + (AccReg << 4); END break; case ModIReg8: PutCode(z+6+AdrPart); break; case ModIReg: PutCode(z+0x10e); BAsmCode[CodeLen++] = 0x09 + AdrSize + (AdrPart << 4); BAsmCode[CodeLen++] = AccReg << 4; break; case ModDir8: PutCode(z+0x05); BAsmCode[CodeLen++] = AdrVals[0]; break; case ModDir16: PutCode(0x10e + z); BAsmCode[CodeLen++] = 0x03 + (AccReg << 4); memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt); CodeLen+=AdrCnt; break; case ModImm: PutCode(z+0x04); BAsmCode[CodeLen++] = AdrVals[0]; break; END break; case ModReg: if (MomCPU=CPU80251) AND (strcasecmp(ArgStr[2],"R11")==0))) BEGIN z=0x10; strcpy(ArgStr[2],ArgStr[1]); strmaxcpy(ArgStr[1],"A",255); END if ((strcasecmp(ArgStr[1],"A")!=0) AND ((MomCPU7) WrError(1350); else PutCode(0xc8+AdrPart); break; case ModIReg8: PutCode(0xc6+AdrPart); break; case ModDir8: PutCode(0xc5); BAsmCode[CodeLen++] = AdrVals[0]; break; END break; case ModReg: if ((OpSize!=0) OR (AdrPart>7)) WrError(1350); else BEGIN HReg=AdrPart; DecodeAdr(ArgStr[2],MModAcc); switch (AdrMode) BEGIN case ModAcc: PutCode(0xc8+HReg); break; END END break; case ModIReg8: HReg=AdrPart; DecodeAdr(ArgStr[2],MModAcc); switch (AdrMode) BEGIN case ModAcc: PutCode(0xc6+HReg); break; END break; case ModDir8: HReg=AdrVals[0]; DecodeAdr(ArgStr[2],MModAcc); switch (AdrMode) BEGIN case ModAcc: PutCode(0xc5); BAsmCode[CodeLen++] = HReg; break; END break; END END END static void DecodeXCHD(Word Index) BEGIN Byte HReg; if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[1],MModAcc+MModIReg8); switch (AdrMode) BEGIN case ModAcc: DecodeAdr(ArgStr[2],MModIReg8); switch (AdrMode) BEGIN case ModIReg8: PutCode(0xd6+AdrPart); break; END break; case ModIReg8: HReg=AdrPart; DecodeAdr(ArgStr[2],MModAcc); switch (AdrMode) BEGIN case ModAcc: PutCode(0xd6+HReg); break; END break; END END END static void DecodeABranch(Word Index) BEGIN Boolean OK; LongInt AdrLong; /* Index: AJMP=0 ACALL=1 */ if (ArgCnt!=1) WrError(1110); else BEGIN AdrLong=EvalIntExpression(ArgStr[1],Int24,&OK); if (OK) if ((NOT SymbolQuestionable) AND (((EProgCounter()+2) >> 11)!=(AdrLong >> 11))) WrError(1910); else if (Chk504(EProgCounter())) WrError(1900); else BEGIN ChkSpace(SegCode); PutCode(0x01 + (Index << 4) + ((Hi(AdrLong) & 7) << 5)); BAsmCode[CodeLen++]=Lo(AdrLong); END END END static void DecodeLBranch(Word Index) BEGIN LongInt AdrLong; Boolean OK; /* Index: LJMP=0 LCALL=1 */ if (ArgCnt!=1) WrError(1110); else if (MomCPU=CPU80251) AND (((EProgCounter()+3) >> 16)!=(AdrLong >> 16))) WrError(1910); else BEGIN ChkSpace(SegCode); PutCode(0x02 + (Index << 4)); BAsmCode[CodeLen++] = (AdrLong >> 8) & 0xff; BAsmCode[CodeLen++] = AdrLong & 0xff; END END END static void DecodeEBranch(Word Index) BEGIN LongInt AdrLong; Boolean OK; /* Index: AJMP=0 ACALL=1 */ if (ArgCnt!=1) WrError(1110); else if (MomCPU> 16) & 0xff; BAsmCode[CodeLen++] = (AdrLong >> 8) & 0xff; BAsmCode[CodeLen++] = AdrLong & 0xff; END END END static void DecodeJMP(Word Index) BEGIN LongInt AdrLong,Dist; Boolean OK; if (ArgCnt!=1) WrError(1110); else if (strcasecmp(ArgStr[1],"@A+DPTR")==0) PutCode(0x73); else if (*ArgStr[1]=='@') BEGIN DecodeAdr(ArgStr[1],MModIReg); switch (AdrMode) BEGIN case ModIReg: PutCode(0x189); BAsmCode[CodeLen++] = 0x04 + (AdrSize << 1) + (AdrPart << 4); break; END END else BEGIN AdrLong=EvalIntExpression(ArgStr[1],UInt24,&OK); if (OK) BEGIN Dist=AdrLong-(EProgCounter()+2); if ((Dist<=127) AND (Dist>=-128)) BEGIN PutCode(0x80); BAsmCode[CodeLen++] = Dist & 0xff; END else if ((NOT Chk504(EProgCounter())) AND ((AdrLong >> 11)==((EProgCounter()+2) >> 11))) BEGIN PutCode(0x01 + ((Hi(AdrLong) & 7) << 5)); BAsmCode[CodeLen++] = Lo(AdrLong); END else if (MomCPU> 16)==(AdrLong >> 16)) BEGIN PutCode(0x02); BAsmCode[CodeLen++] = Hi(AdrLong); BAsmCode[CodeLen++] = Lo(AdrLong); END else if (MomCPU> 16) & 0xff; BAsmCode[CodeLen++] =(AdrLong >> 8) & 0xff; BAsmCode[CodeLen++] = AdrLong & 0xff; END END END END static void DecodeCALL(Word Index) BEGIN LongInt AdrLong; Boolean OK; if (ArgCnt!=1) WrError(1110); else if (*ArgStr[1]=='@') BEGIN DecodeAdr(ArgStr[1],MModIReg); switch (AdrMode) BEGIN case ModIReg: PutCode(0x199); BAsmCode[CodeLen++] = 0x04 + (AdrSize << 1) + (AdrPart << 4); break; END END else BEGIN AdrLong=EvalIntExpression(ArgStr[1],UInt24,&OK); if (OK) BEGIN if ((NOT Chk504(EProgCounter())) AND ((AdrLong >> 11)==((EProgCounter()+2) >> 11))) BEGIN PutCode(0x11 + ((Hi(AdrLong) & 7) << 5)); BAsmCode[CodeLen++] = Lo(AdrLong); END else if (MomCPU> 16)!=((EProgCounter()+3) >> 16)) WrError(1910); else BEGIN PutCode(0x12); BAsmCode[CodeLen++] = Hi(AdrLong); BAsmCode[CodeLen++] = Lo(AdrLong); END END END END static void DecodeDJNZ(Word Index) BEGIN LongInt AdrLong; Boolean OK,Questionable; if (ArgCnt!=2) WrError(1110); else BEGIN AdrLong=EvalIntExpression(ArgStr[2],UInt24,&OK); Questionable=SymbolQuestionable; if (OK) BEGIN DecodeAdr(ArgStr[1],MModReg+MModDir8); switch (AdrMode) BEGIN case ModReg: if ((OpSize!=0) OR (AdrPart>7)) WrError(1350); else BEGIN AdrLong-=EProgCounter()+2+Ord(NeedsPrefix(0xd8+AdrPart)); if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT Questionable)) WrError(1370); else BEGIN PutCode(0xd8+AdrPart); BAsmCode[CodeLen++] = AdrLong & 0xff; END END break; case ModDir8: AdrLong-=EProgCounter()+3+Ord(NeedsPrefix(0xd5)); if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT Questionable)) WrError(1370); else BEGIN PutCode(0xd5); BAsmCode[CodeLen++] = AdrVals[0]; BAsmCode[CodeLen++] = Lo(AdrLong); END break; END END END END static void DecodeCJNE(Word Index) BEGIN LongInt AdrLong; Boolean OK,Questionable; Byte HReg; if (ArgCnt!=3) WrError(1110); else BEGIN AdrLong=EvalIntExpression(ArgStr[3],UInt24,&OK); Questionable=SymbolQuestionable; if (OK) BEGIN DecodeAdr(ArgStr[1],MModAcc+MModIReg8+MModReg); switch (AdrMode) BEGIN case ModAcc: DecodeAdr(ArgStr[2],MModDir8+MModImm); switch (AdrMode) BEGIN case ModDir8: AdrLong-=EProgCounter()+3+Ord(NeedsPrefix(0xb5)); if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT Questionable)) WrError(1370); else BEGIN PutCode(0xb5); BAsmCode[CodeLen++] = AdrVals[0]; BAsmCode[CodeLen++] = AdrLong & 0xff; END break; case ModImm: AdrLong-=EProgCounter()+3+Ord(NeedsPrefix(0xb5)); if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT Questionable)) WrError(1370); else BEGIN PutCode(0xb4); BAsmCode[CodeLen++] = AdrVals[0]; BAsmCode[CodeLen++] = AdrLong & 0xff; END break; END break; case ModReg: if ((OpSize!=0) OR (AdrPart>7)) WrError(1350); else BEGIN HReg=AdrPart; DecodeAdr(ArgStr[2],MModImm); switch (AdrMode) BEGIN case ModImm: AdrLong-=EProgCounter()+3+Ord(NeedsPrefix(0xb8+HReg)); if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT Questionable)) WrError(1370); else BEGIN PutCode(0xb8+HReg); BAsmCode[CodeLen++] = AdrVals[0]; BAsmCode[CodeLen++] = AdrLong & 0xff; END break; END END break; case ModIReg8: HReg=AdrPart; SetOpSize(0); DecodeAdr(ArgStr[2],MModImm); switch (AdrMode) BEGIN case ModImm: AdrLong-=EProgCounter()+3+Ord(NeedsPrefix(0xb6+HReg)); if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT Questionable)) WrError(1370); else BEGIN PutCode(0xb6+HReg); BAsmCode[CodeLen++] = AdrVals[0]; BAsmCode[CodeLen++] = AdrLong & 0xff; END break; END break; END END END END static void DecodeADD(Word Index) BEGIN Byte HReg; if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[1],MModAcc+MModReg); switch (AdrMode) BEGIN case ModAcc: DecodeAdr(ArgStr[2],MModImm+MModDir8+MModDir16+MModIReg8+MModIReg+MModReg); switch (AdrMode) BEGIN case ModImm: PutCode(0x24); BAsmCode[CodeLen++] = AdrVals[0]; break; case ModDir8: PutCode(0x25); BAsmCode[CodeLen++] = AdrVals[0]; break; case ModDir16: PutCode(0x12e); BAsmCode[CodeLen++] = (AccReg << 4) + 3; memcpy(BAsmCode+CodeLen,AdrVals,2); CodeLen+=2; break; case ModIReg8: PutCode(0x26+AdrPart); break; case ModIReg: PutCode(0x12e); BAsmCode[CodeLen++] = 0x09 + AdrSize + (AdrPart << 4); BAsmCode[CodeLen++] = AccReg << 4; break; case ModReg: if ((AdrPart<8) AND (NOT SrcMode)) PutCode(0x28+AdrPart); else if (MomCPU7) WrError(1350); else PutCode(HReg+0x08+AdrPart); break; case ModIReg8: PutCode(HReg+0x06+AdrPart); break; case ModDir8: PutCode(HReg+0x05); BAsmCode[CodeLen++] = AdrVals[0]; break; case ModImm: PutCode(HReg+0x04); BAsmCode[CodeLen++] = AdrVals[0]; break; END break; END END END static void DecodeINCDEC(Word Index) BEGIN Byte HReg; int z; Boolean OK; /* Index: INC=0 DEC=1 */ if (ArgCnt==1) strmaxcpy(ArgStr[++ArgCnt],"#1",255); z=Index << 4; if (ArgCnt!=2) WrError(1110); else if (*ArgStr[2]!='#') WrError(1350); else BEGIN FirstPassUnknown=False; HReg=EvalIntExpression(ArgStr[2]+1,UInt3,&OK); if (FirstPassUnknown) HReg=1; if (OK) BEGIN OK=True; if (HReg==1) HReg=0; else if (HReg==2) HReg=1; else if (HReg==4) HReg=2; else OK=False; if (NOT OK) WrError(1320); else if (strcasecmp(ArgStr[1],"DPTR")==0) BEGIN if (Index==1) WrError(1350); else if (HReg!=0) WrError(1320); else PutCode(0xa3); END else BEGIN DecodeAdr(ArgStr[1],MModAcc+MModReg+MModDir8+MModIReg8); switch (AdrMode) BEGIN case ModAcc: if (HReg==0) PutCode(0x04+z); else if (MomCPU2)) WrError(1110); else if (ArgCnt==1) BEGIN if (strcasecmp(ArgStr[1],"AB")!=0) WrError(1350); else PutCode(0x84+z); END else BEGIN DecodeAdr(ArgStr[1],MModReg); switch (AdrMode) BEGIN case ModReg: HReg=AdrPart; DecodeAdr(ArgStr[2],MModReg); switch (AdrMode) BEGIN case ModReg: if (MomCPU> 24); BAsmCode[CodeLen++] = AdrLong & 0xff; break; END END static void DecodeShift(Word Index) BEGIN int z; /* Index: SRA=0 SRL=1 SLL=3 */ if (ArgCnt!=1) WrError(1110); else if (MomCPUMinCPU) WrError(1500); else BEGIN AdrLong=EvalIntExpression(ArgStr[1],UInt24,&OK); if (OK) BEGIN AdrLong-=EProgCounter()+2+Ord(NeedsPrefix(FixedZ->Code)); if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT SymbolQuestionable)) WrError(1370); else BEGIN ChkSpace(SegCode); PutCode(FixedZ->Code); BAsmCode[CodeLen++] = AdrLong & 0xff; END END END END static void DecodeBCond(Word Index) BEGIN FixedOrder *FixedZ=BCondOrders+Index; LongInt AdrLong,BitLong; Boolean OK,Questionable; if (ArgCnt!=2) WrError(1110); else BEGIN AdrLong=EvalIntExpression(ArgStr[2],UInt24,&OK); Questionable=SymbolQuestionable; if (OK) BEGIN ChkSpace(SegCode); switch (DecodeBitAdr(ArgStr[1],&BitLong,True)) BEGIN case ModBit51: AdrLong-=EProgCounter()+3+Ord(NeedsPrefix(FixedZ->Code)); if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT Questionable)) WrError(1370); else BEGIN PutCode(FixedZ->Code); BAsmCode[CodeLen++] = BitLong & 0xff; BAsmCode[CodeLen++] = AdrLong & 0xff; END break; case ModBit251: AdrLong-=EProgCounter()+4+Ord(NeedsPrefix(0x1a9)); if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT Questionable)) WrError(1370); else BEGIN PutCode(0x1a9); BAsmCode[CodeLen++] = FixedZ->Code+(BitLong >> 24); BAsmCode[CodeLen++] = BitLong & 0xff; BAsmCode[CodeLen++] = AdrLong & 0xff; END break; END END END END static void DecodeAcc(Word Index) BEGIN FixedOrder *FixedZ=AccOrders+Index; if (ArgCnt!=1) WrError(1110); else if (MomCPUMinCPU) WrError(1500); else BEGIN DecodeAdr(ArgStr[1],MModAcc); switch (AdrMode) BEGIN case ModAcc: PutCode(FixedZ->Code); break; END END; END static void DecodeFixed(Word Index) BEGIN FixedOrder *FixedZ=FixedOrders+Index; if (ArgCnt!=0) WrError(1110); else if (MomCPUMinCPU) WrError(1500); else PutCode(FixedZ->Code); END static void DecodeSFR(Word Index) BEGIN Word AdrByte; Boolean OK; int z,DSeg; String s; FirstPassUnknown=False; if (ArgCnt!=1) WrError(1110); else if ((Memo("SFRB")) AND (MomCPU>=CPU80251)) WrError(1500); else BEGIN if (MomCPU>=CPU80251) AdrByte=EvalIntExpression(ArgStr[1],UInt9,&OK); else AdrByte=EvalIntExpression(ArgStr[1],UInt8,&OK); if ((OK) AND (NOT FirstPassUnknown)) BEGIN PushLocHandle(-1); DSeg=(MomCPU>=CPU80251)?(SegIO):(SegData); EnterIntSymbol(LabPart,AdrByte,DSeg,False); if (MakeUseList) if (AddChunk(SegChunks+DSeg,AdrByte,1,False)) WrError(90); if (Memo("SFRB")) BEGIN if (AdrByte>0x7f) BEGIN if ((AdrByte & 7)!=0) WrError(220); END else BEGIN if ((AdrByte & 0xe0)!=0x20) WrError(220); AdrByte=(AdrByte-0x20) << 3; END for (z=0; z<8; z++) BEGIN sprintf(s,"%s.%c",LabPart,z+'0'); EnterIntSymbol(s,AdrByte+z,SegBData,False); END if (MakeUseList) if (AddChunk(SegChunks+SegBData,AdrByte,8,False)) WrError(90); sprintf(ListLine,"=%sH-",HexString(AdrByte,2)); strmaxcat(ListLine,HexString(AdrByte+7,2),255); strmaxcat(ListLine,"H",255); END else sprintf(ListLine,"=%sH",HexString(AdrByte,2)); PopLocHandle(); END END END static void DecodeBIT(Word Index) BEGIN LongInt AdrLong; if (MomCPU>=CPU80251) BEGIN if (ArgCnt!=1) WrError(1110); else if (DecodeBitAdr(ArgStr[1],&AdrLong,False)==ModBit251) BEGIN EnterIntSymbol(LabPart,AdrLong,SegNone,False); sprintf(ListLine,"=%sH.%s",HexString(AdrLong&0xff,2),HexString(AdrLong>>24,1)); END END else CodeEquate(SegBData,0,0xff); END static void DecodePORT(Word Index) BEGIN if (MomCPU=FixedOrderCnt) exit(255); FixedOrders[InstrZ].Code=NCode; FixedOrders[InstrZ].MinCPU=NCPU; AddInstTable(InstTable,NName,InstrZ++,DecodeFixed); END static void AddAcc(char *NName, Word NCode, CPUVar NCPU) BEGIN if (InstrZ>=AccOrderCnt) exit(255); AccOrders[InstrZ].Code=NCode; AccOrders[InstrZ].MinCPU=NCPU; AddInstTable(InstTable,NName,InstrZ++,DecodeAcc); END static void AddCond(char *NName, Word NCode, CPUVar NCPU) BEGIN if (InstrZ>=CondOrderCnt) exit(255); CondOrders[InstrZ].Code=NCode; CondOrders[InstrZ].MinCPU=NCPU; AddInstTable(InstTable,NName,InstrZ++,DecodeCond); END static void AddBCond(char *NName, Word NCode, CPUVar NCPU) BEGIN if (InstrZ>=BCondOrderCnt) exit(255); BCondOrders[InstrZ].Code=NCode; BCondOrders[InstrZ].MinCPU=NCPU; AddInstTable(InstTable,NName,InstrZ++,DecodeBCond); END static void InitFields(void) BEGIN InstTable=CreateInstTable(203); AddInstTable(InstTable,"MOV" , 0,DecodeMOV); AddInstTable(InstTable,"ANL" , 1,DecodeLogic); AddInstTable(InstTable,"ORL" , 0,DecodeLogic); AddInstTable(InstTable,"XRL" , 2,DecodeLogic); AddInstTable(InstTable,"MOVC" , 0,DecodeMOVC); AddInstTable(InstTable,"MOVH" , 0,DecodeMOVH); AddInstTable(InstTable,"MOVZ" , 0,DecodeMOVZS); AddInstTable(InstTable,"MOVS" , 0,DecodeMOVZS); AddInstTable(InstTable,"MOVX" , 0,DecodeMOVX); AddInstTable(InstTable,"POP" , 1,DecodeStack); AddInstTable(InstTable,"PUSH" , 0,DecodeStack); AddInstTable(InstTable,"PUSHW", 2,DecodeStack); AddInstTable(InstTable,"XCH" , 0,DecodeXCH); AddInstTable(InstTable,"XCHD" , 0,DecodeXCHD); AddInstTable(InstTable,"AJMP" , 0,DecodeABranch); AddInstTable(InstTable,"ACALL", 1,DecodeABranch); AddInstTable(InstTable,"LJMP" , 0,DecodeLBranch); AddInstTable(InstTable,"LCALL", 1,DecodeLBranch); AddInstTable(InstTable,"EJMP" , 0,DecodeEBranch); AddInstTable(InstTable,"ECALL", 1,DecodeEBranch); AddInstTable(InstTable,"JMP" , 0,DecodeJMP); AddInstTable(InstTable,"CALL" , 0,DecodeCALL); AddInstTable(InstTable,"DJNZ" , 0,DecodeDJNZ); AddInstTable(InstTable,"CJNE" , 0,DecodeCJNE); AddInstTable(InstTable,"ADD" , 0,DecodeADD); AddInstTable(InstTable,"SUB" , 0,DecodeSUBCMP); AddInstTable(InstTable,"CMP" , 1,DecodeSUBCMP); AddInstTable(InstTable,"ADDC" , 0,DecodeADDCSUBB); AddInstTable(InstTable,"SUBB" , 1,DecodeADDCSUBB); AddInstTable(InstTable,"INC" , 0,DecodeINCDEC); AddInstTable(InstTable,"DEC" , 1,DecodeINCDEC); AddInstTable(InstTable,"MUL" , 1,DecodeMULDIV); AddInstTable(InstTable,"DIV" , 0,DecodeMULDIV); AddInstTable(InstTable,"CLR" , 1,DecodeBits); AddInstTable(InstTable,"CPL" , 0,DecodeBits); AddInstTable(InstTable,"SETB" , 2,DecodeBits); AddInstTable(InstTable,"SRA" , 0,DecodeShift); AddInstTable(InstTable,"SRL" , 1,DecodeShift); AddInstTable(InstTable,"SLL" , 3,DecodeShift); AddInstTable(InstTable,"SFR" , 0,DecodeSFR); AddInstTable(InstTable,"SFRB" , 1,DecodeSFR); AddInstTable(InstTable,"BIT" , 0,DecodeBIT); AddInstTable(InstTable,"PORT" , 0,DecodePORT); FixedOrders=(FixedOrder *) malloc(FixedOrderCnt*sizeof(FixedOrder)); InstrZ=0; AddFixed("NOP" ,0x0000,CPU87C750); AddFixed("RET" ,0x0022,CPU87C750); AddFixed("RETI",0x0032,CPU87C750); AddFixed("ERET",0x01aa,CPU80251); AddFixed("TRAP",0x01b9,CPU80251); AccOrders=(FixedOrder *) malloc(AccOrderCnt*sizeof(FixedOrder)); InstrZ=0; AddAcc("DA" ,0x00d4,CPU87C750); AddAcc("RL" ,0x0023,CPU87C750); AddAcc("RLC" ,0x0033,CPU87C750); AddAcc("RR" ,0x0003,CPU87C750); AddAcc("RRC" ,0x0013,CPU87C750); AddAcc("SWAP",0x00c4,CPU87C750); CondOrders=(FixedOrder *) malloc(CondOrderCnt*sizeof(FixedOrder)); InstrZ=0; AddCond("JC" ,0x0040,CPU87C750); AddCond("JE" ,0x0168,CPU80251); AddCond("JG" ,0x0138,CPU80251); AddCond("JLE" ,0x0128,CPU80251); AddCond("JNC" ,0x0050,CPU87C750); AddCond("JNE" ,0x0178,CPU80251); AddCond("JNZ" ,0x0070,CPU87C750); AddCond("JSG" ,0x0118,CPU80251); AddCond("JSGE",0x0158,CPU80251); AddCond("JSL" ,0x0148,CPU80251); AddCond("JSLE",0x0108,CPU80251); AddCond("JZ" ,0x0060,CPU87C750); AddCond("SJMP",0x0080,CPU87C750); BCondOrders=(FixedOrder *) malloc(BCondOrderCnt*sizeof(FixedOrder)); InstrZ=0; AddBCond("JB" ,0x0020,CPU87C750); AddBCond("JBC",0x0010,CPU87C750); AddBCond("JNB",0x0030,CPU87C750); END static void DeinitFields(void) BEGIN DestroyInstTable(InstTable); free(FixedOrders); free(AccOrders); free(CondOrders); free(BCondOrders); END /*-------------------------------------------------------------------------*/ /* Instruktionsdecoder */ static Boolean DecodePseudo(void) BEGIN return False; END static void MakeCode_51(void) BEGIN CodeLen=0; DontPrint=False; OpSize=(-1); MinOneIs0=False; /* zu ignorierendes */ if (*OpPart=='\0') return; /* Pseudoanweisungen */ if (DecodePseudo()) return; if (DecodeIntelPseudo(BigEndian)) return; /* suchen */ if (NOT LookupInstTable(InstTable,OpPart)) WrXError(1200,OpPart); END static Boolean IsDef_51(void) BEGIN switch (*OpPart) BEGIN case 'B': return Memo("BIT"); case 'S': if (Memo("SFR")) return True; if (MomCPU>=CPU80251) return False; return Memo("SFRB"); case 'P': if (MomCPU>=CPU80251) return Memo("PORT"); else return False; default : return False; END END static void InitPass_51(void) BEGIN SaveInitProc(); SetFlag(&SrcMode,SrcModeName,False); SetFlag(&BigEndian,BigEndianName,False); END static void SwitchFrom_51(void) BEGIN DeinitFields(); ClearONOFF(); END static void SwitchTo_51(void) BEGIN TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False; PCSymbol="$"; HeaderID=0x31; NOPCode=0x00; DivideChars=","; HasAttrs=False; if (MomCPU>=CPU80251) BEGIN ValidSegs=(1<