/* code166.c */ /*****************************************************************************/ /* AS-Portierung */ /* */ /* AS-Codegenerator Siemens 80C16x */ /* */ /* Historie: 11.11.1996 (alaaf) Grundsteinlegung */ /* 9. 5.1998 Registersymbole */ /* 3. 1.1999 ChkPC angepasst */ /* */ /*****************************************************************************/ #include "stdinc.h" #include #include #include "nls.h" #include "strutil.h" #include "bpemu.h" #include "asmdef.h" #include "asmsub.h" #include "asmpars.h" #include "codepseudo.h" #include "codevars.h" typedef struct { char *Name; CPUVar MinCPU; Word Code1,Code2; } BaseOrder; typedef struct { char *Name; Byte Code; } SimpOrder; typedef struct { char *Name; Byte Code; } Condition; #define FixedOrderCount 10 #define ConditionCount 20 #define ALU2OrderCount 8 #define ShiftOrderCount 5 #define Bit2OrderCount 6 #define LoopOrderCount 4 #define DivOrderCount 4 #define BJmpOrderCount 4 #define MulOrderCount 3 #define DPPCount 4 static char *RegNames[6]={"DPP0","DPP1","DPP2","DPP3","CP","SP"}; static CPUVar CPU80C166,CPU80C167; static BaseOrder *FixedOrders; static Condition *Conditions; static int TrueCond; static char **ALU2Orders; static SimpOrder *ShiftOrders; static SimpOrder *Bit2Orders; static SimpOrder *LoopOrders; static char **DivOrders; static char **BJmpOrders; static char **MulOrders; static SimpProc SaveInitProc; static LongInt DPPAssumes[DPPCount]; static IntType MemInt,MemInt2; static Byte OpSize; static Boolean DPPChanged[DPPCount],N_DPPChanged[DPPCount]; static Boolean SPChanged,CPChanged,N_SPChanged,N_CPChanged; static ShortInt ExtCounter; static enum {MemModeStd,MemModeNoCheck,MemModeZeroPage,MemModeFixedBank,MemModeFixedPage} MemMode; /* normal EXTS Rn EXTP Rn EXTS nn EXTP nn */ static Word MemPage; static Boolean ExtSFRs; /*-------------------------------------------------------------------------*/ static void AddFixed(char *NName, CPUVar NMin, Word NCode1, Word NCode2) BEGIN if (InstrZ>=FixedOrderCount) exit(255); FixedOrders[InstrZ].Name=NName; FixedOrders[InstrZ].MinCPU=NMin; FixedOrders[InstrZ].Code1=NCode1; FixedOrders[InstrZ++].Code2=NCode2; END static void AddShift(char *NName, Byte NCode) BEGIN if (InstrZ>=ShiftOrderCount) exit(255); ShiftOrders[InstrZ].Name=NName; ShiftOrders[InstrZ++].Code=NCode; END static void AddBit2(char *NName, Byte NCode) BEGIN if (InstrZ>=Bit2OrderCount) exit(255); Bit2Orders[InstrZ].Name=NName; Bit2Orders[InstrZ++].Code=NCode; END static void AddLoop(char *NName, Byte NCode) BEGIN if (InstrZ>=LoopOrderCount) exit(255); LoopOrders[InstrZ].Name=NName; LoopOrders[InstrZ++].Code=NCode; END static void AddCondition(char *NName, Byte NCode) BEGIN if (InstrZ>=ConditionCount) exit(255); Conditions[InstrZ].Name=NName; Conditions[InstrZ++].Code=NCode; END static void InitFields(void) BEGIN FixedOrders=(BaseOrder *) malloc(FixedOrderCount*sizeof(BaseOrder)); InstrZ=0; AddFixed("DISWDT",CPU80C166,0x5aa5,0xa5a5); AddFixed("EINIT" ,CPU80C166,0x4ab5,0xb5b5); AddFixed("IDLE" ,CPU80C166,0x7887,0x8787); AddFixed("NOP" ,CPU80C166,0x00cc,0x0000); AddFixed("PWRDN" ,CPU80C166,0x6897,0x9797); AddFixed("RET" ,CPU80C166,0x00cb,0x0000); AddFixed("RETI" ,CPU80C166,0x88fb,0x0000); AddFixed("RETS" ,CPU80C166,0x00db,0x0000); AddFixed("SRST" ,CPU80C166,0x48b7,0xb7b7); AddFixed("SRVWDT",CPU80C166,0x58a7,0xa7a7); Conditions=(Condition *) malloc(sizeof(Condition)*ConditionCount); InstrZ=0; TrueCond=InstrZ; AddCondition("UC" ,0x0); AddCondition("Z" ,0x2); AddCondition("NZ" ,0x3); AddCondition("V" ,0x4); AddCondition("NV" ,0x5); AddCondition("N" ,0x6); AddCondition("NN" ,0x7); AddCondition("C" ,0x8); AddCondition("NC" ,0x9); AddCondition("EQ" ,0x2); AddCondition("NE" ,0x3); AddCondition("ULT",0x8); AddCondition("ULE",0xf); AddCondition("UGE",0x9); AddCondition("UGT",0xe); AddCondition("SLT",0xc); AddCondition("SLE",0xb); AddCondition("SGE",0xd); AddCondition("SGT",0xa); AddCondition("NET",0x1); ALU2Orders=(char **) malloc(sizeof(char *)*ALU2OrderCount); InstrZ=0; ALU2Orders[InstrZ++]="ADD" ; ALU2Orders[InstrZ++]="ADDC"; ALU2Orders[InstrZ++]="SUB" ; ALU2Orders[InstrZ++]="SUBC"; ALU2Orders[InstrZ++]="CMP" ; ALU2Orders[InstrZ++]="XOR" ; ALU2Orders[InstrZ++]="AND" ; ALU2Orders[InstrZ++]="OR" ; ShiftOrders=(SimpOrder *) malloc(sizeof(SimpOrder)*ShiftOrderCount); InstrZ=0; AddShift("ASHR",0xac); AddShift("ROL" ,0x0c); AddShift("ROR" ,0x2c); AddShift("SHL" ,0x4c); AddShift("SHR" ,0x6c); Bit2Orders=(SimpOrder *) malloc(sizeof(SimpOrder)*Bit2OrderCount); InstrZ=0; AddBit2("BAND",0x6a); AddBit2("BCMP" ,0x2a); AddBit2("BMOV",0x4a); AddBit2("BMOVN",0x3a); AddBit2("BOR" ,0x5a); AddBit2("BXOR" ,0x7a); LoopOrders=(SimpOrder *) malloc(sizeof(SimpOrder)*LoopOrderCount); InstrZ=0; AddLoop("CMPD1",0xa0); AddLoop("CMPD2",0xb0); AddLoop("CMPI1",0x80); AddLoop("CMPI2",0x90); DivOrders=(char **) malloc(sizeof(char *)*DivOrderCount); InstrZ=0; DivOrders[InstrZ++]="DIV"; DivOrders[InstrZ++]="DIVU"; DivOrders[InstrZ++]="DIVL"; DivOrders[InstrZ++]="DIVLU"; BJmpOrders=(char **) malloc(sizeof(char *)*BJmpOrderCount); InstrZ=0; BJmpOrders[InstrZ++]="JB"; BJmpOrders[InstrZ++]="JNB"; BJmpOrders[InstrZ++]="JBC"; BJmpOrders[InstrZ++]="JNBS"; MulOrders=(char **) malloc(sizeof(char *)*MulOrderCount); InstrZ=0; MulOrders[InstrZ++]="MUL"; MulOrders[InstrZ++]="MULU"; MulOrders[InstrZ++]="PRIOR"; END static void DeinitFields(void) BEGIN free(FixedOrders); free(Conditions); free(ALU2Orders); free(ShiftOrders); free(Bit2Orders); free(LoopOrders); free(DivOrders); free(BJmpOrders); free(MulOrders); END /*-------------------------------------------------------------------------*/ #define ModNone (-1) #define ModReg 0 #define MModReg (1 << ModReg) #define ModImm 1 #define MModImm (1 << ModImm) #define ModIReg 2 #define MModIReg (1 << ModIReg) #define ModPreDec 3 #define MModPreDec (1 << ModPreDec) #define ModPostInc 4 #define MModPostInc (1 << ModPostInc) #define ModIndex 5 #define MModIndex (1 << ModIndex) #define ModAbs 6 #define MModAbs (1 << ModAbs) #define ModMReg 7 #define MModMReg (1 << ModMReg) #define ModLAbs 8 #define MModLAbs (1 << ModLAbs) static Byte AdrMode; static Byte AdrVals[2]; static ShortInt AdrType; static Boolean IsReg(char *Asc, Byte *Erg, Boolean WordWise) BEGIN Boolean err; char *s; if (FindRegDef(Asc,&s)) Asc=s; if ((strlen(Asc)<2) OR (toupper(*Asc)!='R')) return False; else if ((strlen(Asc)>2) AND (toupper(Asc[1])=='L') AND (NOT WordWise)) BEGIN *Erg=ConstLongInt(Asc+2,&err); *Erg<<=1; return ((err) AND (*Erg<=15)); END else if ((strlen(Asc)>2) AND (toupper(Asc[1])=='H') AND (NOT WordWise)) BEGIN *Erg=ConstLongInt(Asc+2,&err); *Erg<<=1; (*Erg)++; return ((err) AND (*Erg<=15)); END else BEGIN *Erg=ConstLongInt(Asc+1,&err); return ((err) AND (*Erg<=15)); END END static Boolean IsRegM1(char *Asc, Byte *Erg, Boolean WordWise) BEGIN char tmp; int l; Boolean b; if (*Asc!='\0') BEGIN tmp=Asc[l=(strlen(Asc)-1)]; Asc[l]='\0'; b=IsReg(Asc,Erg,WordWise); Asc[l]=tmp; return b; END else return False; END static LongInt SFRStart(void) BEGIN return (ExtSFRs) ? 0xf000 : 0xfe00; END static LongInt SFREnd(void) BEGIN return (ExtSFRs) ? 0xf1de : 0xffde; END static Boolean CalcPage(LongInt *Adr, Boolean DoAnyway) BEGIN int z; Word Bank; switch (MemMode) BEGIN case MemModeStd: z=0; while ((z<=3) AND (((*Adr) >> 14)!=DPPAssumes[z])) z++; if (z>3) BEGIN WrError(110); (*Adr)&=0xffff; return (DoAnyway); END else BEGIN *Adr=((*Adr) & 0x3fff)+(z << 14); if (DPPChanged[z]) WrXError(200,RegNames[z]); return True; END case MemModeZeroPage: (*Adr)&=0x3fff; return True; case MemModeFixedPage: Bank=(*Adr) >> 14; (*Adr)&=0x3fff; if (Bank!=MemPage) BEGIN WrError(110); return (DoAnyway); END else return True; case MemModeNoCheck: (*Adr)&=0xffff; return True; case MemModeFixedBank: Bank=(*Adr) >> 16; (*Adr)&=0xffff; if (Bank!=MemPage) BEGIN WrError(110); return (DoAnyway); END else return True; default: return False; END END static void DecideAbsolute(Boolean InCode, LongInt DispAcc, Word Mask, Boolean Dest) BEGIN #define DPPAdr 0xfe00 #define SPAdr 0xfe12 #define CPAdr 0xfe10 int z; if (InCode) if (((EProgCounter() >> 16)==(DispAcc >> 16)) AND ((Mask & MModAbs)!=0)) BEGIN AdrType=ModAbs; AdrCnt=2; AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc); END else BEGIN AdrType=ModLAbs; AdrCnt=2; AdrMode=DispAcc >> 16; AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc); END else if (((Mask & MModMReg)!=0) AND (DispAcc>=SFRStart()) AND (DispAcc<=SFREnd()) AND ((DispAcc&1)==0)) BEGIN AdrType=ModMReg; AdrCnt=1; AdrVals[0]=(DispAcc-SFRStart()) >> 1; END else switch (MemMode) BEGIN case MemModeStd: z=0; while ((z<=3) AND ((DispAcc >> 14)!=DPPAssumes[z])) z++; if (z>3) BEGIN WrError(110); z=(DispAcc >> 14) & 3; END AdrType=ModAbs; AdrCnt=2; AdrVals[0]=Lo(DispAcc); AdrVals[1]=(Hi(DispAcc) & 0x3f)+(z << 6); if (DPPChanged[z]) WrXError(200,RegNames[z]); break; case MemModeZeroPage: AdrType=ModAbs; AdrCnt=2; AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc) & 0x3f; break; case MemModeFixedPage: if ((DispAcc >> 14)!=MemPage) WrError(110); AdrType=ModAbs; AdrCnt=2; AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc) & 0x3f; break; case MemModeNoCheck: AdrType=ModAbs; AdrCnt=2; AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc); break; case MemModeFixedBank: if ((DispAcc >> 16)!=MemPage) WrError(110); AdrType=ModAbs; AdrCnt=2; AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc); break; END if ((AdrType!=ModNone) AND (Dest)) switch ((Word)DispAcc) BEGIN case SPAdr : N_SPChanged=True; break; case CPAdr : N_CPChanged=True; break; case DPPAdr : case DPPAdr+1 : N_DPPChanged[0]=True; break; case DPPAdr+2 : case DPPAdr+3 : N_DPPChanged[1]=True; break; case DPPAdr+4 : case DPPAdr+5 : N_DPPChanged[2]=True; break; case DPPAdr+6 : case DPPAdr+7 : N_DPPChanged[3]=True; break; END END static void DecodeAdr(char *Asc, Word Mask, Boolean InCode, Boolean Dest) BEGIN LongInt HDisp,DispAcc; char *PPos,*MPos; String Part; Boolean OK,NegFlag,NNegFlag; Byte HReg; AdrType=ModNone; AdrCnt=0; /* immediate ? */ if (*Asc=='#') BEGIN switch (OpSize) BEGIN case 0: AdrVals[0]=EvalIntExpression(Asc+1,Int8,&OK); AdrVals[1]=0; break; case 1: HDisp=EvalIntExpression(Asc+1,Int16,&OK); AdrVals[0]=Lo(HDisp); AdrVals[1]=Hi(HDisp); break; END if (OK) BEGIN AdrType=ModImm; AdrCnt=OpSize+1; END END /* Register ? */ else if (IsReg(Asc,&AdrMode,OpSize==1)) BEGIN if ((Mask & MModReg)!=0) AdrType=ModReg; else BEGIN AdrType=ModMReg; AdrVals[0]=0xf0+AdrMode; AdrCnt=1; END if (CPChanged) WrXError(200,RegNames[4]); END /* indirekt ? */ else if ((*Asc=='[') AND (Asc[strlen(Asc)-1]==']')) BEGIN strcpy(Asc,Asc+1); Asc[strlen(Asc)-1]='\0'; /* Predekrement ? */ if ((strlen(Asc)>2) AND (*Asc=='-') AND (IsReg(Asc+1,&AdrMode,True))) AdrType=ModPreDec; /* Postinkrement ? */ else if ((strlen(Asc)>2) AND (Asc[strlen(Asc)-1]=='+') AND (IsRegM1(Asc,&AdrMode,True))) AdrType=ModPostInc; /* indiziert ? */ else BEGIN NegFlag=False; DispAcc=0; AdrMode=0xff; while (*Asc!='\0') BEGIN MPos=QuotPos(Asc,'-'); PPos=QuotPos(Asc,'+'); if (((MPos0xffff) WrError(1320); else if (DispAcc<-0x8000l) WrError(1315); else BEGIN AdrVals[0]=Lo(DispAcc); AdrVals[1]=Hi(DispAcc); AdrType=ModIndex; AdrCnt=2; END END END else BEGIN DispAcc=EvalIntExpression(Asc,MemInt,&OK); if (OK) DecideAbsolute(InCode,DispAcc,Mask,Dest); END if ((AdrType!=ModNone) AND (((1 << AdrType) & Mask)==0)) BEGIN WrError(1350); AdrType=ModNone; AdrCnt=0; END END static int DecodeCondition(char *Name) BEGIN int z; NLS_UpString(Name); for (z=0; z> 12)!=Ord(ExtSFRs))) BEGIN WrError(1335); return False; END *Adr=LAdr >> 4; *Bit=LAdr & 15; if (NOT MayBeOut) *Adr=Lo(*Adr); return True; END else return False; END else if (p==Asc) BEGIN WrError(1350); return False; END else BEGIN *p='\0'; if (IsReg(Asc,&Reg,True)) *Adr=0xf0+Reg; else BEGIN FirstPassUnknown=False; LAdr=EvalIntExpression(Asc,UInt16,&OK); if (NOT OK) return False; if (FirstPassUnknown) LAdr=0xfd00; if ((LAdr&1)==1) BEGIN WrError(1325); return False; END if ((LAdr>=0xfd00) AND (LAdr<=0xfdfe)) *Adr=(LAdr-0xfd00)/2; else if ((LAdr>=0xff00) AND (LAdr<=0xffde)) BEGIN if ((ExtSFRs) AND (NOT MayBeOut)) BEGIN WrError(1335); return False; END *Adr=0x80+((LAdr-0xff00)/2); END else if ((LAdr>=0xf100) AND (LAdr<=0xf1de)) BEGIN if ((NOT ExtSFRs) AND (NOT MayBeOut)) BEGIN WrError(1335); return False; END *Adr=0x80+((LAdr-0xf100)/2); if (MayBeOut) (*Adr)+=0x100; END else BEGIN WrError(1320); return False; END END *Bit=EvalIntExpression(p+1,UInt4,&OK); return OK; END END static Word WordVal(void) BEGIN return AdrVals[0]+(((Word)AdrVals[1]) << 8); END static Boolean DecodePref(char *Asc, Byte *Erg) BEGIN Boolean OK; if (*Asc!='#') BEGIN WrError(1350); return False; END strcpy(Asc,Asc+1); FirstPassUnknown=False; *Erg=EvalIntExpression(Asc,UInt3,&OK); if (FirstPassUnknown) *Erg=1; if (NOT OK) return False; if (*Erg<1) WrError(1315); else if (*Erg>4) WrError(1320); else BEGIN (*Erg)--; return True; END return False; END /*-------------------------------------------------------------------------*/ #define ASSUME166Count 4 static ASSUMERec ASSUME166s[ASSUME166Count]= {{"DPP0", DPPAssumes+0, 0, 15, -1}, {"DPP1", DPPAssumes+1, 0, 15, -1}, {"DPP2", DPPAssumes+2, 0, 15, -1}, {"DPP3", DPPAssumes+3, 0, 15, -1}}; static Boolean DecodePseudo(void) BEGIN Word Adr; Byte Bit; if (Memo("ASSUME")) BEGIN CodeASSUME(ASSUME166s,ASSUME166Count); return True; END if (Memo("BIT")) BEGIN if (ArgCnt!=1) WrError(1110); else if (DecodeBitAddr(ArgStr[1],&Adr,&Bit,True)) BEGIN PushLocHandle(-1); EnterIntSymbol(LabPart,(Adr << 4)+Bit,SegNone,False); PopLocHandle(); sprintf(ListLine,"=%02xH.%1x",Adr,Bit); END return True; END if (Memo("REG")) BEGIN if (ArgCnt!=1) WrError(1110); else AddRegDef(LabPart,ArgStr[1]); return True; END return False; END static Boolean BMemo(char *Name) BEGIN int l; if (strncmp(OpPart,Name,l=strlen(Name))!=0) return False; switch (OpPart[l]) BEGIN case '\0': OpSize=1; return True; case 'B': if (OpPart[l+1]=='\0') BEGIN OpSize=0; return True; END else return False; default: return False; END END static void MakeCode_166(void) BEGIN int z,Cond; Word AdrWord; Byte AdrBank,HReg; Byte BOfs1,BOfs2; Word BAdr1,BAdr2; LongInt AdrLong; Boolean OK; CodeLen=0; DontPrint=False; OpSize=1; /* zu ignorierendes */ if (Memo("")) return; /* Pseudoanweisungen */ if (DecodePseudo()) return; if (DecodeIntelPseudo(False)) return; /* Pipeline-Flags weiterschalten */ SPChanged=N_SPChanged; N_SPChanged=False; CPChanged=N_CPChanged; N_CPChanged=False; for (z=0; z=0) if (--ExtCounter<0) BEGIN MemMode=MemModeStd; ExtSFRs=False; END /* ohne Argument */ for (z=0; z> 7); /* ANSI :-0 */ BAsmCode[1]=AdrMode; break; case ModAbs: CodeLen=2+AdrCnt; BAsmCode[0]=0xf2+Cond; memcpy(BAsmCode+2,AdrVals,AdrCnt); break; END break; case ModIReg: HReg=AdrMode; DecodeAdr(ArgStr[2],MModReg+MModIReg+MModPostInc+MModAbs,False,False); switch (AdrType) BEGIN case ModReg: CodeLen=2; BAsmCode[0]=0xb8+Cond; BAsmCode[1]=HReg+(AdrMode << 4); break; case ModIReg: CodeLen=2; BAsmCode[0]=0xc8+Cond; BAsmCode[1]=(HReg << 4)+AdrMode; break; case ModPostInc: CodeLen=2; BAsmCode[0]=0xe8+Cond; BAsmCode[1]=(HReg << 4)+AdrMode; break; case ModAbs: CodeLen=2+AdrCnt; BAsmCode[0]=0x84+(Cond << 5); BAsmCode[1]=HReg; memcpy(BAsmCode+2,AdrVals,AdrCnt); break; END break; case ModPreDec: HReg=AdrMode; DecodeAdr(ArgStr[2],MModReg,False,False); switch (AdrType) BEGIN case ModReg: CodeLen=2; BAsmCode[0]=0x88+Cond; BAsmCode[1]=HReg+(AdrMode << 4); break; END break; case ModPostInc: HReg=AdrMode; DecodeAdr(ArgStr[2],MModIReg,False,False); switch (AdrType) BEGIN case ModIReg: CodeLen=2; BAsmCode[0]=0xd8+Cond; BAsmCode[1]=(HReg << 4)+AdrMode; break; END break; case ModIndex: BAsmCode[1]=AdrMode; memcpy(BAsmCode+2,AdrVals,AdrCnt); DecodeAdr(ArgStr[2],MModReg,False,False); switch (AdrType) BEGIN case ModReg: BAsmCode[0]=0xc4+(Cond << 5); CodeLen=4; BAsmCode[1]+=AdrMode << 4; break; END break; case ModAbs: memcpy(BAsmCode+2,AdrVals,AdrCnt); DecodeAdr(ArgStr[2],MModIReg+MModMReg,False,False); switch (AdrType) BEGIN case ModIReg: CodeLen=4; BAsmCode[0]=0x94+(Cond << 5); BAsmCode[1]=AdrMode; break; case ModMReg: CodeLen=4; BAsmCode[0]=0xf6+Cond; BAsmCode[1]=AdrVals[0]; break; END break; END END return; END if ((Memo("MOVBS")) OR (Memo("MOVBZ"))) BEGIN Cond=Ord(Memo("MOVBS")) << 4; if (ArgCnt!=2) WrError(1110); else BEGIN OpSize=1; DecodeAdr(ArgStr[1],MModReg+MModMReg+MModAbs,False,True); OpSize=0; switch (AdrType) BEGIN case ModReg: HReg=AdrMode; DecodeAdr(ArgStr[2],MModReg+MModAbs,False,False); switch (AdrType) BEGIN case ModReg: CodeLen=2; BAsmCode[0]=0xc0+Cond; BAsmCode[1]=HReg+(AdrMode << 4); break; case ModAbs: CodeLen=4; BAsmCode[0]=0xc2+Cond; BAsmCode[1]=0xf0+HReg; memcpy(BAsmCode+2,AdrVals,2); break; END break; case ModMReg: BAsmCode[1]=AdrVals[0]; DecodeAdr(ArgStr[2],MModAbs+MModMReg,False,False); switch (AdrType) BEGIN case ModMReg: /* BAsmCode[1] sicher absolut darstellbar, da Rn vorher */ /* abgefangen wird! */ BAsmCode[0]=0xc5+Cond; AdrLong=0xfe00+(((Word)BAsmCode[1]) << 1); CalcPage(&AdrLong,True); BAsmCode[2]=Lo(AdrLong); BAsmCode[3]=Hi(AdrLong); BAsmCode[1]=AdrVals[0]; CodeLen=4; break; case ModAbs: CodeLen=2+AdrCnt; BAsmCode[0]=0xc2+Cond; memcpy(BAsmCode+2,AdrVals,AdrCnt); break; END break; case ModAbs: memcpy(BAsmCode+2,AdrVals,AdrCnt); DecodeAdr(ArgStr[2],MModMReg,False,False); switch (AdrType) BEGIN case ModMReg: CodeLen=4; BAsmCode[0]=0xc5+Cond; BAsmCode[1]=AdrVals[0]; break; END break; END END return; END if ((Memo("PUSH")) OR (Memo("POP"))) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN DecodeAdr(ArgStr[1],MModMReg,False,Memo("POP")); switch (AdrType) BEGIN case ModMReg: CodeLen=2; BAsmCode[0]=0xec+(Ord(Memo("POP")) << 4); BAsmCode[1]=AdrVals[0]; if (SPChanged) WrXError(200,RegNames[5]); break; END END return; END if (Memo("SCXT")) BEGIN if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[1],MModMReg,False,True); switch (AdrType) BEGIN case ModMReg: BAsmCode[1]=AdrVals[0]; DecodeAdr(ArgStr[2],MModAbs+MModImm,False,False); if (AdrType!=ModNone) BEGIN CodeLen=4; BAsmCode[0]=0xc6+(Ord(AdrType==ModAbs) << 4); memcpy(BAsmCode+2,AdrVals,2); END break; END END return; END /* Arithmetik */ for (z=0; z3) WrError(1350); else BEGIN CodeLen=2; BAsmCode[0]=0x08+Cond; BAsmCode[1]=(HReg << 4)+8+AdrMode; END break; case ModPostInc: if (AdrMode>3) WrError(1350); else BEGIN CodeLen=2; BAsmCode[0]=0x08+Cond; BAsmCode[1]=(HReg << 4)+12+AdrMode; END break; case ModAbs: CodeLen=4; BAsmCode[0]=0x02+Cond; BAsmCode[1]=0xf0+HReg; memcpy(BAsmCode+2,AdrVals,AdrCnt); break; case ModImm: if (WordVal()<=7) BEGIN CodeLen=2; BAsmCode[0]=0x08+Cond; BAsmCode[1]=(HReg << 4)+AdrVals[0]; END else BEGIN CodeLen=4; BAsmCode[0]=0x06+Cond; BAsmCode[1]=0xf0+HReg; memcpy(BAsmCode+2,AdrVals,2); END break; END break; case ModMReg: BAsmCode[1]=AdrVals[0]; DecodeAdr(ArgStr[2],MModAbs+MModMReg+MModImm,False,False); switch (AdrType) BEGIN case ModAbs: CodeLen=4; BAsmCode[0]=0x02+Cond; memcpy(BAsmCode+2,AdrVals,AdrCnt); break; case ModMReg: /* BAsmCode[1] sicher absolut darstellbar, da Rn vorher */ /* abgefangen wird! */ BAsmCode[0]=0x04+Cond; AdrLong=0xfe00+(((Word)BAsmCode[1]) << 1); CalcPage(&AdrLong,True); BAsmCode[2]=Lo(AdrLong); BAsmCode[3]=Hi(AdrLong); BAsmCode[1]=AdrVals[0]; CodeLen=4; break; case ModImm: CodeLen=4; BAsmCode[0]=0x06+Cond; memcpy(BAsmCode+2,AdrVals,2); break; END break; case ModAbs: memcpy(BAsmCode+2,AdrVals,AdrCnt); DecodeAdr(ArgStr[2],MModMReg,False,False); switch (AdrType) BEGIN case ModMReg: CodeLen=4; BAsmCode[0]=0x04+Cond; BAsmCode[1]=AdrVals[0]; break; END break; END END return; END if ((BMemo("CPL")) OR (BMemo("NEG"))) BEGIN Cond=0x81+((1-OpSize) << 5); if (ArgCnt!=1) WrError(1110); else BEGIN DecodeAdr(ArgStr[1],MModReg,False,True); if (AdrType==ModReg) BEGIN CodeLen=2; BAsmCode[0]=Cond+(Ord(BMemo("CPL")) << 4); BAsmCode[1]=AdrMode << 4; END END return; END for (z=0; z15) WrError(1320); else BEGIN BAsmCode[0]=ShiftOrders[z].Code+0x10; BAsmCode[1]=(WordVal() << 4)+HReg; CodeLen=2; END break; END break; END END return; END for (z=0; z=ConditionCount) WrXError(1360,ArgStr[1]); else BEGIN DecodeAdr(ArgStr[ArgCnt],MModAbs+MModLAbs+MModIReg,True,False); switch (AdrType) BEGIN case ModLAbs: if (Cond!=TrueCond) WrXError(1360,ArgStr[1]); else BEGIN CodeLen=2+AdrCnt; BAsmCode[0]=0xfa; BAsmCode[1]=AdrMode; memcpy(BAsmCode+2,AdrVals,AdrCnt); END break; case ModAbs: AdrLong=WordVal()-(EProgCounter()+2); if ((AdrLong<=254) AND (AdrLong>=-256) AND ((AdrLong&1)==0)) BEGIN CodeLen=2; BAsmCode[0]=0x0d+(Conditions[Cond].Code << 4); BAsmCode[1]=(AdrLong/2)&0xff; END else BEGIN CodeLen=2+AdrCnt; BAsmCode[0]=0xea; BAsmCode[1]=Conditions[Cond].Code << 4; memcpy(BAsmCode+2,AdrVals,AdrCnt); END break; case ModIReg: CodeLen=2; BAsmCode[0]=0x9c; BAsmCode[1]=(Conditions[Cond].Code << 4)+AdrMode; break; END END END return; END if (Memo("CALL")) BEGIN if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110); else BEGIN Cond=(ArgCnt==1) ? TrueCond : DecodeCondition(ArgStr[1]); if (Cond>=ConditionCount) WrXError(1360,ArgStr[1]); else BEGIN DecodeAdr(ArgStr[ArgCnt],MModAbs+MModLAbs+MModIReg,True,False); switch (AdrType) BEGIN case ModLAbs: if (Cond!=TrueCond) WrXError(1360,ArgStr[1]); else BEGIN CodeLen=2+AdrCnt; BAsmCode[0]=0xda; BAsmCode[1]=AdrMode; memcpy(BAsmCode+2,AdrVals,AdrCnt); END break; case ModAbs: AdrLong=WordVal()-(EProgCounter()+2); if ((AdrLong<=254) AND (AdrLong>=-256) AND ((AdrLong&1)==0) AND (Cond==TrueCond)) BEGIN CodeLen=2; BAsmCode[0]=0xbb; BAsmCode[1]=(AdrLong/2) & 0xff; END else BEGIN CodeLen=2+AdrCnt; BAsmCode[0]=0xca; BAsmCode[1]=0x00+(Conditions[Cond].Code << 4); memcpy(BAsmCode+2,AdrVals,AdrCnt); END break; case ModIReg: CodeLen=2; BAsmCode[0]=0xab; BAsmCode[1]=(Conditions[Cond].Code << 4)+AdrMode; break; END END END return; END if (Memo("JMPR")) BEGIN if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110); else BEGIN Cond=(ArgCnt==1) ? TrueCond : DecodeCondition(ArgStr[1]); if (Cond>=ConditionCount) WrXError(1360,ArgStr[1]); else BEGIN AdrLong=EvalIntExpression(ArgStr[ArgCnt],MemInt,&OK)-(EProgCounter()+2); if (OK) if ((AdrLong&1)==1) WrError(1375); else if ((NOT SymbolQuestionable) AND ((AdrLong>254) OR (AdrLong<-256))) WrError(1370); else BEGIN CodeLen=2; BAsmCode[0]=0x0d+(Conditions[Cond].Code << 4); BAsmCode[1]=(AdrLong/2) & 0xff; END END END return; END if (Memo("CALLR")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN AdrLong=EvalIntExpression(ArgStr[ArgCnt],MemInt,&OK)-(EProgCounter()+2); if (OK) if ((AdrLong&1)==1) WrError(1375); else if ((NOT SymbolQuestionable) AND ((AdrLong>254) OR (AdrLong<-256))) WrError(1370); else BEGIN CodeLen=2; BAsmCode[0]=0xbb; BAsmCode[1]=(AdrLong/2) & 0xff; END END return; END if ((Memo("JMPA")) OR (Memo("CALLA"))) BEGIN if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110); else BEGIN Cond=(ArgCnt==1) ? TrueCond : DecodeCondition(ArgStr[1]); if (Cond>=ConditionCount) WrXError(1360,ArgStr[1]); else BEGIN AdrLong=EvalIntExpression(ArgStr[ArgCnt],MemInt,&OK); if (OK) if ((AdrLong >> 16)!=(EProgCounter() >> 16)) WrError(1910); else BEGIN CodeLen=4; BAsmCode[0]=(Memo("JMPA")) ? 0xea : 0xca; BAsmCode[1]=0x00+(Conditions[Cond].Code << 4); BAsmCode[2]=Lo(AdrLong); BAsmCode[3]=Hi(AdrLong); END END END return; END if ((Memo("JMPS")) OR (Memo("CALLS"))) BEGIN if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110); else BEGIN if (ArgCnt==1) BEGIN AdrLong=EvalIntExpression(ArgStr[1],MemInt,&OK); AdrWord=AdrLong & 0xffff; AdrBank=AdrLong >> 16; END else BEGIN AdrWord=EvalIntExpression(ArgStr[2],UInt16,&OK); if (OK) AdrBank=EvalIntExpression(ArgStr[1],MemInt2,&OK); else AdrBank=0; END if (OK) BEGIN CodeLen=4; BAsmCode[0]=(Memo("JMPS")) ? 0xfa : 0xda; BAsmCode[1]=AdrBank; BAsmCode[2]=Lo(AdrWord); BAsmCode[3]=Hi(AdrWord); END END return; END if ((Memo("JMPI")) OR (Memo("CALLI"))) BEGIN if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110); else BEGIN Cond=(ArgCnt==1) ? TrueCond : DecodeCondition(ArgStr[1]); if (Cond>=ConditionCount) WrXError(1360,ArgStr[1]); else BEGIN DecodeAdr(ArgStr[ArgCnt],MModIReg,True,False); switch (AdrType) BEGIN case ModIReg: CodeLen=2; BAsmCode[0]=(Memo("JMPI")) ? 0x9c : 0xab; BAsmCode[1]=AdrMode+(Conditions[Cond].Code << 4); break; END END END return; END for (z=0; z254))) WrError(1370); else BEGIN CodeLen=4; BAsmCode[0]=0x8a+(z << 4); BAsmCode[1]=BAdr1; BAsmCode[2]=(AdrLong/2) & 0xff; BAsmCode[3]=BOfs1 << 4; END END return; END if (Memo("PCALL")) BEGIN if (ArgCnt!=2) WrError(1110); else BEGIN DecodeAdr(ArgStr[1],MModMReg,False,False); switch (AdrType) BEGIN case ModMReg: BAsmCode[1]=AdrVals[0]; DecodeAdr(ArgStr[2],MModAbs,True,False); switch (AdrType) BEGIN case ModAbs: CodeLen=4; BAsmCode[0]=0xe2; memcpy(BAsmCode+2,AdrVals,2); break; END break; END END return; END if (Memo("RETP")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN DecodeAdr(ArgStr[1],MModMReg,False,False); switch (AdrType) BEGIN case ModMReg: BAsmCode[1]=AdrVals[0]; BAsmCode[0]=0xeb; CodeLen=2; if (SPChanged) WrXError(200,RegNames[5]); break; END END return; END if (Memo("TRAP")) BEGIN if (ArgCnt!=1) WrError(1110); else if (*ArgStr[1]!='#') WrError(1350); else BEGIN BAsmCode[1]=EvalIntExpression(ArgStr[1]+1,UInt7,&OK) << 1; if (OK) BEGIN BAsmCode[0]=0x9b; CodeLen=2; END END return; END /* spezielle Steuerbefehle */ if (Memo("ATOMIC")) BEGIN if (ArgCnt!=1) WrError(1110); else if (MomCPU> 8) & 3; ExtCounter=HReg+1; MemMode=MemModeFixedPage; MemPage=WordVal() & 0x3ff; break; END END return; END if ((Memo("EXTS")) OR (Memo("EXTSR"))) BEGIN OpSize=0; if (ArgCnt!=2) WrError(1110); else if (MomCPU