/* code96c141.c */ /*****************************************************************************/ /* AS-Portierung */ /* */ /* Codegenerator TLCS-900(L) */ /* */ /* Historie: 27. 6.1996 Grundsteinlegung */ /* 9. 1.1999 ChkPC jetzt mit Adresse als Parameter */ /* */ /*****************************************************************************/ #include "stdinc.h" #include #include #include "nls.h" #include "bpemu.h" #include "strutil.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 { char *Name; Word Code; Byte CPUFlag; Boolean InSup; } FixedOrder; typedef struct { char *Name; Word Code; Boolean InSup; Byte MinMax,MaxMax; ShortInt Default; } ImmOrder; typedef struct { char *Name; Word Code; Byte OpMask; } RegOrder; typedef struct { char *Name; Byte Code; } ALU2Order; typedef struct { char *Name; Byte Code; } Condition; #define FixedOrderCnt 13 #define ImmOrderCnt 3 #define RegOrderCnt 8 #define ALU2OrderCnt 8 #define ShiftOrderCnt 8 #define MulDivOrderCnt 4 #define BitCFOrderCnt 5 #define BitOrderCnt 5 #define ConditionCnt 24 #define ModNone (-1) #define ModReg 0 #define MModReg (1 << ModReg) #define ModXReg 1 #define MModXReg (1 << ModXReg) #define ModMem 2 #define MModMem (1 << ModMem) #define ModImm 3 #define MModImm (1 << ModImm) #define ModCReg 4 #define MModCReg (1 << ModCReg) static FixedOrder *FixedOrders; static RegOrder *RegOrders; static ImmOrder *ImmOrders; static ALU2Order *ALU2Orders; static char **ShiftOrders; static char **MulDivOrders; static ALU2Order *BitCFOrders; static char **BitOrders; static Condition *Conditions; static LongInt DefaultCondition; static PInstTable InstTable; static ShortInt AdrType; static ShortInt OpSize; /* -1/0/1/2 = nix/Byte/Word/Long */ static Byte AdrMode; static Byte AdrVals[10]; static Boolean MinOneIs0; static CPUVar CPU96C141,CPU93C141; /*---------------------------------------------------------------------------*/ /* Adressparser */ static Boolean IsRegBase(Byte No, Byte Size) BEGIN return ((Size==2) OR ((Size==1) AND (No<0xf0) AND (NOT Maximum) AND ((No & 3)==0))); END static void ChkMaximum(Boolean MustMax, Byte *Result) BEGIN if (Maximum!=MustMax) BEGIN *Result=1; WrError((MustMax)?1997:1996); END END static Boolean IsQuot(char Ch) BEGIN return ((Ch=='\'') OR (Ch=='`')); END static Byte CodeEReg(char *Asc, Byte *ErgNo, Byte *ErgSize) BEGIN #define RegCnt 8 static char Reg8Names[RegCnt+1]="AWCBEDLH"; static char *Reg16Names[RegCnt]= {"WA" ,"BC" ,"DE" ,"HL" ,"IX" ,"IY" ,"IZ" ,"SP" }; static char *Reg32Names[RegCnt]= {"XWA","XBC","XDE","XHL","XIX","XIY","XIZ","XSP"}; int z,l=strlen(Asc); char *pos; String HAsc,Asc_N; Byte Result; strmaxcpy(Asc_N,Asc,255); NLS_UpString(Asc_N); Asc=Asc_N; Result=2; /* mom. Bank ? */ if ((l==1) AND ((pos=strchr(Reg8Names,*Asc))!=Nil)) BEGIN z=pos-Reg8Names; *ErgNo=0xe0+((z & 6) << 1)+(z & 1); *ErgSize=0; return Result; END for (z=0; z='0') AND (Asc[2]<='7'))) for (z=0; z'3')) BEGIN WrError(1320); Result=1; END *ErgSize=0; return Result; END /* Bankregister, 16 Bit ? */ if ((l==4) AND ((*Asc=='Q') OR (*Asc=='R')) AND ((Asc[3]>='0') AND (Asc[3]<='7'))) BEGIN strcpy(HAsc,Asc+2); HAsc[2]='\0'; for (z=0; z<(RegCnt/2)-1; z++) if (strcmp(HAsc,Reg16Names[z])==0) BEGIN *ErgNo=((Asc[3]-'0') << 4)+(z << 2); if (*Asc=='Q') BEGIN ErgNo+=2; ChkMaximum(True,&Result); END if (((*Asc=='Q') OR (Maximum)) AND (Asc[3]>'3')) BEGIN WrError(1320); Result=1; END *ErgSize=1; return Result; END END /* Bankregister, 32 Bit ? */ if ((l==4) AND ((Asc[3]>='0') AND (Asc[3]<='7'))) BEGIN strcpy(HAsc,Asc); HAsc[3]='\0'; for (z=0; z<(RegCnt/2)-1; z++) if (strcmp(HAsc,Reg32Names[z])==0) BEGIN *ErgNo=((Asc[3]-'0') << 4)+(z << 2); ChkMaximum(True,&Result); if (Asc[3]>'3') BEGIN WrError(1320); Result=1; END *ErgSize=2; return Result; END END /* obere 8-Bit-Haelften momentaner Bank ? */ if ((l==2) AND (*Asc=='Q')) for (z=0; z='0') AND (Asc[4]<='3')) switch (toupper(Asc[3])) BEGIN case 'S': *ErgNo=(Asc[4]-'0')*4; *ErgSize=2; return Result; case 'D': *ErgNo=(Asc[4]-'0')*4+0x10; *ErgSize=2; return Result; case 'M': *ErgNo=(Asc[4]-'0')*4+0x22; *ErgSize=0; return Result; case 'C': *ErgNo=(Asc[4]-'0')*4+0x20; *ErgSize=1; return Result; END return (Result=0); END typedef struct { char *Name; Byte Num; Boolean InMax,InMin; } RegDesc; static void SetOpSize(ShortInt NewSize) BEGIN if (OpSize==-1) OpSize=NewSize; else if (OpSize!=NewSize) BEGIN WrError(1131); AdrType=ModNone; END END static Boolean IsRegCurrent(Byte No, Byte Size, Byte *Erg) BEGIN switch (Size) BEGIN case 0: if ((No & 0xf2)==0xe0) BEGIN *Erg=((No & 0x0c) >> 1)+((No & 1) ^ 1); return True; END else return False; case 1: case 2: if ((No & 0xe3)==0xe0) BEGIN *Erg=((No & 0x1c) >> 2); return True; END else return False; default: return False; END END static void ChkAdr(Byte Erl) BEGIN if (AdrType!=ModNone) if ((Erl&(1 << AdrType))==0) BEGIN WrError(1350); AdrType=ModNone; END END static void DecodeAdr(char *Asc, Byte Erl) BEGIN String HAsc,Rest; Byte HNum,HSize; Boolean OK,NegFlag,NNegFlag,MustInd,FirstFlag; Byte BaseReg,BaseSize; Byte IndReg,IndSize; Byte PartMask; LongInt DispPart,DispAcc; char *MPos,*PPos,*EPos; AdrType=ModNone; /* Register ? */ switch (CodeEReg(Asc,&HNum,&HSize)) BEGIN case 1: ChkAdr(Erl); return; case 2: if (IsRegCurrent(HNum,HSize,&AdrMode)) AdrType=ModReg; else BEGIN AdrType=ModXReg; AdrMode=HNum; END SetOpSize(HSize); ChkAdr(Erl); return; END /* Steuerregister ? */ if (CodeCReg(Asc,&HNum,&HSize)==2) BEGIN AdrType=ModCReg; AdrMode=HNum; SetOpSize(HSize); ChkAdr(Erl); return; END /* Predekrement ? */ if ((strlen(Asc)>4) AND (Asc[strlen(Asc)-1]==')') AND (strncmp(Asc,"(-",2)==0)) BEGIN strcpy(HAsc,Asc+2); HAsc[strlen(HAsc)-1]='\0'; if (CodeEReg(HAsc,&HNum,&HSize)!=2) WrError(1350); else if (NOT IsRegBase(HNum,HSize)) WrError(1350); else BEGIN AdrType=ModMem; AdrMode=0x44; AdrCnt=1; AdrVals[0]=HNum; if (OpSize!=-1) AdrVals[0]+=OpSize; END ChkAdr(Erl); return; END /* Postinkrement ? */ if ((strlen(Asc)>4) AND (Asc[0]=='(') AND (strncmp(Asc+strlen(Asc)-2,"+)",2)==0)) BEGIN strcpy(HAsc,Asc+1); HAsc[strlen(HAsc)-2]='\0'; if (CodeEReg(HAsc,&HNum,&HSize)!=2) WrError(1350); else if (NOT IsRegBase(HNum,HSize)) WrError(1350); else BEGIN AdrType=ModMem; AdrMode=0x45; AdrCnt=1; AdrVals[0]=HNum; if (OpSize!=-1) AdrVals[0]+=OpSize; END ChkAdr(Erl); return; END /* Speicheroperand ? */ if (IsIndirect(Asc)) BEGIN NegFlag=False; NNegFlag=False; FirstFlag=False; PartMask=0; DispAcc=0; BaseReg=IndReg=BaseSize=IndSize=0xff; strcpy(Rest,Asc+1); Rest[strlen(Rest)-1]='\0'; do BEGIN MPos=QuotPos(Rest,'-'); PPos=QuotPos(Rest,'+'); if ((PPos!=Nil) AND ((MPos==Nil) OR (PPos> 8) & 0xff; AdrVals[2]=(DispAcc >> 16) & 0xff; END else WrError(1925); break; case 4: if (IsRegCurrent(BaseReg,BaseSize,&AdrMode)) BEGIN AdrType=ModMem; AdrCnt=0; END else BEGIN AdrType=ModMem; AdrMode=0x43; AdrCnt=1; AdrVals[0]=BaseReg; END break; case 5: if ((DispAcc<=127) AND (DispAcc>=-128) AND (IsRegCurrent(BaseReg,BaseSize,&AdrMode))) BEGIN AdrType=ModMem; AdrMode+=8; AdrCnt=1; AdrVals[0]=DispAcc & 0xff; END else if ((DispAcc<=32767) AND (DispAcc>=-32768)) BEGIN AdrType=ModMem; AdrMode=0x43; AdrCnt=3; AdrVals[0]=BaseReg+1; AdrVals[1]=DispAcc & 0xff; AdrVals[2]=(DispAcc >> 8) & 0xff; END else WrError(1320); break; case 6: AdrType=ModMem; AdrMode=0x43; AdrCnt=3; AdrVals[0]=3+(IndSize << 2); AdrVals[1]=BaseReg; AdrVals[2]=IndReg; break; END ChkAdr(Erl); return; END /* bleibt nur noch immediate... */ if ((MinOneIs0) AND (OpSize==-1)) OpSize=0; switch (OpSize) BEGIN case -1: WrError(1132); break; case 0: AdrVals[0]=EvalIntExpression(Asc,Int8,&OK); if (OK) BEGIN AdrType=ModImm; AdrCnt=1; END break; case 1: DispAcc=EvalIntExpression(Asc,Int16,&OK); if (OK) BEGIN AdrType=ModImm; AdrCnt=2; AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc); END break; case 2: DispAcc=EvalIntExpression(Asc,Int32,&OK); if (OK) BEGIN AdrType=ModImm; AdrCnt=4; AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc); AdrVals[2]=Lo(DispAcc >> 16); AdrVals[3]=Hi(DispAcc >> 16); END break; END END /*---------------------------------------------------------------------------*/ static void CorrMode(Byte Ref, Byte Adr) BEGIN if ((BAsmCode[Ref] & 0x4e)==0x44) BAsmCode[Adr]=(BAsmCode[Adr] & 0xfc) | OpSize; END static Boolean ArgPair(const char *Val1, const char *Val2) BEGIN return (((strcasecmp(ArgStr[1],Val1)==0) AND (strcasecmp(ArgStr[2],Val2)==0)) OR ((strcasecmp(ArgStr[1],Val2)==0) AND (strcasecmp(ArgStr[2],Val1)==0))); END static LongInt ImmVal(void) BEGIN LongInt tmp; tmp=AdrVals[0]; if (OpSize>=1) tmp+=((LongInt)AdrVals[1]) << 8; if (OpSize==2) BEGIN tmp+=((LongInt)AdrVals[2]) << 16; tmp+=((LongInt)AdrVals[3]) << 24; END return tmp; END static Boolean IsPwr2(LongInt Inp, Byte *Erg) BEGIN LongInt Shift; Shift=1; *Erg=0; do BEGIN if (Inp==Shift) return True; Shift+=Shift; (*Erg)++; END while (Shift!=0); return False; END static Boolean IsShort(Byte Code) BEGIN return ((Code & 0x4e)==40); END static void CheckSup(void) BEGIN if (MomCPU==CPU96C141) if (NOT SupAllowed) WrError(50); END /*---------------------------------------------------------------------------*/ static void DecodeMULA(Word Index) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN DecodeAdr(ArgStr[1],MModReg+MModXReg); if ((AdrType!=ModNone) AND (OpSize!=2)) WrError(1130); else switch (AdrType) BEGIN case ModReg: CodeLen=2; BAsmCode[0]=0xd8+AdrMode; BAsmCode[1]=0x19; break; case ModXReg: CodeLen=3; BAsmCode[0]=0xd7; BAsmCode[1]=AdrMode; BAsmCode[2]=0x19; break; END END END static void DecodeJPCALL(Word Index) BEGIN int z; if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110); else BEGIN if (ArgCnt==1) z=DefaultCondition; else BEGIN z=0; NLS_UpString(ArgStr[1]); while ((z=ConditionCnt) WrError(1360); else BEGIN OpSize=2; DecodeAdr(ArgStr[ArgCnt],MModMem+MModImm); if (AdrType==ModImm) if (AdrVals[3]!=0) BEGIN WrError(1320); AdrType=ModNone; END else if (AdrVals[2]!=0) BEGIN AdrType=ModMem; AdrMode=0x42; AdrCnt=3; END else BEGIN AdrType=ModMem; AdrMode=0x41; AdrCnt=2; END if (AdrType==ModMem) if ((z==DefaultCondition) AND ((AdrMode==0x41) OR (AdrMode==0x42))) BEGIN CodeLen=1+AdrCnt; BAsmCode[0]=0x1a+2*Index+(AdrCnt-2); memcpy(BAsmCode+1,AdrVals,AdrCnt); END else BEGIN CodeLen=2+AdrCnt; BAsmCode[0]=0xb0+AdrMode; memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=0xd0+(Index << 4)+(Conditions[z].Code); END END END END static void DecodeJR(Word Index) BEGIN Boolean OK; int z; LongInt AdrLong; if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110); else BEGIN if (ArgCnt==1) z=DefaultCondition; else BEGIN z=0; NLS_UpString(ArgStr[1]); while ((z=ConditionCnt) WrError(1360); else BEGIN AdrLong=EvalIntExpression(ArgStr[ArgCnt],Int32,&OK); if (OK) if (Index==1) BEGIN AdrLong-=EProgCounter()+3; if (((AdrLong>0x7fffl) OR (AdrLong<-0x8000l)) AND (NOT SymbolQuestionable)) WrError(1330); else BEGIN CodeLen=3; BAsmCode[0]=0x70+Conditions[z].Code; BAsmCode[1]=Lo(AdrLong); BAsmCode[2]=Hi(AdrLong); if (NOT FirstPassUnknown) BEGIN AdrLong++; if ((AdrLong>=-128) AND (AdrLong<=127)) WrError(20); END END END else BEGIN AdrLong-=EProgCounter()+2; if (((AdrLong>127) OR (AdrLong<-128)) AND (NOT SymbolQuestionable)) WrError(1330); else BEGIN CodeLen=2; BAsmCode[0]=0x60+Conditions[z].Code; BAsmCode[1]=Lo(AdrLong); END END END END END static void DecodeCALR(Word Index) BEGIN LongInt AdrLong; Boolean OK; if (ArgCnt!=1) WrError(1110); else BEGIN AdrLong=EvalIntExpression(ArgStr[1],Int32,&OK)-(EProgCounter()+3); if (OK) if (((AdrLong<-32768) OR (AdrLong>32767)) AND (NOT SymbolQuestionable)) WrError(1330); else BEGIN CodeLen=3; BAsmCode[0]=0x1e; BAsmCode[1]=Lo(AdrLong); BAsmCode[2]=Hi(AdrLong); END END END static void DecodeRET(Word Index) BEGIN int z; if (ArgCnt>1) WrError(1110); else BEGIN if (ArgCnt==0) z=DefaultCondition; else BEGIN z=0; NLS_UpString(ArgStr[1]); while ((z=ConditionCnt) WrError(1360); else if (z==DefaultCondition) BEGIN CodeLen=1; BAsmCode[0]=0x0e; END else BEGIN CodeLen=2; BAsmCode[0]=0xb0; BAsmCode[1]=0xf0+Conditions[z].Code; END END END static void DecodeRETD(Word Index) BEGIN Word AdrWord; Boolean OK; if (ArgCnt!=1) WrError(1110); else BEGIN AdrWord=EvalIntExpression(ArgStr[1],Int16,&OK); if (OK) BEGIN CodeLen=3; BAsmCode[0]=0x0f; BAsmCode[1]=Lo(AdrWord); BAsmCode[2]=Hi(AdrWord); END END END static void DecodeDJNZ(Word Index) BEGIN LongInt AdrLong; Boolean OK; if ((ArgCnt!=2) AND (ArgCnt!=1)) WrError(1110); else BEGIN if (ArgCnt==1) BEGIN AdrType=ModReg; AdrMode=2; OpSize=0; END else DecodeAdr(ArgStr[1],MModReg+MModXReg); if (AdrType!=ModNone) if (OpSize==2) WrError(1130); else BEGIN AdrLong=EvalIntExpression(ArgStr[ArgCnt],Int32,&OK)-(EProgCounter()+3+Ord(AdrType==ModXReg)); if (OK) if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT SymbolQuestionable)) WrError(1370); else switch (AdrType) BEGIN case ModReg: CodeLen=3; BAsmCode[0]=0xc8+(OpSize << 4)+AdrMode; BAsmCode[1]=0x1c; BAsmCode[2]=AdrLong & 0xff; break; case ModXReg: CodeLen=4; BAsmCode[0]=0xc7+(OpSize << 4); BAsmCode[1]=AdrMode; BAsmCode[2]=0x1c; BAsmCode[3]=AdrLong & 0xff; break; END END END END static void DecodeEX(Word Index) BEGIN Byte HReg; if (ArgCnt!=2) WrError(1110); else if ((ArgPair("F","F\'")) OR (ArgPair("F`","F"))) BEGIN CodeLen=1; BAsmCode[0]=0x16; END else BEGIN DecodeAdr(ArgStr[1],MModReg+MModXReg+MModMem); if (OpSize==2) WrError(1130); else switch (AdrType) BEGIN case ModReg: HReg=AdrMode; DecodeAdr(ArgStr[2],MModReg+MModXReg+MModMem); switch (AdrType) BEGIN case ModReg: CodeLen=2; BAsmCode[0]=0xc8+(OpSize << 4)+AdrMode; BAsmCode[1]=0xb8+HReg; break; case ModXReg: CodeLen=3; BAsmCode[0]=0xc7+(OpSize << 4); BAsmCode[1]=AdrMode; BAsmCode[2]=0xb8+HReg; break; case ModMem: CodeLen=2+AdrCnt; BAsmCode[0]=0x80+(OpSize << 4)+AdrMode; memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=0x30+HReg; break; END break; case ModXReg: HReg=AdrMode; DecodeAdr(ArgStr[2],MModReg); if (AdrType==ModReg) BEGIN CodeLen=3; BAsmCode[0]=0xc7+(OpSize << 4); BAsmCode[1]=HReg; BAsmCode[2]=0xb8+AdrMode; END break; case ModMem: MinOneIs0=True; HReg=AdrCnt; BAsmCode[0]=AdrMode; memcpy(BAsmCode+1,AdrVals,AdrCnt); DecodeAdr(ArgStr[2],MModReg); if (AdrType==ModReg) BEGIN CodeLen=2+HReg; CorrMode(0,1); BAsmCode[0]+=0x80+(OpSize << 4); BAsmCode[1+HReg]=0x30+AdrMode; END break; END END END static void DecodeBS1x(Word Index) BEGIN if (ArgCnt!=2) WrError(1110); else if (strcasecmp(ArgStr[1],"A")!=0) WrError(1135); else BEGIN DecodeAdr(ArgStr[2],MModReg+MModXReg); if (OpSize!=1) WrError(1130); else switch (AdrType) BEGIN case ModReg: CodeLen=2; BAsmCode[0]=0xd8+AdrMode; BAsmCode[1]=0x0e +Index; /* ANSI */ break; case ModXReg: CodeLen=3; BAsmCode[0]=0xd7; BAsmCode[1]=AdrMode; BAsmCode[2]=0x0e +Index; /* ANSI */ break; END END END static void DecodeLDA(Word Index) BEGIN Byte HReg; if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[1],MModReg); if (AdrType!=ModNone) if (OpSize<1) WrError(1130); else BEGIN HReg=AdrMode; DecodeAdr(ArgStr[2],MModMem); if (AdrType!=ModNone) BEGIN CodeLen=2+AdrCnt; BAsmCode[0]=0xb0+AdrMode; memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=0x20+((OpSize-1) << 4)+HReg; END END END END static void DecodeLDAR(Word Index) BEGIN LongInt AdrLong; Boolean OK; if (ArgCnt!=2) WrError(1110); else BEGIN AdrLong=EvalIntExpression(ArgStr[2],Int32,&OK)-(EProgCounter()+4); if (OK) if (((AdrLong<-32768) OR (AdrLong>32767)) AND (NOT SymbolQuestionable)) WrError(1330); else BEGIN DecodeAdr(ArgStr[1],MModReg); if (AdrType!=ModNone) if (OpSize<1) WrError(1130); else BEGIN CodeLen=5; BAsmCode[0]=0xf3; BAsmCode[1]=0x13; BAsmCode[2]=Lo(AdrLong); BAsmCode[3]=Hi(AdrLong); BAsmCode[4]=0x20+((OpSize-1) << 4)+AdrMode; END END END END static void DecodeLDC(Word Index) BEGIN Byte HReg; if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[1],MModReg+MModXReg+MModCReg); HReg=AdrMode; switch (AdrType) BEGIN case ModReg: DecodeAdr(ArgStr[2],MModCReg); if (AdrType!=ModNone) BEGIN CodeLen=3; BAsmCode[0]=0xc8+(OpSize << 4)+HReg; BAsmCode[1]=0x2f; BAsmCode[2]=AdrMode; END break; case ModXReg: DecodeAdr(ArgStr[2],MModCReg); if (AdrType!=ModNone) BEGIN CodeLen=4; BAsmCode[0]=0xc7+(OpSize << 4); BAsmCode[1]=HReg; BAsmCode[2]=0x2f; BAsmCode[3]=AdrMode; END; break; case ModCReg: DecodeAdr(ArgStr[2],MModReg+MModXReg); switch (AdrType) BEGIN case ModReg: CodeLen=3; BAsmCode[0]=0xc8+(OpSize << 4)+AdrMode; BAsmCode[1]=0x2e; BAsmCode[2]=HReg; break; case ModXReg: CodeLen=4; BAsmCode[0]=0xc7+(OpSize << 4); BAsmCode[1]=AdrMode; BAsmCode[2]=0x2e; BAsmCode[3]=HReg; break; END break; END END END static void DecodeLDX(Word Index) BEGIN Boolean OK; if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[1],MModMem); if (AdrType!=ModNone) if (AdrMode!=0x40) WrError(1350); else BEGIN BAsmCode[4]=EvalIntExpression(ArgStr[2],Int8,&OK); if (OK) BEGIN CodeLen=6; BAsmCode[0]=0xf7; BAsmCode[1]=0; BAsmCode[2]=AdrVals[0]; BAsmCode[3]=0; BAsmCode[5]=0; END END END END static void DecodeLINK(Word Index) BEGIN Word AdrWord; Boolean OK; if (ArgCnt!=2) WrError(1110); else BEGIN AdrWord=EvalIntExpression(ArgStr[2],Int16,&OK); if (OK) BEGIN DecodeAdr(ArgStr[1],MModReg+MModXReg); if ((AdrType!=ModNone) AND (OpSize!=2)) WrError(1130); else switch (AdrType) BEGIN case ModReg: CodeLen=4; BAsmCode[0]=0xe8+AdrMode; BAsmCode[1]=0x0c; BAsmCode[2]=Lo(AdrWord); BAsmCode[3]=Hi(AdrWord); break; case ModXReg: CodeLen=5; BAsmCode[0]=0xe7; BAsmCode[1]=AdrMode; BAsmCode[2]=0x0c; BAsmCode[3]=Lo(AdrWord); BAsmCode[4]=Hi(AdrWord); break; END END END END static void DecodeLD(Word Index) BEGIN Byte HReg; Boolean ShDest,ShSrc,OK; if (Index<3) OpSize=Index; if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[1],MModReg+MModXReg+MModMem); switch (AdrType) BEGIN case ModReg: HReg=AdrMode; DecodeAdr(ArgStr[2],MModReg+MModXReg+MModMem+MModImm); switch (AdrType) BEGIN case ModReg: CodeLen=2; BAsmCode[0]=0xc8+(OpSize << 4)+AdrMode; BAsmCode[1]=0x88+HReg; break; case ModXReg: CodeLen=3; BAsmCode[0]=0xc7+(OpSize << 4); BAsmCode[1]=AdrMode; BAsmCode[2]=0x88+HReg; break; case ModMem: CodeLen=2+AdrCnt; BAsmCode[0]=0x80+(OpSize << 4)+AdrMode; memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=0x20+HReg; break; case ModImm: if ((ImmVal()<=7) AND (ImmVal()>=0)) BEGIN CodeLen=2; BAsmCode[0]=0xc8+(OpSize << 4)+HReg; BAsmCode[1]=0xa8+AdrVals[0]; END else BEGIN CodeLen=1+AdrCnt; BAsmCode[0]=((OpSize+2) << 4)+HReg; memcpy(BAsmCode+1,AdrVals,AdrCnt); END break; END break; case ModXReg: HReg=AdrMode; DecodeAdr(ArgStr[2],MModReg+MModImm); switch (AdrType) BEGIN case ModReg: CodeLen=3; BAsmCode[0]=0xc7+(OpSize << 4); BAsmCode[1]=HReg; BAsmCode[2]=0x98+AdrMode; break; case ModImm: if ((ImmVal()<=7) AND (ImmVal()>=0)) BEGIN CodeLen=3; BAsmCode[0]=0xc7+(OpSize << 4); BAsmCode[1]=HReg; BAsmCode[2]=0xa8+AdrVals[0]; END else BEGIN CodeLen=3+AdrCnt; BAsmCode[0]=0xc7+(OpSize << 4); BAsmCode[1]=HReg; BAsmCode[2]=3; memcpy(BAsmCode+3,AdrVals,AdrCnt); END break; END break; case ModMem: BAsmCode[0]=AdrMode; HReg=AdrCnt; MinOneIs0=True; memcpy(BAsmCode+1,AdrVals,AdrCnt); DecodeAdr(ArgStr[2],MModReg+MModMem+MModImm); switch (AdrType) BEGIN case ModReg: CodeLen=2+HReg; BAsmCode[0]+=0xb0; CorrMode(0,1); BAsmCode[1+HReg]=0x40+(OpSize << 4)+AdrMode; break; case ModMem: if (OpSize==-1) OpSize=0; ShDest=IsShort(BAsmCode[0]); ShSrc=IsShort(AdrMode); if (NOT (ShDest OR ShSrc)) WrError(1350); else BEGIN if ((ShDest AND (NOT ShSrc))) OK=True; else if (ShSrc AND (NOT ShDest)) OK=False; else if (AdrMode==0x40) OK=True; else OK=False; if (OK) /* dest=(dir8/16) */ BEGIN CodeLen=4+AdrCnt; HReg=BAsmCode[0]; if (BAsmCode[0]==0x40) BAsmCode[3+AdrCnt]=0; else BAsmCode[3+AdrCnt]=BAsmCode[2]; BAsmCode[2+AdrCnt]=BAsmCode[1]; BAsmCode[0]=0x80+(OpSize << 4)+AdrMode; AdrMode=HReg; CorrMode(0,1); memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=0x19; END else BEGIN CodeLen=4+HReg; BAsmCode[2+HReg]=AdrVals[0]; if (AdrMode==0x40) BAsmCode[3+HReg]=0; else BAsmCode[3+HReg]=AdrVals[1]; BAsmCode[0]+=0xb0; CorrMode(0,1); BAsmCode[1+HReg]=0x14+(OpSize << 1); END END break; case ModImm: if (BAsmCode[0]==0x40) BEGIN CodeLen=2+AdrCnt; BAsmCode[0]=0x08+(OpSize << 1); memcpy(BAsmCode+2,AdrVals,AdrCnt); END else BEGIN CodeLen=2+HReg+AdrCnt; BAsmCode[0]+=0xb0; BAsmCode[1+HReg]=OpSize << 1; memcpy(BAsmCode+2+HReg,AdrVals,AdrCnt); END break; END break; END END END static void DecodeFixed(Word Index) BEGIN FixedOrder *FixedZ=FixedOrders+Index; if (ArgCnt!=0) WrError(1110); else if ((FixedZ->CPUFlag & (1 << (MomCPU-CPU96C141)))==0) WrError(1500); else BEGIN if (Hi(FixedZ->Code)==0) BEGIN CodeLen=1; BAsmCode[0]=Lo(FixedZ->Code); END else BEGIN CodeLen=2; BAsmCode[0]=Hi(FixedZ->Code); BAsmCode[1]=Lo(FixedZ->Code); END if (FixedZ->InSup) CheckSup(); END END static void DecodeImm(Word Index) BEGIN ImmOrder *ImmZ=ImmOrders+Index; Word AdrWord; Boolean OK; if ((ArgCnt>1) OR ((ImmZ->Default==-1) AND (ArgCnt==0))) WrError(1110); else BEGIN if (ArgCnt==0) BEGIN AdrWord=ImmZ->Default; OK=True; END else AdrWord=EvalIntExpression(ArgStr[1],Int8,&OK); if (OK) if (((Maximum) AND (AdrWord>ImmZ->MaxMax)) OR ((NOT Maximum) AND (AdrWord>ImmZ->MinMax))) WrError(1320); else if (Hi(ImmZ->Code)==0) BEGIN CodeLen=1; BAsmCode[0]=Lo(ImmZ->Code)+AdrWord; END else BEGIN CodeLen=2; BAsmCode[0]=Hi(ImmZ->Code); BAsmCode[1]=Lo(ImmZ->Code)+AdrWord; END if (ImmZ->InSup) CheckSup(); END END static void DecodeReg(Word Index) BEGIN RegOrder *RegZ=RegOrders+Index; if (ArgCnt!=1) WrError(1110); else BEGIN DecodeAdr(ArgStr[1],MModReg+MModXReg); if (AdrType!=ModNone) if (((1 << OpSize) & RegZ->OpMask)==0) WrError(1130); else if (AdrType==ModReg) BEGIN BAsmCode[0]=Hi(RegZ->Code)+8+(OpSize << 4)+AdrMode; BAsmCode[1]=Lo(RegZ->Code); CodeLen=2; END else BEGIN BAsmCode[0]=Hi(RegZ->Code)+7+(OpSize << 4); BAsmCode[1]=AdrMode; BAsmCode[2]=Lo(RegZ->Code); CodeLen=3; END END END /*---------------------------------------------------------------------------*/ static void AddFixed(char *NName, Word NCode, Byte NFlag, Boolean NSup) BEGIN if (InstrZ>=FixedOrderCnt) exit(255); FixedOrders[InstrZ].Name=NName; FixedOrders[InstrZ].Code=NCode; FixedOrders[InstrZ].CPUFlag=NFlag; FixedOrders[InstrZ].InSup=NSup; AddInstTable(InstTable,NName,InstrZ++,DecodeFixed); END static void AddReg(char *NName, Word NCode, Byte NMask) BEGIN if (InstrZ>=RegOrderCnt) exit(255); RegOrders[InstrZ].Name=NName; RegOrders[InstrZ].Code=NCode; RegOrders[InstrZ].OpMask=NMask; AddInstTable(InstTable,NName,InstrZ++,DecodeReg); END static void AddImm(char *NName, Word NCode, Boolean NInSup, Byte NMinMax, Byte NMaxMax, ShortInt NDefault) BEGIN if (InstrZ>=ImmOrderCnt) exit(255); ImmOrders[InstrZ].Name=NName; ImmOrders[InstrZ].Code=NCode; ImmOrders[InstrZ].InSup=NInSup; ImmOrders[InstrZ].MinMax=NMinMax; ImmOrders[InstrZ].MaxMax=NMaxMax; ImmOrders[InstrZ].Default=NDefault; AddInstTable(InstTable,NName,InstrZ++,DecodeImm); END static void AddALU2(char *NName, Byte NCode) BEGIN if (InstrZ>=ALU2OrderCnt) exit(255); ALU2Orders[InstrZ].Name=NName; ALU2Orders[InstrZ++].Code=NCode; END static void AddShift(char *NName) BEGIN if (InstrZ>=ShiftOrderCnt) exit(255); ShiftOrders[InstrZ++]=NName; END static void AddMulDiv(char *NName) BEGIN if (InstrZ>=MulDivOrderCnt) exit(255); MulDivOrders[InstrZ++]=NName; END static void AddBitCF(char *NName, Byte NCode) BEGIN if (InstrZ>=BitCFOrderCnt) exit(255); BitCFOrders[InstrZ].Name=NName; BitCFOrders[InstrZ++].Code=NCode; END static void AddBit(char *NName) BEGIN if (InstrZ>=BitOrderCnt) exit(255); BitOrders[InstrZ++]=NName; END static void AddCondition(char *NName, Byte NCode) BEGIN if (InstrZ>=ConditionCnt) exit(255); Conditions[InstrZ].Name=NName; Conditions[InstrZ++].Code=NCode; END static void InitFields(void) BEGIN InstTable=CreateInstTable(201); AddInstTable(InstTable,"MULA" ,0,DecodeMULA); AddInstTable(InstTable,"JP" ,0,DecodeJPCALL); AddInstTable(InstTable,"CALL" ,1,DecodeJPCALL); AddInstTable(InstTable,"JR" ,0,DecodeJR); AddInstTable(InstTable,"JRL" ,1,DecodeJR); AddInstTable(InstTable,"CALR" ,0,DecodeCALR); AddInstTable(InstTable,"RET" ,0,DecodeRET); AddInstTable(InstTable,"RETD" ,0,DecodeRETD); AddInstTable(InstTable,"DJNZ" ,0,DecodeDJNZ); AddInstTable(InstTable,"EX" ,0,DecodeEX); AddInstTable(InstTable,"BS1F" ,0,DecodeBS1x); AddInstTable(InstTable,"BS1B" ,0,DecodeBS1x); AddInstTable(InstTable,"LDA" ,0,DecodeLDA); AddInstTable(InstTable,"LDAR" ,0,DecodeLDAR); AddInstTable(InstTable,"LDC" ,0,DecodeLDC); AddInstTable(InstTable,"LDX" ,0,DecodeLDX); AddInstTable(InstTable,"LINK" ,0,DecodeLINK); AddInstTable(InstTable,"LDB" ,0,DecodeLD); AddInstTable(InstTable,"LDW" ,1,DecodeLD); AddInstTable(InstTable,"LDL" ,2,DecodeLD); AddInstTable(InstTable,"LD" ,3,DecodeLD); FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); InstrZ=0; AddFixed("CCF" , 0x0012, 3, False); AddFixed("DECF" , 0x000d, 3, False); AddFixed("DI" , 0x0607, 3, True ); AddFixed("HALT" , 0x0005, 3, True ); AddFixed("INCF" , 0x000c, 3, False); AddFixed("MAX" , 0x0004, 1, True ); AddFixed("MIN" , 0x0004, 2, True ); AddFixed("NOP" , 0x0000, 3, False); AddFixed("NORMAL", 0x0001, 1, True ); AddFixed("RCF" , 0x0010, 3, False); AddFixed("RETI" , 0x0007, 3, True ); AddFixed("SCF" , 0x0011, 3, False); AddFixed("ZCF" , 0x0013, 3, False); RegOrders=(RegOrder *) malloc(sizeof(RegOrder)*RegOrderCnt); InstrZ=0; AddReg("CPL" , 0xc006, 3); AddReg("DAA" , 0xc010, 1); AddReg("EXTS", 0xc013, 6); AddReg("EXTZ", 0xc012, 6); AddReg("MIRR", 0xc016, 2); AddReg("NEG" , 0xc007, 3); AddReg("PAA" , 0xc014, 6); AddReg("UNLK", 0xc00d, 4); ImmOrders=(ImmOrder *) malloc(sizeof(ImmOrder)*ImmOrderCnt); InstrZ=0; AddImm("EI" , 0x0600, True, 7, 7, 0); AddImm("LDF" , 0x1700, False, 7, 3, -1); AddImm("SWI" , 0x00f8, False, 7, 7, 7); ALU2Orders=(ALU2Order *) malloc(sizeof(ALU2Order)*ALU2OrderCnt); InstrZ=0; AddALU2("ADC", 1); AddALU2("ADD", 0); AddALU2("AND", 4); AddALU2("OR" , 6); AddALU2("SBC", 3); AddALU2("SUB", 2); AddALU2("XOR", 5); AddALU2("CP" , 7); ShiftOrders=(char **) malloc(sizeof(char*)*ShiftOrderCnt); InstrZ=0; AddShift("RLC"); AddShift("RRC"); AddShift("RL"); AddShift("RR"); AddShift("SLA"); AddShift("SRA"); AddShift("SLL"); AddShift("SRL"); MulDivOrders=(char **) malloc(sizeof(char*)*MulDivOrderCnt); InstrZ=0; AddMulDiv("MUL"); AddMulDiv("MULS"); AddMulDiv("DIV"); AddMulDiv("DIVS"); BitCFOrders=(ALU2Order *) malloc(sizeof(ALU2Order)*BitCFOrderCnt); InstrZ=0; AddBitCF("ANDCF" , 0); AddBitCF("LDCF" , 3); AddBitCF("ORCF" , 1); AddBitCF("STCF" , 4); AddBitCF("XORCF" , 2); BitOrders=(char **) malloc(sizeof(char*)*BitOrderCnt); InstrZ=0; AddBit("RES"); AddBit("SET"); AddBit("CHG"); AddBit("BIT"); AddBit("TSET"); Conditions=(Condition *) malloc(sizeof(Condition)*ConditionCnt); InstrZ=0; AddCondition("F" , 0); DefaultCondition=InstrZ; AddCondition("T" , 8); AddCondition("Z" , 6); AddCondition("NZ" , 14); AddCondition("C" , 7); AddCondition("NC" , 15); AddCondition("PL" , 13); AddCondition("MI" , 5); AddCondition("P" , 13); AddCondition("M" , 5); AddCondition("NE" , 14); AddCondition("EQ" , 6); AddCondition("OV" , 4); AddCondition("NOV" , 12); AddCondition("PE" , 4); AddCondition("PO" , 12); AddCondition("GE" , 9); AddCondition("LT" , 1); AddCondition("GT" , 10); AddCondition("LE" , 2); AddCondition("UGE" , 15); AddCondition("ULT" , 7); AddCondition("UGT" , 11); AddCondition("ULE" , 3); END static void DeinitFields(void) BEGIN DestroyInstTable(InstTable); free(FixedOrders); free(RegOrders); free(ImmOrders); free(ALU2Orders); free(ShiftOrders); free(MulDivOrders); free(BitCFOrders); free(BitOrders); free(Conditions); END static Boolean WMemo(char *Asc_O) BEGIN int l=strlen(Asc_O); if (strncmp(OpPart,Asc_O,l)!=0) return False; switch (OpPart[l]) BEGIN case '\0': return True; case 'W': if (OpPart[l+1]=='\0') BEGIN OpSize=1; return True; END else return False; case 'L': if (OpPart[l+1]=='\0') BEGIN OpSize=2; return True; END else return False; case 'B': if (OpPart[l+1]=='\0') BEGIN OpSize=0; return True; END else return False; default: return False; END END static Boolean DecodePseudo(void) BEGIN return False; END static Boolean CodeMove(void) BEGIN if ((WMemo("POP")) OR (WMemo("PUSH"))) BEGIN if (ArgCnt!=1) WrError(1110); else if (strcasecmp(ArgStr[1],"F")==0) BEGIN CodeLen=1; BAsmCode[0]=0x18+Ord(Memo("POP")); END else if (strcasecmp(ArgStr[1],"A")==0) BEGIN CodeLen=1; BAsmCode[0]=0x14+Ord(Memo("POP")); END else if (strcasecmp(ArgStr[1],"SR")==0) BEGIN CodeLen=1; BAsmCode[0]=0x02+Ord(Memo("POP")); CheckSup(); END else BEGIN MinOneIs0=True; DecodeAdr(ArgStr[1],MModReg+MModXReg+MModMem+ (WMemo("PUSH")?MModImm:0)); switch (AdrType) BEGIN case ModReg: if (OpSize==0) BEGIN CodeLen=2; BAsmCode[0]=0xc8+(OpSize << 4)+AdrMode; BAsmCode[1]=0x04+Ord(Memo("POP")); END else BEGIN CodeLen=1; BAsmCode[0]=0x28+(Ord(Memo("POP")) << 5)+((OpSize-1) << 4)+AdrMode; END break; case ModXReg: CodeLen=3; BAsmCode[0]=0xc7+(OpSize << 4); BAsmCode[1]=AdrMode; BAsmCode[2]=0x04+Ord(Memo("POP")); break; case ModMem: if (OpSize==-1) OpSize=0; CodeLen=2+AdrCnt; if (strncmp(OpPart,"POP",3)==0) BAsmCode[0]=0xb0+AdrMode; else BAsmCode[0]=0x80+(OpSize << 4)+AdrMode; memcpy(BAsmCode+1,AdrVals,AdrCnt); if (strncmp(OpPart,"POP",3)==0) BAsmCode[1+AdrCnt]=0x04+(OpSize << 1); else BAsmCode[1+AdrCnt]=0x04; break; case ModImm: if (OpSize==-1) OpSize=0; BAsmCode[0]=9+(OpSize << 1); memcpy(BAsmCode+1,AdrVals,AdrCnt); CodeLen=1+AdrCnt; break; END END return True; END return False; END static void MakeCode_96C141(void) BEGIN int z; Word AdrWord; Boolean OK; Byte HReg; char *CmpStr; char LChar; CodeLen=0; DontPrint=False; OpSize=(-1); MinOneIs0=False; /* zu ignorierendes */ if (Memo("")) return; /* Pseudoanweisungen */ if (DecodePseudo()) return; if (DecodeIntelPseudo(False)) return; if (CodeMove()) return; /* vermischt */ if (LookupInstTable(InstTable,OpPart)) return; for (z=0; z=0)) BEGIN CodeLen=2; BAsmCode[0]=0xc8+(OpSize << 4)+HReg; BAsmCode[1]=0xd8+AdrVals[0]; END else BEGIN CodeLen=2+AdrCnt; BAsmCode[0]=0xc8+(OpSize << 4)+HReg; BAsmCode[1]=0xc8+ALU2Orders[z].Code; memcpy(BAsmCode+2,AdrVals,AdrCnt); END break; END break; case ModXReg: HReg=AdrMode; DecodeAdr(ArgStr[2],MModImm); switch (AdrType) BEGIN case ModImm: if ((ALU2Orders[z].Code==7) AND (OpSize!=2) AND (ImmVal()<=7) AND (ImmVal()>=0)) BEGIN CodeLen=3; BAsmCode[0]=0xc7+(OpSize << 4); BAsmCode[1]=HReg; BAsmCode[2]=0xd8+AdrVals[0]; END else BEGIN CodeLen=3+AdrCnt; BAsmCode[0]=0xc7+(OpSize << 4); BAsmCode[1]=HReg; BAsmCode[2]=0xc8+ALU2Orders[z].Code; memcpy(BAsmCode+3,AdrVals,AdrCnt); END break; END break; case ModMem: MinOneIs0=True; HReg=AdrCnt; BAsmCode[0]=AdrMode; memcpy(BAsmCode+1,AdrVals,AdrCnt); DecodeAdr(ArgStr[2],MModReg+MModImm); switch (AdrType) BEGIN case ModReg: CodeLen=2+HReg; CorrMode(0,1); BAsmCode[0]+=0x80+(OpSize << 4); BAsmCode[1+HReg]=0x88+(ALU2Orders[z].Code << 4)+AdrMode; break; case ModImm: CodeLen=2+HReg+AdrCnt; BAsmCode[0]+=0x80+(OpSize << 4); BAsmCode[1+HReg]=0x38+ALU2Orders[z].Code; memcpy(BAsmCode+2+HReg,AdrVals,AdrCnt); break; END; break; END END return; END for (z=0; z16)) BEGIN WrError(1320); OK=False; END else HReg&=0x0f; END if (OK) BEGIN DecodeAdr(ArgStr[ArgCnt],MModReg+MModXReg+((HReg==0xff)?0:MModMem)); switch (AdrType) BEGIN case ModReg: CodeLen=2+Ord(HReg!=0xff); BAsmCode[0]=0xc8+(OpSize << 4)+AdrMode; BAsmCode[1]=0xe8+z; if (HReg==0xff) BAsmCode[1]+=0x10; else BAsmCode[2]=HReg; break; case ModXReg: CodeLen=3+Ord(HReg!=0xff); BAsmCode[0]=0xc7+(OpSize << 4); BAsmCode[1]=AdrMode; BAsmCode[2]=0xe8+z; if (HReg==0xff) BAsmCode[2]+=0x10; else BAsmCode[3]=HReg; break; case ModMem: if (HReg!=1) WrError(1350); else BEGIN if (OpSize==-1) OpSize=0; CodeLen=2+AdrCnt; BAsmCode[0]=0x80+(OpSize << 4)+AdrMode; memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=0x78+z; END break; END END END return; END for (z=0;z3) BEGIN AdrType=ModXReg; AdrMode=0xe0+(AdrMode << 2); END else AdrMode+=1+AdrMode; OpSize--; HReg=AdrMode; switch (AdrType) BEGIN case ModReg: DecodeAdr(ArgStr[2],MModReg+MModXReg+MModMem+MModImm); switch (AdrType) BEGIN case ModReg: CodeLen=2; BAsmCode[0]=0xc8+(OpSize << 4)+AdrMode; BAsmCode[1]=0x40+(z << 3)+HReg; break; case ModXReg: CodeLen=3; BAsmCode[0]=0xc7+(OpSize << 4); BAsmCode[1]=AdrMode; BAsmCode[2]=0x40+(z << 3)+HReg; break; case ModMem: CodeLen=2+AdrCnt; BAsmCode[0]=0x80+(OpSize << 4)+AdrMode; memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=0x40+(z << 3)+HReg; break; case ModImm: CodeLen=2+AdrCnt; BAsmCode[0]=0xc8+(OpSize << 4)+HReg; BAsmCode[1]=0x08+z; memcpy(BAsmCode+2,AdrVals,AdrCnt); break; END break; case ModXReg: DecodeAdr(ArgStr[2],MModImm); if (AdrType==ModImm) BEGIN CodeLen=3+AdrCnt; BAsmCode[0]=0xc7+(OpSize << 4); BAsmCode[1]=HReg; BAsmCode[2]=0x08+z; memcpy(BAsmCode+3,AdrVals,AdrCnt); END break; END END END return; END for (z=0; z8)) BEGIN WrError(1320); OK=False; END if (OK) BEGIN HReg&=7; /* 8-->0 */ DecodeAdr(ArgStr[ArgCnt],MModReg+MModXReg+MModMem); switch (AdrType) BEGIN case ModReg: CodeLen=2; BAsmCode[0]=0xc8+(OpSize << 4)+AdrMode; BAsmCode[1]=0x60+(Ord(WMemo("DEC")) << 3)+HReg; break; case ModXReg: CodeLen=3; BAsmCode[0]=0xc7+(OpSize << 4); BAsmCode[1]=AdrMode; BAsmCode[2]=0x60+(Ord(WMemo("DEC")) << 3)+HReg; break; case ModMem: if (OpSize==-1) OpSize=0; CodeLen=2+AdrCnt; BAsmCode[0]=0x80+AdrMode+(OpSize << 4); memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=0x60+(Ord(WMemo("DEC")) << 3)+HReg; break; END END END return; END if ((Memo("CPD")) OR (Memo("CPDR")) OR (Memo("CPI")) OR (Memo("CPIR"))) BEGIN if ((ArgCnt!=0) AND (ArgCnt!=2)) WrError(1110); else BEGIN if (ArgCnt==0) BEGIN OK=True; OpSize=0; AdrMode=3; END else BEGIN OK=True; if (strcasecmp(ArgStr[1],"A")==0) OpSize=0; else if (strcasecmp(ArgStr[1],"WA")==0) OpSize=1; if (OpPart[2]=='I') CmpStr="+)"; else CmpStr="-)"; if (OpSize==-1) OK=False; else if ((*ArgStr[2]!='(') OR (strcasecmp(ArgStr[2]+strlen(ArgStr[2])-2,CmpStr)!=0)) OK=False; else BEGIN ArgStr[2][strlen(ArgStr[2])-2]='\0'; if (CodeEReg(ArgStr[2]+1,&AdrMode,&HReg)!=2) OK=False; else if (NOT IsRegBase(AdrMode,HReg)) OK=False; else if (NOT IsRegCurrent(AdrMode,HReg,&AdrMode)) OK=False; END if (NOT OK) WrError(1135); END if (OK) BEGIN CodeLen=2; BAsmCode[0]=0x80+(OpSize << 4)+AdrMode; BAsmCode[1]=0x14+(Ord(OpPart[2]=='D') << 1)+(strlen(OpPart)-3); END END return; END if ((WMemo("LDD")) OR (WMemo("LDDR")) OR (WMemo("LDI")) OR (WMemo("LDIR"))) BEGIN if (OpSize==-1) OpSize=0; if (OpSize==2) WrError(1130); else if ((ArgCnt!=0) AND (ArgCnt!=2)) WrError(1110); else BEGIN if (ArgCnt==0) BEGIN OK=True; HReg=0; END else BEGIN OK=True; if (OpPart[2]=='I') CmpStr="+)"; else CmpStr="-)"; if ((*ArgStr[1]!='(') OR (*ArgStr[2]!='(') OR (strcasecmp(ArgStr[1]+strlen(ArgStr[1])-2,CmpStr)!=0) OR (strcasecmp(ArgStr[2]+strlen(ArgStr[2])-2,CmpStr)!=0)) OK=False; else BEGIN strcpy(ArgStr[1],ArgStr[1]+1); ArgStr[1][strlen(ArgStr[1])-2]='\0'; strcpy(ArgStr[2],ArgStr[2]+1); ArgStr[2][strlen(ArgStr[2])-2]='\0'; if ((strcasecmp(ArgStr[1],"XIX")==0) AND (strcasecmp(ArgStr[2],"XIY")==0)) HReg=2; else if ((Maximum) AND (strcasecmp(ArgStr[1],"XDE")==0) AND (strcasecmp(ArgStr[2],"XHL")==0)) HReg=0; else if ((NOT Maximum) AND (strcasecmp(ArgStr[1],"DE")==0) AND (strcasecmp(ArgStr[2],"HL")==0)) HReg=0; else OK=False; END END if (NOT OK) WrError(1350); else BEGIN CodeLen=2; BAsmCode[0]=0x83+(OpSize << 4)+HReg; BAsmCode[1]=0x10+(Ord(OpPart[2]=='D') << 1)+Ord(strchr(OpPart,'R')!=Nil); END END return; END LChar=OpPart[strlen(OpPart)-1]; if (((strncmp(OpPart,"MDEC",4)==0) OR (strncmp(OpPart,"MINC",4)==0)) AND (LChar>='1') AND (LChar<='4')) BEGIN if (LChar=='3') WrError(1135); else if (ArgCnt!=2) WrError(1110); else BEGIN AdrWord=EvalIntExpression(ArgStr[1],Int16,&OK); if (OK) if (NOT IsPwr2(AdrWord,&HReg)) WrError(1135); else if ((HReg==0) OR ((LChar=='2') AND (HReg<2)) OR ((LChar=='4') AND (HReg<3))) WrError(1135); else BEGIN AdrWord-=LChar-'0'; IsPwr2(LChar-'0',&HReg); DecodeAdr(ArgStr[2],MModReg+MModXReg); if ((AdrType!=ModNone) AND (OpSize!=1)) WrError(1130); else switch (AdrType) BEGIN case ModReg: CodeLen=4; BAsmCode[0]=0xd8+AdrMode; BAsmCode[1]=0x38+(Ord(OpPart[2]=='D') << 2)+HReg; BAsmCode[2]=Lo(AdrWord); BAsmCode[3]=Hi(AdrWord); break; case ModXReg: CodeLen=5; BAsmCode[0]=0xd7; BAsmCode[1]=AdrMode; BAsmCode[2]=0x38+(Ord(OpPart[2]=='D') << 2)+HReg; BAsmCode[3]=Lo(AdrWord); BAsmCode[4]=Hi(AdrWord); break; END END END return; END if ((Memo("RLD")) OR (Memo("RRD"))) BEGIN if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110); else if ((ArgCnt==2) AND (strcasecmp(ArgStr[1],"A")!=0)) WrError(1350); else BEGIN DecodeAdr(ArgStr[ArgCnt],MModMem); if (AdrType!=ModNone) BEGIN CodeLen=2+AdrCnt; BAsmCode[0]=0x80+AdrMode; memcpy(BAsmCode+1,AdrVals,AdrCnt); BAsmCode[1+AdrCnt]=0x06+Ord(Memo("RRD")); END END return; END if (Memo("SCC")) BEGIN if (ArgCnt!=2) WrError(1110); else BEGIN z=0; NLS_UpString(ArgStr[1]); while ((z=ConditionCnt) WrError(1360); else BEGIN DecodeAdr(ArgStr[2],MModReg+MModXReg); if (OpSize>1) WrError(1110); else switch (AdrType) BEGIN case ModReg: CodeLen=2; BAsmCode[0]=0xc8+(OpSize << 4)+AdrMode; BAsmCode[1]=0x70+Conditions[z].Code; break; case ModXReg: CodeLen=3; BAsmCode[0]=0xc7+(OpSize << 4); BAsmCode[1]=AdrMode; BAsmCode[2]=0x70+Conditions[z].Code; break; END END END return; END WrXError(1200,OpPart); END static Boolean ChkPC_96C141(LargeWord Addr) BEGIN Boolean ok; switch (ActPC) BEGIN case SegCode: if (Maximum) ok=(Addr<=0xffffff); else ok=(Addr<=0xffff); break; default: ok=False; END return (ok); END static Boolean IsDef_96C141(void) BEGIN return False; END static void SwitchFrom_96C141(void) BEGIN DeinitFields(); ClearONOFF(); END static void SwitchTo_96C141(void) BEGIN TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=True; PCSymbol="$"; HeaderID=0x52; NOPCode=0x00; DivideChars=","; HasAttrs=False; ValidSegs=(1<