/* codem16.c */ /*****************************************************************************/ /* AS-Portierung */ /* */ /* Codegenerator Mitsubishi M16 */ /* */ /* Historie: 27.12.1996 Grundsteinlegung */ /* 3. 1.1999 ChkPC-Anpassung */ /* */ /*****************************************************************************/ #include "stdinc.h" #include #include #include "bpemu.h" #include "nls.h" #include "strutil.h" #include "asmdef.h" #include "asmsub.h" #include "asmpars.h" #include "codepseudo.h" #include "codevars.h" #define ModNone (-1) #define ModReg 0 #define MModReg (1 << ModReg) #define ModIReg 1 #define MModIReg (1 << ModIReg) #define ModDisp16 2 #define MModDisp16 (1 << ModDisp16) #define ModDisp32 3 #define MModDisp32 (1 << ModDisp32) #define ModImm 4 #define MModImm (1 << ModImm) #define ModAbs16 5 #define MModAbs16 (1 << ModAbs16) #define ModAbs32 6 #define MModAbs32 (1 << ModAbs32) #define ModPCRel16 7 #define MModPCRel16 (1 << ModPCRel16) #define ModPCRel32 8 #define MModPCRel32 (1 << ModPCRel32) #define ModPop 9 #define MModPop (1 << ModPop) #define ModPush 10 #define MModPush (1 << ModPush) #define ModRegChain 11 #define MModRegChain (1 << ModRegChain) #define ModPCChain 12 #define MModPCChain (1 << ModPCChain) #define ModAbsChain 13 #define MModAbsChain (1 << ModAbsChain) #define Mask_RegOnly (MModReg) #define Mask_AllShort (MModReg+MModIReg+MModDisp16+MModImm+MModAbs16+MModAbs32+MModPCRel16+MModPCRel32+MModPop+MModPush+MModPCChain+MModAbsChain) #define Mask_AllGen (Mask_AllShort+MModDisp32+MModRegChain) #define Mask_NoImmShort (Mask_AllShort-MModImm) #define Mask_NoImmGen (Mask_AllGen-MModImm) #define Mask_MemShort (Mask_NoImmShort-MModReg) #define Mask_MemGen (Mask_NoImmGen-MModReg) #define Mask_Source (Mask_AllGen-MModPush) #define Mask_Dest (Mask_NoImmGen-MModPop) #define Mask_PureDest (Mask_NoImmGen-MModPush-MModPop) #define Mask_PureMem (Mask_MemGen-MModPush-MModPop) #define FixedOrderCount 7 #define OneOrderCount 13 #define GE2OrderCount 11 #define BitOrderCount 6 #define GetPutOrderCount 8 #define BFieldOrderCount 4 #define MulOrderCount 4 #define ConditionCount 14 #define LogOrderCount 3 typedef struct { char *Name; Word Code; } FixedOrder; typedef struct { char *Name; Word Mask; Byte OpMask; Word Code; } OneOrder; typedef struct { char *Name; Word Mask1,Mask2; Word SMask1,SMask2; Word Code; Boolean Signed; } GE2Order; typedef struct { char *Name; Boolean MustByte; Word Code1,Code2; } BitOrder; typedef struct { char *Name; ShortInt Size; Word Code; Boolean Turn; } GetPutOrder; static CPUVar CPUM16; static String Format; static Byte FormatCode; static ShortInt DOpSize,OpSize[5]; static Word AdrMode[5]; static ShortInt AdrType[5]; static Byte AdrCnt1[5],AdrCnt2[5]; static Word AdrVals[5][8]; static Byte OptionCnt; static char Options[2][5]; static FixedOrder *FixedOrders; static OneOrder *OneOrders; static GE2Order *GE2Orders; static BitOrder *BitOrders; static GetPutOrder *GetPutOrders; static char **BFieldOrders; static char **MulOrders; static char **Conditions; static char **LogOrders; /*------------------------------------------------------------------------*/ static void AddFixed(char *NName, Word NCode) BEGIN if (InstrZ>=FixedOrderCount) exit(255); FixedOrders[InstrZ].Name=NName; FixedOrders[InstrZ++].Code=NCode; END static void AddOne(char *NName, Byte NOpMask, Word NMask, Word NCode) BEGIN if (InstrZ>=OneOrderCount) exit(255); OneOrders[InstrZ].Name=NName; OneOrders[InstrZ].Code=NCode; OneOrders[InstrZ].Mask=NMask; OneOrders[InstrZ++].OpMask=NOpMask; END static void AddGE2(char *NName, Word NMask1, Word NMask2, Byte NSMask1, Byte NSMask2, Word NCode, Boolean NSigned) BEGIN if (InstrZ>=GE2OrderCount) exit(255); GE2Orders[InstrZ].Name=NName; GE2Orders[InstrZ].Mask1=NMask1; GE2Orders[InstrZ].Mask2=NMask2; GE2Orders[InstrZ].SMask1=NSMask1; GE2Orders[InstrZ].SMask2=NSMask2; GE2Orders[InstrZ].Code=NCode; GE2Orders[InstrZ++].Signed=NSigned; END static void AddBit(char *NName, Boolean NMust, Word NCode1, Word NCode2) BEGIN if (InstrZ>=BitOrderCount) exit(255); BitOrders[InstrZ].Name=NName; BitOrders[InstrZ].Code1=NCode1; BitOrders[InstrZ].Code2=NCode2; BitOrders[InstrZ++].MustByte=NMust; END static void AddGetPut(char *NName, Byte NSize, Word NCode, Boolean NTurn) BEGIN if (InstrZ>=GetPutOrderCount) exit(255); GetPutOrders[InstrZ].Name=NName; GetPutOrders[InstrZ].Code=NCode; GetPutOrders[InstrZ].Turn=NTurn; GetPutOrders[InstrZ++].Size=NSize; END static void InitFields(void) BEGIN FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCount); InstrZ=0; AddFixed("NOP" ,0x1bd6); AddFixed("PIB" ,0x0bd6); AddFixed("RIE" ,0x08f7); AddFixed("RRNG" ,0x3bd6); AddFixed("RTS" ,0x2bd6); AddFixed("STCTX",0x07d6); AddFixed("REIT" ,0x2fd6); OneOrders=(OneOrder *) malloc(sizeof(OneOrder)*OneOrderCount); InstrZ=0; AddOne("ACS" ,0x00,Mask_PureMem, 0x8300); AddOne("NEG" ,0x07,Mask_PureDest, 0xc800); AddOne("NOT" ,0x07,Mask_PureDest, 0xcc00); AddOne("JMP" ,0x00,Mask_PureMem, 0x8200); AddOne("JSR" ,0x00,Mask_PureMem, 0xaa00); AddOne("LDCTX" ,0x00,MModIReg+MModDisp16+MModDisp32+ MModAbs16+MModAbs32+MModPCRel16+MModPCRel32, 0x8600); AddOne("LDPSB" ,0x02,Mask_Source, 0xdb00); AddOne("LDPSM" ,0x02,Mask_Source, 0xdc00); AddOne("POP" ,0x04,Mask_PureDest, 0x9000); AddOne("PUSH" ,0x04,Mask_Source-MModPop, 0xb000); AddOne("PUSHA" ,0x00,Mask_PureMem, 0xa200); AddOne("STPSB" ,0x02,Mask_Dest, 0xdd00); AddOne("STPSM" ,0x02,Mask_Dest, 0xde00); GE2Orders=(GE2Order *) malloc(sizeof(GE2Order)*GE2OrderCount); InstrZ=0; AddGE2("ADDU" ,Mask_Source,Mask_PureDest,7,7,0x0400,False); AddGE2("ADDX" ,Mask_Source,Mask_PureDest,7,7,0x1000,True ); AddGE2("SUBU" ,Mask_Source,Mask_PureDest,7,7,0x0c00,False); AddGE2("SUBX" ,Mask_Source,Mask_PureDest,7,7,0x1800,True ); AddGE2("CMPU" ,Mask_Source,Mask_PureDest,7,7,0x8400,False); AddGE2("LDC" ,Mask_Source,Mask_PureDest,7,4,0x9800,True ); AddGE2("LDP" ,Mask_Source,Mask_PureMem ,7,7,0x9c00,True ); AddGE2("MOVU" ,Mask_Source,Mask_Dest ,7,7,0x8c00,True ); AddGE2("REM" ,Mask_Source,Mask_PureDest,7,7,0x5800,True ); AddGE2("REMU" ,Mask_Source,Mask_PureDest,7,7,0x5c00,True ); AddGE2("ROT" ,Mask_Source,Mask_PureDest,1,7,0x3800,True ); BitOrders=(BitOrder *) malloc(sizeof(BitOrder)*BitOrderCount); InstrZ=0; AddBit("BCLR" ,False,0xb400,0xa180); AddBit("BCLRI",True ,0xa400,0x0000); AddBit("BNOT" ,False,0xb800,0x0000); AddBit("BSET" ,False,0xb000,0x8180); AddBit("BSETI",True ,0xa000,0x81c0); AddBit("BTST" ,False,0xbc00,0xa1c0); GetPutOrders=(GetPutOrder *) malloc(sizeof(GetPutOrder)*GetPutOrderCount); InstrZ=0; AddGetPut("GETB0",0,0xc000,False); AddGetPut("GETB1",0,0xc400,False); AddGetPut("GETB2",0,0xc800,False); AddGetPut("GETH0",1,0xcc00,False); AddGetPut("PUTB0",0,0xd000,True ); AddGetPut("PUTB1",0,0xd400,True ); AddGetPut("PUTB2",0,0xd800,True ); AddGetPut("PUTH0",1,0xdc00,True ); BFieldOrders=(char **) malloc(sizeof(char *)*BFieldOrderCount); InstrZ=0; BFieldOrders[InstrZ++]="BFCMP"; BFieldOrders[InstrZ++]="BFCMPU"; BFieldOrders[InstrZ++]="BFINS"; BFieldOrders[InstrZ++]="BFINSU"; MulOrders=(char **) malloc(sizeof(char *)*MulOrderCount); InstrZ=0; MulOrders[InstrZ++]="MUL"; MulOrders[InstrZ++]="MULU"; MulOrders[InstrZ++]="DIV"; MulOrders[InstrZ++]="DIVU"; Conditions=(char **) malloc(sizeof(char *)*ConditionCount); InstrZ=0; Conditions[InstrZ++]="XS"; Conditions[InstrZ++]="XC"; Conditions[InstrZ++]="EQ"; Conditions[InstrZ++]="NE"; Conditions[InstrZ++]="LT"; Conditions[InstrZ++]="GE"; Conditions[InstrZ++]="LE"; Conditions[InstrZ++]="GT"; Conditions[InstrZ++]="VS"; Conditions[InstrZ++]="VC"; Conditions[InstrZ++]="MS"; Conditions[InstrZ++]="MC"; Conditions[InstrZ++]="FS"; Conditions[InstrZ++]="FC"; LogOrders=(char **) malloc(sizeof(char *)*LogOrderCount); InstrZ=0; LogOrders[InstrZ++]="AND"; LogOrders[InstrZ]="OR"; LogOrders[InstrZ++]="XOR"; END static void DeinitFields(void) BEGIN free(FixedOrders); free(OneOrders); free(GE2Orders); free(BitOrders); free(GetPutOrders); free(BFieldOrders); free(MulOrders); free(Conditions); free(LogOrders); END /*------------------------------------------------------------------------*/ typedef enum {DispSizeNone,DispSize4,DispSize4Eps,DispSize16,DispSize32} DispSize; typedef struct _TChainRec { struct _TChainRec *Next; Byte RegCnt; Word Regs[5],Scales[5]; LongInt DispAcc; Boolean HasDisp; DispSize DSize; } *PChainRec,TChainRec; static Boolean ErrFlag; static Boolean IsD4(LongInt inp) BEGIN return ((inp>=-32) AND (inp<=28)); END static Boolean IsD16(LongInt inp) BEGIN return ((inp>=-0x8000) AND (inp<=0x7fff)); END static Boolean DecodeReg(char *Asc, Word *Erg) BEGIN Boolean IO; if (strcasecmp(Asc,"SP")==0) *Erg=15; else if (strcasecmp(Asc,"FP")==0) *Erg=14; else if ((strlen(Asc)>1) AND (toupper(*Asc)=='R')) BEGIN *Erg=ConstLongInt(Asc+1,&IO); return ((IO) AND (*Erg<=15)); END else return False; return True; END static void SplitSize(char *s, DispSize *Erg) BEGIN int l=strlen(s); if ((l>2) AND (s[l-1]=='4') AND (s[l-2]==':')) BEGIN *Erg=DispSize4; s[l-2]='\0'; END else if ((l>3) AND (s[l-1]=='6') AND (s[l-2]=='1') AND (s[l-3]==':')) BEGIN *Erg=DispSize16; s[l-3]='\0'; END else if ((l>3) AND (s[l-1]=='2') AND (s[l-2]=='3') AND (s[l-3]==':')) BEGIN *Erg=DispSize32; s[l-3]='\0'; END END static void DecideAbs(LongInt Disp, DispSize Size, Word Mask, int Index) BEGIN switch (Size) BEGIN case DispSize4: Size=DispSize16; break; case DispSizeNone: if ((IsD16(Disp)) AND ((Mask & MModAbs16)!=0)) Size=DispSize16; else Size=DispSize32; break; default: break; END switch (Size) BEGIN case DispSize16: if (ChkRange(Disp,-0x8000,0x7fff)) BEGIN AdrType[Index]=ModAbs16; AdrMode[Index]=0x09; AdrVals[Index][0]=Disp & 0xffff; AdrCnt1[Index]=2; END break; case DispSize32: AdrType[Index]=ModAbs32; AdrMode[Index]=0x0a; AdrVals[Index][0]=Disp >> 16; AdrVals[Index][1]=Disp & 0xffff; AdrCnt1[Index]=4; break; default: WrError(10000); END END static void SetError(Word Code) BEGIN WrError(Code); ErrFlag=True; END static PChainRec DecodeChain(char *Asc) BEGIN PChainRec Rec; String Part,SReg; int z; char *p; Boolean OK; Byte Scale; ChkStack(); Rec=(PChainRec) malloc(sizeof(TChainRec)); Rec->Next=Nil; Rec->RegCnt=0; Rec->DispAcc=0; Rec->HasDisp=False; Rec->DSize=DispSizeNone; while ((*Asc!='\0') AND (NOT ErrFlag)) BEGIN /* eine Komponente abspalten */ p=QuotPos(Asc,','); if (p==Nil) BEGIN strmaxcpy(Part,Asc,255); *Asc='\0'; END else BEGIN *p='\0'; strmaxcpy(Part,Asc,255); strcpy(Asc,p+1); END strcpy(SReg,Part); p=QuotPos(SReg,'*'); if (p!=Nil) *p='\0'; /* weitere Indirektion ? */ if (*Part=='@') if (Rec->Next!=Nil) SetError(1350); else BEGIN strcpy(Part,Part+1); if (IsIndirect(Part)) BEGIN strcpy(Part,Part+1); Part[strlen(Part)-1]='\0'; END Rec->Next=DecodeChain(Part); END /* Register, mit Skalierungsfaktor ? */ else if (DecodeReg(SReg,Rec->Regs+Rec->RegCnt)) BEGIN if (Rec->RegCnt>=5) SetError(1350); else BEGIN FirstPassUnknown=False; if (p==Nil) BEGIN OK=True; Scale=1; END else Scale=EvalIntExpression(p+1,UInt4,&OK); if (FirstPassUnknown) Scale=1; if (NOT OK) ErrFlag=True; else if ((Scale!=1) AND (Scale!=2) AND (Scale!=4) AND (Scale!=8)) SetError(1350); else BEGIN Rec->Scales[Rec->RegCnt]=0; while (Scale>1) BEGIN Rec->Scales[Rec->RegCnt]++; Scale=Scale >> 1; END Rec->RegCnt++; END END END /* PC, mit Skalierungsfaktor ? */ else if (strcasecmp(SReg,"PC")==0) BEGIN if (Rec->RegCnt>=5) SetError(1350); else BEGIN FirstPassUnknown=False; if (p==Nil) BEGIN OK=True; Scale=1; END else Scale=EvalIntExpression(p+1,UInt4,&OK); if (FirstPassUnknown) Scale=1; if (NOT OK) ErrFlag=True; else if ((Scale!=1) AND (Scale!=2) AND (Scale!=4) AND (Scale!=8)) SetError(1350); else BEGIN for (z=Rec->RegCnt-1; z>=0; z--) BEGIN Rec->Regs[z+1]=Rec->Regs[z]; Rec->Scales[z+1]=Rec->Scales[z]; END Rec->Scales[0]=0; while (Scale>1) BEGIN Rec->Scales[0]++; Scale=Scale >> 1; END Rec->Regs[0]=16; Rec->RegCnt++; END END END /* ansonsten Displacement */ else BEGIN SplitSize(Part,&(Rec->DSize)); Rec->DispAcc+=EvalIntExpression(Part,Int32,&OK); if (NOT OK) ErrFlag=True; Rec->HasDisp=True; END END if (ErrFlag) BEGIN free(Rec); return Nil; END else return Rec; END static Boolean ChkAdr(Word Mask, int Index) BEGIN AdrCnt2[Index]=AdrCnt1[Index] >> 1; if ((AdrType[Index]!=-1) AND ((Mask & (1 << AdrType[Index]))==0)) BEGIN AdrCnt1[Index]=AdrCnt2[Index]=0; AdrType[Index]=ModNone; WrError(1350); return False; END else return (AdrType[Index]!=ModNone); END static Boolean DecodeAdr(char *Asc, int Index, Word Mask) BEGIN LongInt AdrLong,MinReserve,MaxReserve; int z,z2,LastChain; Boolean OK; PChainRec RootChain,RunChain,PrevChain; DispSize DSize; AdrCnt1[Index]=0; AdrType[Index]=ModNone; /* Register ? */ if (DecodeReg(Asc,AdrMode+Index)) BEGIN AdrType[Index]=ModReg; AdrMode[Index]+=0x10; return ChkAdr(Mask,Index); END /* immediate ? */ if (*Asc=='#') BEGIN switch (OpSize[Index]) BEGIN case -1: WrError(1132); OK=False; break; case 0: AdrVals[Index][0]=EvalIntExpression(Asc+1,Int8,&OK) & 0xff; if (OK) AdrCnt1[Index]=2; break; case 1: AdrVals[Index][0]=EvalIntExpression(Asc+1,Int16,&OK); if (OK) AdrCnt1[Index]=2; break; case 2: AdrLong=EvalIntExpression(Asc+1,Int32,&OK); if (OK) BEGIN AdrVals[Index][0]=AdrLong >> 16; AdrVals[Index][1]=AdrLong & 0xffff; AdrCnt1[Index]=4; END break; END if (OK) BEGIN AdrType[Index]=ModImm; AdrMode[Index]=0x0c; END return ChkAdr(Mask,Index); END /* indirekt ? */ if (*Asc=='@') BEGIN strcpy(Asc,Asc+1); if (IsIndirect(Asc)) BEGIN strcpy(Asc,Asc+1); Asc[strlen(Asc)-1]='\0'; END /* Stack Push ? */ if ((strcasecmp(Asc,"-R15")==0) OR (strcasecmp(Asc,"-SP")==0)) BEGIN AdrType[Index]=ModPush; AdrMode[Index]=0x05; return ChkAdr(Mask,Index); END /* Stack Pop ? */ if ((strcasecmp(Asc,"R15+")==0) OR (strcasecmp(Asc,"SP+")==0)) BEGIN AdrType[Index]=ModPop; AdrMode[Index]=0x04; return ChkAdr(Mask,Index); END /* Register einfach indirekt ? */ if (DecodeReg(Asc,AdrMode+Index)) BEGIN AdrType[Index]=ModIReg; AdrMode[Index]+=0x30; return ChkAdr(Mask,Index); END /* zusammengesetzt indirekt ? */ ErrFlag=False; RootChain=DecodeChain(Asc); if (ErrFlag); else if (RootChain==Nil); /* absolut ? */ else if ((RootChain->Next==Nil) AND (RootChain->RegCnt==0)) BEGIN if (NOT RootChain->HasDisp) RootChain->DispAcc=0; DecideAbs(RootChain->DispAcc,RootChain->DSize,Mask,Index); free(RootChain); END /* einfaches Register/PC mit Displacement ? */ else if ((RootChain->Next==Nil) AND (RootChain->RegCnt==1) AND (RootChain->Scales[0]==0)) BEGIN if (RootChain->Regs[0]==16) RootChain->DispAcc-=EProgCounter(); /* Displacement-Groesse entscheiden */ if (RootChain->DSize==DispSizeNone) if ((RootChain->DispAcc==0) AND (RootChain->Regs[0]<16)); else if (IsD16(RootChain->DispAcc)) RootChain->DSize=DispSize16; else RootChain->DSize=DispSize32; switch (RootChain->DSize) BEGIN /* kein Displacement mit Register */ case DispSizeNone: if (ChkRange(RootChain->DispAcc,0,0)) if (RootChain->Regs[0]>=16) WrError(1350); else BEGIN AdrType[Index]=ModIReg; AdrMode[Index]=0x30+RootChain->Regs[0]; END break; /* 16-Bit-Displacement */ case DispSize4: case DispSize16: if (ChkRange(RootChain->DispAcc,-0x8000,0x7fff)) BEGIN AdrVals[Index][0]=RootChain->DispAcc & 0xffff; AdrCnt1[Index]=2; if (RootChain->Regs[0]==16) BEGIN AdrType[Index]=ModPCRel16; AdrMode[Index]=0x0d; END else BEGIN AdrType[Index]=ModDisp16; AdrMode[Index]=0x20+RootChain->Regs[0]; END END break; /* 32-Bit-Displacement */ default: AdrVals[Index][1]=RootChain->DispAcc & 0xffff; AdrVals[Index][0]=RootChain->DispAcc >> 16; AdrCnt1[Index]=4; if (RootChain->Regs[0]==16) BEGIN AdrType[Index]=ModPCRel32; AdrMode[Index]=0x0e; END else BEGIN AdrType[Index]=ModDisp32; AdrMode[Index]=0x40+RootChain->Regs[0]; END END free(RootChain); END /* komplex: dann chained iterieren */ else BEGIN /* bis zum innersten Element der Indirektion als Basis laufen */ RunChain=RootChain; while (RunChain->Next!=Nil) RunChain=RunChain->Next; /* Entscheidung des Basismodus: die Basis darf nicht skaliert sein, und wenn ein Modus nicht erlaubt ist, muessen wir mit Base-none anfangen... */ z=0; while ((zRegCnt) AND (RunChain->Scales[z]!=0)) z++; if (z>=RunChain->RegCnt) BEGIN AdrType[Index]=ModAbsChain; AdrMode[Index]=0x0b; END else BEGIN if (RunChain->Regs[z]==16) BEGIN AdrType[Index]=ModPCChain; AdrMode[Index]=0x0f; RunChain->DispAcc-=EProgCounter(); END else BEGIN AdrType[Index]=ModRegChain; AdrMode[Index]=0x60+RunChain->Regs[z]; END for (z2=z; z2<=RunChain->RegCnt-2; z2++) BEGIN RunChain->Regs[z2]=RunChain->Regs[z2+1]; RunChain->Scales[z2]=RunChain->Scales[z2+1]; END RunChain->RegCnt--; END; /* Jetzt ueber die einzelnen Komponenten iterieren */ LastChain=0; while (RootChain!=Nil) BEGIN RunChain=RootChain; PrevChain=Nil; while (RunChain->Next!=Nil) BEGIN PrevChain=RunChain; RunChain=RunChain->Next; END; /* noch etwas abzulegen ? */ if ((RunChain->RegCnt!=0) OR (RunChain->HasDisp)) BEGIN LastChain=AdrCnt1[Index] >> 1; /* Register ablegen */ if (RunChain->RegCnt!=0) BEGIN if (RunChain->Regs[0]==16) AdrVals[Index][LastChain]=0x0600; else AdrVals[Index][LastChain]=RunChain->Regs[0] << 10; AdrVals[Index][LastChain]+=RunChain->Scales[0] << 5; for (z2=0; z2<=RunChain->RegCnt-2; z2++) BEGIN RunChain->Regs[z2]=RunChain->Regs[z2+1]; RunChain->Scales[z2]=RunChain->Scales[z2+1]; END RunChain->RegCnt--; END else AdrVals[Index][LastChain]=0x0200; AdrCnt1[Index]+=2; /* Displacement ablegen */ if (RunChain->HasDisp) BEGIN if ((AdrVals[Index][LastChain] & 0x3e00)==0x0600) RunChain->DispAcc-=EProgCounter(); if (RunChain->DSize==DispSizeNone) BEGIN MinReserve=32*RunChain->RegCnt; MaxReserve=28*RunChain->RegCnt; if (IsD4(RunChain->DispAcc)) if ((RunChain->DispAcc & 3)==0) DSize=DispSize4; else DSize=DispSize16; else if ((RunChain->DispAcc>=-32-MinReserve) AND (RunChain->DispAcc<=28+MaxReserve)) DSize=DispSize4Eps; else if (IsD16(RunChain->DispAcc)) DSize=DispSize16; else if ((RunChain->DispAcc>=-0x8000-MinReserve) AND (RunChain->DispAcc<=0x7fff+MaxReserve)) DSize=DispSize4Eps; else DSize=DispSize32; END else DSize=RunChain->DSize; RunChain->DSize=DispSizeNone; switch (DSize) BEGIN /* Fall 1: passt komplett in 4er-Displacement */ case DispSize4: if (ChkRange(RunChain->DispAcc,-32,28)) if ((RunChain->DispAcc & 3)!=0) WrError(1325); else BEGIN AdrVals[Index][LastChain]+=(RunChain->DispAcc >> 2) & 0x000f; RunChain->HasDisp=False; END break; /* Fall 2: passt nicht mehr in naechstkleineres Displacement, aber wir koennen hier schon einen Teil ablegen, um im naechsten Iterations- schritt ein kuerzeres Displacement zu bekommen */ case DispSize4Eps: if (RunChain->DispAcc>0) BEGIN AdrVals[Index][LastChain]+=0x0007; RunChain->DispAcc-=28; END else BEGIN AdrVals[Index][LastChain]+=0x0008; RunChain->DispAcc+=32; END break; /* Fall 3: 16 Bit */ case DispSize16: if (ChkRange(RunChain->DispAcc,-0x8000,0x7fff)) BEGIN AdrVals[Index][LastChain]+=0x0011; AdrVals[Index][LastChain+1]=RunChain->DispAcc & 0xffff; AdrCnt1[Index]+=2; RunChain->HasDisp=False; END break; /* Fall 4: 32 Bit */ case DispSize32: AdrVals[Index][LastChain]+=0x0012; AdrVals[Index][LastChain+1]=RunChain->DispAcc >> 16; AdrVals[Index][LastChain+2]=RunChain->DispAcc & 0xffff; AdrCnt1[Index]+=4; RunChain->HasDisp=False; break; default: WrError(10000); END END END /* nichts mehr drin: dann ein leeres Steuerwort erzeugen. Tritt auf, falls alles schon im Basisadressierungsbyte verschwunden */ else if (RunChain!=RootChain) BEGIN LastChain=AdrCnt1[Index] >> 1; AdrVals[Index][LastChain]=0x0200; AdrCnt1[Index]+=2; END /* nichts mehr drin: wegwerfen wenn wir noch nicht ganz vorne angekommen sind, dann ein Indirektionsflag setzen */ if ((RunChain->RegCnt==0) AND (NOT RunChain->HasDisp)) BEGIN if (RunChain!=RootChain) AdrVals[Index][LastChain]+=0x4000; if (PrevChain==Nil) RootChain=Nil; else PrevChain->Next=Nil; free(RunChain); END END /* Ende-Kennung fuer letztes Glied */ AdrVals[Index][LastChain]+=0x8000; END return ChkAdr(Mask,Index); END /* ansonsten absolut */ DSize=DispSizeNone; SplitSize(Asc,&DSize); AdrLong=EvalIntExpression(Asc,Int32,&OK); if (OK) DecideAbs(AdrLong,DSize,Mask,Index); return ChkAdr(Mask,Index); END static LongInt ImmVal(int Index) BEGIN switch (OpSize[Index]) BEGIN case 0: return (ShortInt) (AdrVals[Index][0] & 0xff); case 1: return (Integer) (AdrVals[Index][0]); case 2: return (((LongInt)AdrVals[Index][0]) << 16)+((Integer)AdrVals[Index][1]); default: WrError(10000); return 0; END END static Boolean IsShort(int Index) BEGIN return ((AdrMode[Index] & 0xc0)==0); END static void AdaptImm(int Index, Byte NSize, Boolean Signed) BEGIN switch (OpSize[Index]) BEGIN case 0: if (NSize!=0) BEGIN if (((AdrVals[Index][0] & 0x80)==0x80) AND (Signed)) AdrVals[Index][0]|=0xff00; else AdrVals[Index][0]&=0xff; if (NSize==2) BEGIN if (((AdrVals[Index][0] & 0x8000)==0x8000) AND (Signed)) AdrVals[Index][1]=0xffff; else AdrVals[Index][1]=0; AdrCnt1[Index]+=2; AdrCnt2[Index]++; END END break; case 1: if (NSize==0) AdrVals[Index][0]&=0xff; else if (NSize==2) BEGIN if (((AdrVals[Index][0] & 0x8000)==0x8000) AND (Signed)) AdrVals[Index][1]=0xffff; else AdrVals[Index][1]=0; AdrCnt1[Index]+=2; AdrCnt2[Index]++; END break; case 2: if (NSize!=2) BEGIN AdrCnt1[Index]-=2; AdrCnt2[Index]--; if (NSize==0) AdrVals[Index][0]&=0xff; END break; END OpSize[Index]=NSize; END static ShortInt DefSize(Byte Mask) BEGIN ShortInt z; z=2; while ((z>=0) AND ((Mask & 4)==0)) BEGIN Mask=(Mask << 1) & 7; z--; END return z; END static Word RMask(Word No, Boolean Turn) BEGIN return (Turn) ? (0x8000 >> No) : (1 << No); END static Boolean DecodeRegList(char *Asc, Word *Erg, Boolean Turn) BEGIN char Part[11]; char *p,*p1,*p2; Word r1,r2,z; if (IsIndirect(Asc)) BEGIN strcpy(Asc,Asc+1); Asc[strlen(Asc)-1]='\0'; END *Erg=0; while (*Asc!='\0') BEGIN p1=strchr(Asc,','); p2=strchr(Asc,'/'); if ((p1!=Nil) AND (p1=0; z--) strcpy(Options[z+1],Options[z]); OptionCnt++; strmaxcpy(Options[0],p+1,255); END *p='\0'; END END while (p!=Nil); END /*------------------------------------------------------------------------*/ static Boolean DecodePseudo(void) BEGIN return False; END static void DecideBranch(LongInt Adr, Byte Index) BEGIN LongInt Dist=Adr-EProgCounter(); if (FormatCode==0) BEGIN /* Groessenangabe erzwingt G-Format */ if (OpSize[Index]!=-1) FormatCode=1; /* gerade 9-Bit-Zahl kurz darstellbar */ else if (((Dist & 1)==0) AND (Dist<=254) AND (Dist>=-256)) FormatCode=2; /* ansonsten allgemein */ else FormatCode=1; END if ((FormatCode==1) AND (OpSize[Index]==-1)) if ((Dist<=127) AND (Dist>=-128)) OpSize[Index]=0; else if ((Dist<=32767) AND (Dist>=-32768)) OpSize[Index]=1; else OpSize[Index]=2; END static Boolean DecideBranchLength(LongInt *Addr, int Index) BEGIN *Addr-=EProgCounter(); if (OpSize[Index]==-1) BEGIN if ((*Addr>=-128) AND (*Addr<=127)) OpSize[Index]=0; else if ((*Addr>=-32768) AND (*Addr<=32767)) OpSize[Index]=1; else OpSize[Index]=2; END if ((NOT SymbolQuestionable) AND (((OpSize[Index]==0) AND ((*Addr<-128) OR (*Addr>127))) OR ((OpSize[Index]==1) AND ((*Addr<-32768) OR (*Addr>32767))))) BEGIN WrError(1370); return False; END else return True; END static void Make_G(Word Code) BEGIN WAsmCode[0]=0xd000+(OpSize[1] << 8)+AdrMode[1]; memcpy(WAsmCode+1,AdrVals[1],AdrCnt1[1]); WAsmCode[1+AdrCnt2[1]]=Code+(OpSize[2] << 8)+AdrMode[2]; memcpy(WAsmCode+2+AdrCnt2[1],AdrVals[2],AdrCnt1[2]); CodeLen=4+AdrCnt1[1]+AdrCnt1[2]; END static void Make_E(Word Code, Boolean Signed) BEGIN LongInt HVal,Min,Max; Min=128*(-Ord(Signed)); Max=Min+255; if (AdrType[1]!=ModImm) WrError(1350); else BEGIN HVal=ImmVal(1); if (ChkRange(HVal,Min,Max)) BEGIN WAsmCode[0]=0xbf00+(HVal & 0xff); WAsmCode[1]=Code+(OpSize[2] << 8)+AdrMode[2]; memcpy(WAsmCode+2,AdrVals[2],AdrCnt1[2]); CodeLen=4+AdrCnt1[2]; END END END static void Make_I(Word Code, Boolean Signed) BEGIN if ((AdrType[1]!=ModImm) OR (NOT IsShort(2))) WrError(1350); else BEGIN AdaptImm(1,OpSize[2],Signed); WAsmCode[0]=Code+(OpSize[2] << 8)+AdrMode[2]; memcpy(WAsmCode+1,AdrVals[2],AdrCnt1[2]); memcpy(WAsmCode+1+AdrCnt2[2],AdrVals[1],AdrCnt1[1]); CodeLen=2+AdrCnt1[1]+AdrCnt1[2]; END END static Boolean CodeAri(void) BEGIN int z; Word AdrWord,Mask,Mask2; char Form[6]; LongInt HVal; if ((Memo("ADD")) OR (Memo("SUB"))) BEGIN z=Ord(Memo("SUB")); if (ArgCnt!=2) WrError(1110); else if (CheckFormat("GELQI")) if (GetOpSize(ArgStr[2],2)) if (GetOpSize(ArgStr[1],1)) BEGIN if (OpSize[2]==-1) OpSize[2]=2; if (OpSize[1]==-1) OpSize[1]=OpSize[2]; if (DecodeAdr(ArgStr[1],1,Mask_Source)) if (DecodeAdr(ArgStr[2],2,Mask_PureDest)) BEGIN if (FormatCode==0) BEGIN if (AdrType[1]==ModImm) BEGIN HVal=ImmVal(1); if (IsShort(2)) if ((HVal>=1) AND (HVal<=8)) FormatCode=4; else FormatCode=5; else if ((HVal>=-128) AND (HVal<127)) FormatCode=2; else FormatCode=1; END else if (IsShort(1) AND (AdrType[2]==ModReg) AND (OpSize[1]==2) AND (OpSize[2]==2)) FormatCode=3; else FormatCode=1; END switch (FormatCode) BEGIN case 1: Make_G(z << 11); break; case 2: Make_E(z << 11,True); break; case 3: if ((NOT IsShort(1)) OR (AdrType[2]!=ModReg)) WrError(1350); else if ((OpSize[1]!=2) OR (OpSize[2]!=2)) WrError(1130); else BEGIN WAsmCode[0]=0x8100+(z << 6)+((AdrMode[2] & 15) << 10)+AdrMode[1]; memcpy(WAsmCode+1,AdrVals[1],AdrCnt1[1]); CodeLen=2+AdrCnt1[1]; if ((AdrMode[1]==0x04) & (AdrMode[2]==15)) WrError(140); END break; case 4: if ((AdrType[1]!=ModImm) OR (NOT IsShort(2))) WrError(1350); else BEGIN HVal=ImmVal(1); if (ChkRange(HVal,1,8)) BEGIN WAsmCode[0]=0x4040+(z << 13)+((HVal & 7) << 10)+(OpSize[2] << 8)+AdrMode[2]; memcpy(WAsmCode+1,AdrVals[2],AdrCnt1[2]); CodeLen=2+AdrCnt1[2]; END END break; case 5: Make_I(0x44c0+(z << 11),True); break; END END END return True; END if (Memo("CMP")) BEGIN if (ArgCnt!=2) WrError(1110); else if (CheckFormat("GELZQI")) if (GetOpSize(ArgStr[1],1)) if (GetOpSize(ArgStr[2],2)) BEGIN if (OpSize[2]==-1) OpSize[2]=2; if (OpSize[1]==-1) OpSize[1]=OpSize[2]; if (DecodeAdr(ArgStr[1],1,Mask_Source)) if (DecodeAdr(ArgStr[2],2,Mask_NoImmGen-MModPush)) BEGIN if (FormatCode==0) BEGIN if (AdrType[1]==ModImm) BEGIN HVal=ImmVal(1); if (HVal==0) FormatCode=4; else if ((HVal>=1) AND (HVal<=8) AND (IsShort(2))) FormatCode=5; else if ((HVal>=-128) AND (HVal<=127)) FormatCode=2; else if (AdrType[2]==ModReg) FormatCode=3; else if (IsShort(2)) FormatCode=5; else FormatCode=1; END else if ((IsShort(1)) AND (AdrType[2]==ModReg)) FormatCode=3; else FormatCode=1; END switch (FormatCode) BEGIN case 1: Make_G(0x8000); break; case 2: Make_E(0x8000,True); break; case 3: if ((NOT IsShort(1)) OR (AdrType[2]!=ModReg)) WrError(1350); else if (OpSize[1]!=2) WrError(1130); else BEGIN WAsmCode[0]=((AdrMode[2] & 15) << 10)+(OpSize[2] << 8)+AdrMode[1]; memcpy(WAsmCode+1,AdrVals[1],AdrCnt1[1]); CodeLen=2+AdrCnt1[1]; END break; case 4: if (AdrType[1]!=ModImm) WrError(1350); else BEGIN HVal=ImmVal(1); if (ChkRange(HVal,0,0)) BEGIN WAsmCode[0]=0xc000+(OpSize[2] << 8)+AdrMode[2]; memcpy(WAsmCode+1,AdrVals[2],AdrCnt1[2]); CodeLen=2+AdrCnt1[2]; END END break; case 5: if ((AdrType[1]!=ModImm) OR (NOT IsShort(2))) WrError(1350); else BEGIN HVal=ImmVal(1); if (ChkRange(HVal,1,8)) BEGIN WAsmCode[0]=0x4000+(OpSize[2] << 8)+AdrMode[2]+((HVal & 7) << 10); memcpy(WAsmCode+1,AdrVals[2],AdrCnt1[2]); CodeLen=2+AdrCnt1[2]; END END break; case 6: Make_I(0x40c0,True); break; END END END return True; END for (z=0; z=-128) AND (HVal<=127)) FormatCode=2; else if ((NOT GE2Orders[z].Signed) AND (HVal>=0) AND (HVal<=255)) FormatCode=2; else FormatCode=1; END else FormatCode=1; END switch (FormatCode) BEGIN case 1: Make_G(GE2Orders[z].Code); break; case 2: Make_E(GE2Orders[z].Code,GE2Orders[z].Signed); break; END END END return True; END for (z=0; z=0) AND (HVal<=255)) FormatCode=2; else if (IsShort(2)) FormatCode=4; else FormatCode=1; END else if ((AdrType[1]==ModReg) AND (AdrType[2]==ModReg) AND (OpSize[1]==2) AND (OpSize[2]==2)) FormatCode=3; else FormatCode=1; END switch (FormatCode) BEGIN case 1: Make_G(0x2000+(z << 10)); break; case 2: Make_E(0x2000+(z << 10),False); break; case 3: if ((AdrType[1]!=ModReg) OR (AdrType[2]!=ModReg)) WrError(1350); else if ((OpSize[1]!=2) OR (OpSize[2]!=2)) WrError(1130); else BEGIN WAsmCode[0]=0x00c0+(z << 8)+(AdrMode[1] & 15)+((AdrMode[2] & 15) << 10); CodeLen=2; END break; case 4: if ((AdrType[1]!=ModImm) OR (NOT IsShort(2))) WrError(1350); else BEGIN WAsmCode[0]=0x50c0+(OpSize[2] << 8)+(z << 10)+AdrMode[2]; memcpy(WAsmCode+1,AdrVals[2],AdrCnt1[2]); AdaptImm(1,OpSize[2],False); memcpy(WAsmCode+1+AdrCnt2[2],AdrVals[1],AdrCnt1[1]); CodeLen=2+AdrCnt1[1]+AdrCnt1[2]; END break; END if (OpSize[1]>OpSize[2]) WrError(140); END END return True; END for (z=0; z=-128+(Ord(Odd(z)) << 7)) AND (HVal<=127+(Ord(Odd(z)) << 7))) FormatCode=2; else FormatCode=1; END else if ((NOT Odd(z)) AND (AdrType[1]==ModReg) AND (OpSize[1]==2) AND (AdrType[2]==ModReg) AND (OpSize[2]==2)) FormatCode=3; else FormatCode=1; END switch (FormatCode) BEGIN case 1: Make_G(0x4000+(z << 10)); break; case 2: Make_E(0x4000+(z << 10),NOT Odd(z)); break; case 3: if ((AdrType[1]!=ModReg) OR (AdrType[2]!=ModReg)) WrError(1350); else if ((OpSize[1]!=2) OR (OpSize[2]!=2)) WrError(1130); else BEGIN WAsmCode[0]=0x00d0+((AdrMode[2] & 15) << 10)+(z << 7)+ (AdrMode[1] & 15); CodeLen=2; END END END END return True; END for (z=0; z=1) AND (abs(HVal)<=8) AND ((z==0) OR (HVal<0))) FormatCode=3; else if ((HVal>=-128) AND (HVal<=127)) FormatCode=2; else FormatCode=1; END else FormatCode=1; END switch (FormatCode) BEGIN case 1: Make_G(0x3000+(z << 10)); break; case 2: Make_E(0x3000+(z << 10),True); break; case 3: if ((AdrType[1]!=ModImm) OR (NOT IsShort(2))) WrError(1350); else BEGIN HVal=ImmVal(1); if (ChkRange(HVal,-8,(1-z) << 3)) if (HVal==0) WrError(1135); else BEGIN if (HVal<0) HVal+=16; else HVal&=7; WAsmCode[0]=0x4080+(HVal << 10)+(z << 6)+(OpSize[2] << 8)+AdrMode[2]; memcpy(WAsmCode+1,AdrVals[2],AdrCnt1[2]); CodeLen=2+AdrCnt1[2]; END END break; END END END return True; END if ((Memo("SHXL")) OR (Memo("SHXR"))) BEGIN if (ArgCnt!=1) WrError(1110); else if (CheckFormat("G")) if (GetOpSize(ArgStr[1],1)) BEGIN if (OpSize[1]==-1) OpSize[1]=2; if (OpSize[1]!=2) WrError(1130); else if (DecodeAdr(ArgStr[1],1,Mask_PureDest)) BEGIN WAsmCode[0]=0x02f7; WAsmCode[1]=0x8a00+(Ord(Memo("SHXR")) << 12)+AdrMode[1]; memcpy(WAsmCode+1,AdrVals,AdrCnt1[1]); CodeLen=4+AdrCnt1[1]; END END return True; END return False; END static Boolean CodeBits(void) BEGIN int z; char Form[6]; LongInt HVal,AdrLong; Word Mask; for (z=0; z=0) AND (HVal<=7) AND (IsShort(2)) AND (BitOrders[z].Code2!=0) AND (OpSize[2]==0)) FormatCode=3; else if ((HVal>=-128) AND (HVal<127)) FormatCode=2; else FormatCode=1; END else FormatCode=1; END; switch (FormatCode) BEGIN case 1: Make_G(BitOrders[z].Code1); break; case 2: Make_E(BitOrders[z].Code1,True); break; case 3: if ((AdrType[1]!=ModImm) OR (NOT IsShort(2))) WrError(1350); else if (OpSize[2]!=0) WrError(1130); else BEGIN HVal=ImmVal(1); if (ChkRange(HVal,0,7)) BEGIN WAsmCode[0]=BitOrders[z].Code2+((HVal & 7) << 10)+AdrMode[2]; memcpy(WAsmCode+1,AdrVals[2],AdrCnt1[2]); CodeLen=2+AdrCnt1[2]; END END break; END END END END return True; END for (z=0; z> 1]+=AdrVals[1][0] & 0xff; else BEGIN memcpy(WAsmCode+(CodeLen >> 1),AdrVals[1],AdrCnt1[1]); CodeLen+=AdrCnt1[1]; END END break; case 3: if ((AdrType[1]!=ModReg) OR (AdrType[2]!=ModImm) OR (AdrType[3]!=ModImm)) WrError(1350); else if ((OpSize[1]!=2) OR (OpSize[4]!=2)) WrError(1130); else BEGIN HVal=ImmVal(2); if (ChkRange(HVal,-128,-127)) BEGIN AdrLong=ImmVal(3); if (ChkRange(AdrLong,1,32)) BEGIN WAsmCode[0]=0xbf00+(HVal & 0xff); WAsmCode[1]=0xc200+(z << 10)+AdrMode[4]; memcpy(WAsmCode+2,AdrVals[4],AdrCnt1[4]); WAsmCode[2+AdrCnt2[4]]=((AdrLong & 31) << 10)+(AdrMode[1] & 15); CodeLen=6+AdrCnt1[4]; END END END break; case 4: if ((AdrType[1]!=ModImm) OR (AdrType[2]!=ModImm) OR (AdrType[3]!=ModImm)) WrError(1350); else if (OpSize[4]!=2) WrError(1130); else BEGIN HVal=ImmVal(2); if (ChkRange(HVal,-128,-127)) BEGIN AdrLong=ImmVal(3); if (ChkRange(AdrLong,1,32)) BEGIN WAsmCode[0]=0xbf00+(HVal & 0xff); WAsmCode[1]=0xd200+(z << 10)+AdrMode[4]; memcpy(WAsmCode+2,AdrVals[4],AdrCnt1[4]); WAsmCode[2+AdrCnt2[4]]=((AdrLong & 31) << 10)+(OpSize[1] << 8); CodeLen=6+AdrCnt1[4]; if (OpSize[1]==0) WAsmCode[(CodeLen-1) >> 1]+=AdrVals[1][0] & 0xff; else BEGIN memcpy(WAsmCode+(CodeLen >> 1),AdrVals[1],AdrCnt1[1]); CodeLen+=AdrCnt1[1]; END END END END break; END END END END return True; END if ((Memo("BFEXT")) OR (Memo("BFEXTU"))) BEGIN z=Ord(Memo("BFEXTU")); if (ArgCnt!=4) WrError(1110); else if (CheckFormat("GE")) if (GetOpSize(ArgStr[1],1)) if (GetOpSize(ArgStr[2],2)) if (GetOpSize(ArgStr[3],3)) if (GetOpSize(ArgStr[4],4)) BEGIN if (OpSize[1]==-1) OpSize[1]=2; if (OpSize[2]==-1) OpSize[2]=2; if (OpSize[3]==-1) OpSize[3]=2; if (OpSize[4]==-1) OpSize[4]=2; if (DecodeAdr(ArgStr[4],4,MModReg)) if (DecodeAdr(ArgStr[3],3,Mask_MemGen-MModPop-MModPush)) if (DecodeAdr(ArgStr[2],2,MModReg+MModImm)) BEGIN if (AdrType[2]==ModReg) Mask=Mask_Source; else Mask=MModImm; if (DecodeAdr(ArgStr[1],1,Mask)) BEGIN if (FormatCode==0) BEGIN if (AdrType[2]==ModReg) FormatCode=1; else FormatCode=2; END switch (FormatCode) BEGIN case 1: if ((OpSize[2]!=2) OR (OpSize[3]!=2) OR (OpSize[4]!=2)) WrError(1130); else BEGIN WAsmCode[0]=0xd000+(OpSize[1] << 8)+AdrMode[1]; memcpy(WAsmCode+1,AdrVals[1],AdrCnt1[1]); WAsmCode[1+AdrCnt2[1]]=0xea00+(z << 10)+AdrMode[3]; memcpy(WAsmCode+2+AdrCnt2[1],AdrVals[3],AdrCnt1[3]); WAsmCode[2+AdrCnt2[1]+AdrCnt2[3]]=((AdrMode[2] & 15) << 10)+(AdrMode[4] & 15); CodeLen=6+AdrCnt1[1]+AdrCnt1[3]; END break; case 2: if ((AdrType[1]!=ModImm) OR (AdrType[2]!=ModImm)) WrError(1350); else if ((OpSize[3]!=2) OR (OpSize[4]!=2)) WrError(1350); else BEGIN HVal=ImmVal(1); if (ChkRange(HVal,-128,127)) BEGIN AdrLong=ImmVal(2); if (ChkRange(AdrLong,1,32)) BEGIN WAsmCode[0]=0xbf00+(HVal & 0xff); WAsmCode[1]=0xea00+(z << 10)+AdrMode[3]; memcpy(WAsmCode+2,AdrVals[3],AdrCnt1[3]); WAsmCode[2+AdrCnt2[3]]=((AdrLong & 31) << 10)+(AdrMode[4] & 15); CodeLen=6+AdrCnt1[3]; END END END break; END END END END return True; END if ((Memo("BSCH/0")) OR (Memo("BSCH/1"))) BEGIN z=OpPart[5]-'0'; if (ArgCnt!=2) WrError(1110); else if (CheckFormat("G")) if (GetOpSize(ArgStr[1],1)) if (GetOpSize(ArgStr[2],2)) BEGIN if (OpSize[1]==-1) OpSize[1]=2; if (OpSize[2]==-1) OpSize[2]=2; if (OpSize[1]!=2) WrError(1130); else if (DecodeAdr(ArgStr[1],1,Mask_Source)) if (DecodeAdr(ArgStr[2],2,Mask_PureDest)) BEGIN /* immer G-Format */ WAsmCode[0]=0xd600+AdrMode[1]; memcpy(WAsmCode+1,AdrVals[1],AdrCnt1[1]); WAsmCode[1+AdrCnt2[1]]=0x5000+(z << 10)+(OpSize[2] << 8)+AdrMode[2]; memcpy(WAsmCode+2+AdrCnt2[1],AdrVals[2],AdrCnt1[2]); CodeLen=4+AdrCnt1[1]+AdrCnt1[2]; END END return True; END return False; END static void MakeCode_M16(void) BEGIN int z; char *p; Word AdrWord,HReg,Mask; LongInt AdrLong,HVal; Boolean OK; DOpSize=(-1); for (z=1; z<=ArgCnt; OpSize[z++]=(-1)); /* zu ignorierendes */ if (Memo("")) return; /* Formatangabe abspalten */ switch (AttrSplit) BEGIN case '.': p=strchr(AttrPart,':'); if (p!=Nil) BEGIN if (p=1) AND (HVal<=8) AND (IsShort(2))) FormatCode=6; else if ((HVal>=-128) AND (HVal<=127)) FormatCode=2; else if (IsShort(2)) FormatCode=7; else FormatCode=1; END else if ((AdrType[1]==ModReg) AND (OpSize[1]==2) AND (IsShort(2))) FormatCode=4; else if ((AdrType[2]==ModReg) AND (OpSize[2]==2) AND (IsShort(1))) FormatCode=3; else FormatCode=1; END switch (FormatCode) BEGIN case 1: Make_G(0x8800); break; case 2: Make_E(0x8800,True); break; case 3: if ((NOT IsShort(1)) OR (AdrType[2]!=ModReg)) WrError(1350); else if (OpSize[2]!=2) WrError(1130); else BEGIN WAsmCode[0]=0x0040+((AdrMode[2] & 15) << 10)+(OpSize[1] << 8)+AdrMode[1]; memcpy(WAsmCode+1,AdrVals[1],AdrCnt1[1]); CodeLen=2+AdrCnt1[1]; END break; case 4: if ((NOT IsShort(2)) OR (AdrType[1]!=ModReg)) WrError(1350); else if (OpSize[1]!=2) WrError(1130); else BEGIN WAsmCode[0]=0x0080+((AdrMode[1] & 15) << 10)+(OpSize[2] << 8)+AdrMode[2]; memcpy(WAsmCode+1,AdrVals[2],AdrCnt1[2]); CodeLen=2+AdrCnt1[2]; END break; case 5: if (AdrType[1]!=ModImm) WrError(1350); else BEGIN HVal=ImmVal(1); if (ChkRange(HVal,0,0)) BEGIN WAsmCode[0]=0xc400+(OpSize[2] << 8)+AdrMode[2]; memcpy(WAsmCode+1,AdrVals[2],AdrCnt1[2]); CodeLen=2+AdrCnt1[2]; END END break; case 6: if ((AdrType[1]!=ModImm) OR (NOT IsShort(2))) WrError(1350); else BEGIN HVal=ImmVal(1); if (ChkRange(HVal,1,8)) BEGIN WAsmCode[0]=0x6000+((HVal & 7) << 10)+(OpSize[2] << 8)+AdrMode[2]; memcpy(WAsmCode+1,AdrVals[2],AdrCnt1[2]); CodeLen=2+AdrCnt1[2]; END END break; case 7: Make_I(0x48c0,True); break; END END END return; END /* ein Operand */ for (z=0; z254))) WrError(1370); else if (Odd(AdrLong)) WrError(1375); else BEGIN CodeLen=2; WAsmCode[0]=0xae00+(z << 8)+Lo(AdrLong >> 1); END END break; case 1: WAsmCode[0]=0x20f7+(z << 11)+(((Word)OpSize[1]) << 8); AdrLong-=EProgCounter(); switch (OpSize[1]) BEGIN case 0: if ((NOT SymbolQuestionable) AND ((AdrLong<-128) OR (AdrLong>127))) WrError(1370); else BEGIN CodeLen=4; WAsmCode[1]=Lo(AdrLong); END break; case 1: if ((NOT SymbolQuestionable) AND ((AdrLong<-32768) OR (AdrLong>32767))) WrError(1370); else BEGIN CodeLen=4; WAsmCode[1]=AdrLong & 0xffff; END break; case 2: CodeLen=6; WAsmCode[1]=AdrLong >> 16; WAsmCode[2]=AdrLong & 0xffff; break; END break; END END END return; END if (*OpPart=='B') for (z=0; z254))) WrError(1370); else if (Odd(AdrLong)) WrError(1375); else BEGIN CodeLen=2; WAsmCode[0]=0x8000+(z << 10)+Lo(AdrLong >> 1); END END break; case 1: WAsmCode[0]=0x00f6+(z << 10)+(((Word)OpSize[1]) << 8); AdrLong-=EProgCounter(); switch (OpSize[1]) BEGIN case 0: if ((AdrLong<-128) OR (AdrLong>127)) WrError(1370); else BEGIN CodeLen=4; WAsmCode[1]=Lo(AdrLong); END break; case 1: if ((AdrLong<-32768) OR (AdrLong>32767)) WrError(1370); else BEGIN CodeLen=4; WAsmCode[1]=AdrLong & 0xffff; END break; case 2: CodeLen=6; WAsmCode[1]=AdrLong >> 16; WAsmCode[2]=AdrLong & 0xffff; break; END break; END END END return; END if ((Memo("ACB")) OR (Memo("SCB"))) BEGIN AdrWord=Ord(Memo("SCB")); if (ArgCnt!=4) WrError(1110); else if (CheckFormat("GEQR")) if (GetOpSize(ArgStr[2],3)) if (GetOpSize(ArgStr[4],4)) if (GetOpSize(ArgStr[1],1)) if (GetOpSize(ArgStr[3],2)) BEGIN if ((OpSize[3]==-1) AND (OpSize[2]==-1)) OpSize[3]=2; if ((OpSize[3]==-1) AND (OpSize[2]!=-1)) OpSize[3]=OpSize[2]; else if ((OpSize[3]!=-1) AND (OpSize[2]==-1)) OpSize[2]=OpSize[3]; if (OpSize[1]==-1) OpSize[1]=OpSize[2]; if (OpSize[3]!=OpSize[2]) WrError(1131); else if (NOT DecodeReg(ArgStr[2],&HReg)) WrError(1350); else BEGIN AdrLong=EvalIntExpression(ArgStr[4],Int32,&OK); if (OK) BEGIN if (DecodeAdr(ArgStr[1],1,Mask_Source)) if (DecodeAdr(ArgStr[3],2,Mask_Source)) BEGIN if (FormatCode==0) BEGIN if (AdrType[1]!=ModImm) FormatCode=1; else BEGIN HVal=ImmVal(1); if ((HVal==1) AND (AdrType[2]==ModReg)) FormatCode=4; else if ((HVal==1) AND (AdrType[2]==ModImm)) BEGIN HVal=ImmVal(2); if ((HVal>=1-AdrWord) AND (HVal<=64-AdrWord)) FormatCode=3; else FormatCode=2; END else if ((HVal>=-128) AND (HVal<=127)) FormatCode=2; else FormatCode=1; END END switch (FormatCode) BEGIN case 1: if (DecideBranchLength(&AdrLong,4)) /* ??? */ BEGIN WAsmCode[0]=0xd000+(OpSize[1] << 8)+AdrMode[1]; memcpy(WAsmCode+1,AdrVals[1],AdrCnt1[1]); WAsmCode[1+AdrCnt2[1]]=0xf000+(AdrWord << 11)+(OpSize[2] << 8)+AdrMode[2]; memcpy(WAsmCode+2+AdrCnt2[1],AdrVals[2],AdrCnt1[2]); WAsmCode[2+AdrCnt2[1]+AdrCnt2[2]]=(HReg << 10)+(OpSize[4] << 8); CodeLen=6+AdrCnt1[1]+AdrCnt1[2]; END break; case 2: if (DecideBranchLength(&AdrLong,4)) /* ??? */ if (AdrType[1]!=ModImm) WrError(1350); else BEGIN HVal=ImmVal(1); if (ChkRange(HVal,-128,127)) BEGIN WAsmCode[0]=0xbf00+(HVal & 0xff); WAsmCode[1]=0xf000+(AdrWord << 11)+(OpSize[2] << 8)+AdrMode[2]; memcpy(WAsmCode+2,AdrVals[2],AdrCnt1[2]); WAsmCode[2+AdrCnt2[2]]=(HReg << 10)+(OpSize[4] << 8); CodeLen=6+AdrCnt1[2]; END END break; case 3: if (DecideBranchLength(&AdrLong,4)) /* ??? */ if (AdrType[1]!=ModImm) WrError(1350); else if (ImmVal(1)!=1) WrError(1135); else if (AdrType[2]!=ModImm) WrError(1350); else BEGIN HVal=ImmVal(2); if (ChkRange(HVal,1-AdrWord,64-AdrWord)) BEGIN WAsmCode[0]=0x03d1+(HReg << 10)+(AdrWord << 1); WAsmCode[1]=((HVal & 0x3f) << 10)+(OpSize[4] << 8); CodeLen=4; END END break; case 4: if (DecideBranchLength(&AdrLong,4)) /* ??? */ if (AdrType[1]!=ModImm) WrError(1350); else if (ImmVal(1)!=1) WrError(1135); else if (OpSize[2]!=2) WrError(1130); else if (AdrType[2]!=ModReg) WrError(1350); else BEGIN WAsmCode[0]=0x03d0+(HReg << 10)+(AdrWord << 1); WAsmCode[1]=((AdrMode[2] & 15) << 10)+(OpSize[4] << 8); CodeLen=4; END break; END if (CodeLen>0) switch (OpSize[4]) BEGIN case 0: WAsmCode[(CodeLen >> 1)-1]+=AdrLong & 0xff; break; case 1: WAsmCode[CodeLen >> 1]=AdrLong & 0xffff; CodeLen+=2; break; case 2: WAsmCode[ CodeLen >> 1 ]=AdrLong >> 16; WAsmCode[(CodeLen >> 1)+1]=AdrLong & 0xffff; CodeLen+=4; break; END END END END END return; END if (Memo("TRAPA")) BEGIN if (ArgCnt!=1) WrError(1110); else if (*AttrPart!='\0') WrError(1100); else if (strcmp(Format," ")!=0) WrError(1090); else if (*ArgStr[1]!='#') WrError(1350); else BEGIN AdrWord=EvalIntExpression(ArgStr[1]+1,UInt4,&OK); if (OK) BEGIN CodeLen=2; WAsmCode[0]=0x03d5+(AdrWord << 10); END END return; END if (strncmp(OpPart,"TRAP",4)==0) BEGIN if (ArgCnt!=0) WrError(1110); else if (*AttrPart!='\0') WrError(1100); else if (strcmp(Format," ")!=0) WrError(1090); else BEGIN SplitOptions(); if (OptionCnt!=1) WrError(1115); else if (NOT DecodeCondition(Options[0],&AdrWord)) WrError(1360); else BEGIN CodeLen=2; WAsmCode[0]=0x03d4+(AdrWord << 10); END END return; END /* Specials */ if ((Memo("ENTER")) OR (Memo("EXITD"))) BEGIN if (Memo("EXITD")) BEGIN z=1; strcpy(ArgStr[3],ArgStr[1]); strcpy(ArgStr[1],ArgStr[2]); strcpy(ArgStr[2],ArgStr[3]); END else z=0; if (ArgCnt!=2) WrError(1110); else if (CheckFormat("GE")) if (GetOpSize(ArgStr[1],1)) if (GetOpSize(ArgStr[2],2)) BEGIN if (OpSize[1]==-1) OpSize[1]=2; if (OpSize[2]==-1) OpSize[2]=2; if (OpSize[2]!=2) WrError(1130); else if (DecodeAdr(ArgStr[1],1,MModReg+MModImm)) if (DecodeRegList(ArgStr[2],&AdrWord,z==1)) if ((z & 0xc000)!=0) WrXError(1410,"SP/FP"); else BEGIN if (FormatCode==0) BEGIN if (AdrType[1]==ModImm) BEGIN HVal=ImmVal(1); if ((HVal>=-128) AND (HVal<=127)) FormatCode=2; else FormatCode=1; END else FormatCode=1; END switch (FormatCode) BEGIN case 1: WAsmCode[0]=0x02f7; WAsmCode[1]=0x8c00+(z << 12)+(OpSize[1] << 8)+AdrMode[1]; memcpy(WAsmCode+2,AdrVals[1],AdrCnt1[1]); WAsmCode[2+AdrCnt2[1]]=AdrWord; CodeLen=6+AdrCnt1[1]; break; case 2: if (AdrType[1]!=ModImm) WrError(1350); else BEGIN HVal=ImmVal(1); if (ChkRange(HVal,-128,127)) BEGIN WAsmCode[0]=0x8e00+(z << 12)+(HVal & 0xff); WAsmCode[1]=AdrWord; CodeLen=4; END END break; END END END return; END if (strncmp(OpPart,"SCMP",4)==0) BEGIN if (DOpSize==-1) DOpSize=2; if (ArgCnt!=0) WrError(1110); else BEGIN SplitOptions(); if (OptionCnt>1) WrError(1115); else BEGIN OK=True; if (OptionCnt==0) AdrWord=6; else if (strcasecmp(Options[0],"LTU")==0) AdrWord=0; else if (strcasecmp(Options[0],"GEU")==0) AdrWord=1; else OK=(DecodeCondition(Options[0],&AdrWord) AND (AdrWord>1) AND (AdrWord<6)); if (NOT OK) WrXError(1360,Options[0]); else BEGIN WAsmCode[0]=0x00e0+(DOpSize << 8)+(AdrWord << 10); CodeLen=2; END END END return; END if ((strncmp(OpPart,"SMOV",4)==0) OR (strncmp(OpPart,"SSCH",4)==0)) BEGIN if (DOpSize==-1) DOpSize=2; z=Ord(OpPart[1]=='S') << 4; if (ArgCnt!=0) WrError(1110); else BEGIN SplitOptions(); if (strcasecmp(Options[0],"F")==0) BEGIN Mask=0; strcpy(Options[0],Options[1]); OptionCnt--; END else if (strcasecmp(Options[0],"B")==0) BEGIN Mask=1; strcpy(Options[0],Options[1]); OptionCnt--; END else if (strcasecmp(Options[1],"F")==0) BEGIN Mask=0; OptionCnt--; END else if (strcasecmp(Options[1],"B")==0) BEGIN Mask=1; OptionCnt--; END else Mask=0; if (OptionCnt>1) WrError(1115); else BEGIN OK=True; if (OptionCnt==0) AdrWord=6; else if (strcasecmp(Options[0],"LTU")==0) AdrWord=0; else if (strcasecmp(Options[0],"GEU")==0) AdrWord=1; else OK=(DecodeCondition(Options[0],&AdrWord)) AND (AdrWord>1) AND (AdrWord<6); if (NOT OK) WrXError(1360,Options[0]); else BEGIN WAsmCode[0]=0x00e4+(DOpSize << 8)+(AdrWord << 10)+Mask+z; CodeLen=2; END END END return; END if (Memo("SSTR")) BEGIN if (DOpSize==-1) DOpSize=2; if (ArgCnt!=0) WrError(1110); else BEGIN WAsmCode[0]=0x24f7+(DOpSize << 8); CodeLen=2; END return; END if ((Memo("LDM")) OR (Memo("STM"))) BEGIN Mask=MModIReg+MModDisp16+MModDisp32+MModAbs16+MModAbs32+MModPCRel16+MModPCRel32; if (Memo("LDM")) BEGIN z=0x1000; Mask+=MModPop; strcpy(ArgStr[3],ArgStr[1]); strcpy(ArgStr[1],ArgStr[2]); strcpy(ArgStr[2],ArgStr[3]); END else BEGIN z=0; Mask+=MModPush; END if (ArgCnt!=2) WrError(1110); else if (CheckFormat("G")) if (GetOpSize(ArgStr[1],1)) if (GetOpSize(ArgStr[2],2)) BEGIN if (OpSize[1]==-1) OpSize[1]=2; if (OpSize[2]==-1) OpSize[2]=2; if ((OpSize[1]!=2) OR (OpSize[2]!=2)) WrError(1130); else if (DecodeAdr(ArgStr[2],2,Mask)) if (DecodeRegList(ArgStr[1],&AdrWord,AdrType[2]!=ModPush)) BEGIN WAsmCode[0]=0x8a00+z+AdrMode[2]; memcpy(WAsmCode+1,AdrVals[2],AdrCnt1[2]); WAsmCode[1+AdrCnt2[2]]=AdrWord; CodeLen=4+AdrCnt1[2]; END END return; END if ((Memo("STC")) OR (Memo("STP"))) BEGIN z=Ord(Memo("STP")) << 10; if (ArgCnt!=2) WrError(1110); else if (CheckFormat("G")) if (GetOpSize(ArgStr[1],1)) if (GetOpSize(ArgStr[2],2)) BEGIN if (OpSize[2]==-1) OpSize[2]=2; if (OpSize[1]==-1) OpSize[1]=OpSize[1]; if (OpSize[1]!=OpSize[2]) WrError(1132); else if ((z==0) AND (OpSize[2]!=2)) WrError(1130); else if (DecodeAdr(ArgStr[1],1,Mask_PureMem)) if (DecodeAdr(ArgStr[2],2,Mask_Dest)) BEGIN OpSize[1]=0; Make_G(0xa800+z); WAsmCode[0]+=0x800; END END return; END if (Memo("WAIT")) BEGIN if (ArgCnt!=1) WrError(1110); else if (*AttrPart!='\0') WrError(1100); else if (strcmp(Format," ")!=0) WrError(1090); else if (*ArgStr[1]!='#') WrError(1350); else BEGIN WAsmCode[1]=EvalIntExpression(ArgStr[1]+1,UInt3,&OK); if (OK) BEGIN WAsmCode[0]=0x0fd6; CodeLen=4; END END return; END if (Memo("JRNG")) BEGIN if (ArgCnt!=1) WrError(1110); else if (CheckFormat("GE")) if (GetOpSize(ArgStr[1],1)) BEGIN if (OpSize[1]==-1) OpSize[1]=1; if (OpSize[1]!=1) WrError(1130); else if (DecodeAdr(ArgStr[1],1,MModReg+MModImm)) BEGIN if (FormatCode==0) BEGIN if (AdrType[1]==ModImm) BEGIN HVal=ImmVal(1); if ((HVal>=0) AND (HVal<=255)) FormatCode=2; else FormatCode=1; END else FormatCode=1; END switch (FormatCode) BEGIN case 1: WAsmCode[0]=0xba00+AdrMode[1]; memcpy(WAsmCode+1,AdrVals[1],AdrCnt1[1]); CodeLen=2+AdrCnt1[1]; break; case 2: if (AdrType[1]!=ModImm) WrError(1350); else BEGIN HVal=ImmVal(1); if (ChkRange(HVal,0,255)) BEGIN WAsmCode[0]=0xbe00+(HVal & 0xff); CodeLen=2; END END break; END END END return; END WrXError(1200,OpPart); END static Boolean IsDef_M16(void) BEGIN return False; END static void SwitchFrom_M16(void) BEGIN DeinitFields(); END static void SwitchTo_M16(void) BEGIN TurnWords=True; ConstMode=ConstModeIntel; SetIsOccupied=False; PCSymbol="$"; HeaderID=0x13; NOPCode=0x1bd6; DivideChars=","; HasAttrs=True; AttrChars=".:"; ValidSegs=1<