From 333b605b2afd472b823aeda0adf0e8b1ea9843c0 Mon Sep 17 00:00:00 2001 From: fishsoupisgood Date: Mon, 27 May 2019 02:41:51 +0100 Subject: initial commit from asl-1.41r8.tar.gz --- codem16c.c | 2360 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2360 insertions(+) create mode 100644 codem16c.c (limited to 'codem16c.c') diff --git a/codem16c.c b/codem16c.c new file mode 100644 index 0000000..ae03b86 --- /dev/null +++ b/codem16c.c @@ -0,0 +1,2360 @@ +/* codem16c.c */ +/*****************************************************************************/ +/* AS-Portierung */ +/* */ +/* Codegenerator M16C */ +/* */ +/* Historie: 17.12.1996 Grundsteinlegung */ +/* 21. 9.1998 Kodierungsfehler: mov.b:s #0,...->dests vergessen */ +/* mov.x:s #imm,reg->OpSize invertiert*/ +/* sub.x:q #imm4,...->falscher Opcode */ +/* 3. 1.1999 ChkPC-Anpassung */ +/* {RMS} 6. 2.1999 Fixed remaining code generation errors - M16C is now */ +/* 100% correct, validated against reference assemblers */ +/* and official Mitsubishi documentation. */ +/* Search for RMS: tags to see changes */ +/* {RMS} 8. 2.1999 Fixed ChkPC SegLimit typo [M16s have 20 bits] */ +/* {RMS} 10. 2.1999 Accomodate JMP.S crossing 64k boundary bug in M16C */ +/* {RMS} 2. 4.1999 Made the JMP.S promotion fix CPU-dependent, and made */ +/* repairs to the JMP.S handling for forward label refs */ +/* so they now work. [JMP.S symbol] now works. */ +/* */ +/*****************************************************************************/ + +#include "stdinc.h" +#include "string.h" +#include + +#include "nls.h" +#include "bpemu.h" +#include "strutil.h" +#include "asmdef.h" +#include "asmsub.h" +#include "asmpars.h" +#include "codepseudo.h" +#include "codevars.h" + +#define ModNone (-1) +#define ModGen 0 +#define MModGen (1 << ModGen) +#define ModAbs20 1 +#define MModAbs20 (1 << ModAbs20) +#define ModAReg32 2 +#define MModAReg32 (1 << ModAReg32) +#define ModDisp20 3 +#define MModDisp20 (1 << ModDisp20) +#define ModReg32 4 +#define MModReg32 (1 << ModReg32) +#define ModIReg32 5 +#define MModIReg32 (1 << ModIReg32) +#define ModImm 6 +#define MModImm (1 << ModImm) +#define ModSPRel 7 +#define MModSPRel (1 << ModSPRel) + +#define FixedOrderCnt 8 +#define StringOrderCnt 4 +#define Gen1OrderCnt 5 +#define Gen2OrderCnt 6 +#define DivOrderCnt 3 +#define ConditionCnt 18 +#define BCDOrderCnt 4 +#define DirOrderCnt 4 +#define BitOrderCnt 13 + +typedef struct + { + char *Name; + Word Code; + } FixedOrder; + +typedef struct + { + char *Name; + Byte Code1,Code2,Code3; + } Gen2Order; + +typedef struct + { + char *Name; + Byte Code; + } Condition; + + +static char *Flags="CDZSBOIU"; + +static CPUVar CPUM16C,CPUM30600M8,CPUM30610,CPUM30620; + +static String Format; +static Byte FormatCode; +static ShortInt OpSize; +static Byte AdrMode,AdrMode2; +static ShortInt AdrType,AdrType2; +static Byte AdrCnt2; +static Byte AdrVals[3],AdrVals2[3]; + +static FixedOrder *FixedOrders; +static FixedOrder *StringOrders; +static FixedOrder *Gen1Orders; +static Gen2Order *Gen2Orders; +static Gen2Order *DivOrders; +static Condition *Conditions; +static char **BCDOrders; +static char **DirOrders; +static FixedOrder *BitOrders; + +/*------------------------------------------------------------------------*/ + + static void AddFixed(char *NName, Word NCode) +BEGIN + if (InstrZ>=FixedOrderCnt) exit(255); + FixedOrders[InstrZ].Name=NName; + FixedOrders[InstrZ++].Code=NCode; +END + + static void AddString(char *NName, Word NCode) +BEGIN + if (InstrZ>=StringOrderCnt) exit(255); + StringOrders[InstrZ].Name=NName; + StringOrders[InstrZ++].Code=NCode; +END + + static void AddGen1(char *NName, Word NCode) +BEGIN + if (InstrZ>=Gen1OrderCnt) exit(255); + Gen1Orders[InstrZ].Name=NName; + Gen1Orders[InstrZ++].Code=NCode; +END + + static void AddGen2(char *NName, Byte NCode1, Byte NCode2, Byte NCode3) +BEGIN + if (InstrZ>=Gen2OrderCnt) exit(255); + Gen2Orders[InstrZ].Name=NName; + Gen2Orders[InstrZ].Code1=NCode1; + Gen2Orders[InstrZ].Code2=NCode2; + Gen2Orders[InstrZ++].Code3=NCode3; +END + + static void AddDiv(char *NName, Byte NCode1, Byte NCode2, Byte NCode3) +BEGIN + if (InstrZ>=DivOrderCnt) exit(255); + DivOrders[InstrZ].Name=NName; + DivOrders[InstrZ].Code1=NCode1; + DivOrders[InstrZ].Code2=NCode2; + DivOrders[InstrZ++].Code3=NCode3; +END + + static void AddCondition(char *NName, Word NCode) +BEGIN + if (InstrZ>=ConditionCnt) exit(255); + Conditions[InstrZ].Name=NName; + Conditions[InstrZ++].Code=NCode; +END + + static void AddBCD(char *NName) +BEGIN + if (InstrZ>=BCDOrderCnt) exit(255); + BCDOrders[InstrZ++]=NName; +END + + static void AddDir(char *NName) +BEGIN + if (InstrZ>=DirOrderCnt) exit(255); + DirOrders[InstrZ++]=NName; +END + + static void AddBit(char *NName, Word NCode) +BEGIN + if (InstrZ>=BitOrderCnt) exit(255); + BitOrders[InstrZ].Name=NName; + BitOrders[InstrZ++].Code=NCode; +END + + static void InitFields(void) +BEGIN + InstrZ=0; FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); + AddFixed("BRK" ,0x0000); + AddFixed("EXITD" ,0x7df2); + AddFixed("INTO" ,0x00f6); + AddFixed("NOP" ,0x0004); + AddFixed("REIT" ,0x00fb); + AddFixed("RTS" ,0x00f3); + AddFixed("UND" ,0x00ff); + AddFixed("WAIT" ,0x7df3); + + InstrZ=0; StringOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*StringOrderCnt); + AddString("RMPA" ,0x7cf1); + AddString("SMOVB",0x7ce9); + AddString("SMOVF",0x7ce8); + AddString("SSTR" ,0x7cea); + + InstrZ=0; Gen1Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*Gen1OrderCnt); + AddGen1("ABS" ,0x76f0); + AddGen1("ADCF",0x76e0); + AddGen1("NEG" ,0x7450); + AddGen1("ROLC",0x76a0); + AddGen1("RORC",0x76b0); + + InstrZ=0; Gen2Orders=(Gen2Order *) malloc(sizeof(Gen2Order)*Gen2OrderCnt); + AddGen2("ADC" ,0xb0,0x76,0x60); + AddGen2("SBB" ,0xb8,0x76,0x70); + AddGen2("TST" ,0x80,0x76,0x00); + AddGen2("XOR" ,0x88,0x76,0x10); + AddGen2("MUL" ,0x78,0x7c,0x50); + AddGen2("MULU",0x70,0x7c,0x40); + + InstrZ=0; DivOrders=(Gen2Order *) malloc(sizeof(Gen2Order)*DivOrderCnt); + AddDiv("DIV" ,0xe1,0x76,0xd0); + AddDiv("DIVU",0xe0,0x76,0xc0); + AddDiv("DIVX",0xe3,0x76,0x90); + + InstrZ=0; Conditions=(Condition *) malloc(sizeof(Condition)*ConditionCnt); + AddCondition("GEU", 0); AddCondition("C" , 0); + AddCondition("GTU", 1); AddCondition("EQ" , 2); + AddCondition("Z" , 2); AddCondition("N" , 3); + AddCondition("LTU", 4); AddCondition("NC" , 4); + AddCondition("LEU", 5); AddCondition("NE" , 6); + AddCondition("NZ" , 6); AddCondition("PZ" , 7); + AddCondition("LE" , 8); AddCondition("O" , 9); + AddCondition("GE" ,10); AddCondition("GT" ,12); + AddCondition("NO" ,13); AddCondition("LT" ,14); + + InstrZ=0; BCDOrders=(char **) malloc(sizeof(char *)*BCDOrderCnt); + AddBCD("DADD"); AddBCD("DSUB"); AddBCD("DADC"); AddBCD("DSBB"); + + InstrZ=0; DirOrders=(char **) malloc(sizeof(char *)*DirOrderCnt); + AddDir("MOVLL"); AddDir("MOVHL"); AddDir("MOVLH"); AddDir("MOVHH"); + + InstrZ=0; BitOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*BitOrderCnt); + AddBit("BAND" , 4); AddBit("BNAND" , 5); + AddBit("BNOR" , 7); AddBit("BNTST" , 3); + AddBit("BNXOR" ,13); AddBit("BOR" , 6); + AddBit("BTSTC" , 0); AddBit("BTSTS" , 1); + AddBit("BXOR" ,12); AddBit("BCLR" , 8); + AddBit("BNOT" ,10); AddBit("BSET" , 9); + AddBit("BTST" ,11); +END + + static void DeinitFields(void) +BEGIN + free(FixedOrders); + free(StringOrders); + free(Gen1Orders); + free(Gen2Orders); + free(DivOrders); + free(Conditions); + free(BCDOrders); + free(DirOrders); + free(BitOrders); +END + +/*------------------------------------------------------------------------*/ +/* Adressparser */ + + static void SetOpSize(ShortInt NSize) +BEGIN + if (OpSize==-1) OpSize=NSize; + else if (NSize!=OpSize) + BEGIN + WrError(1131); + AdrCnt=0; AdrType=ModNone; + END +END + + static void ChkAdr(Word Mask) +BEGIN + if ((AdrType!=ModNone) AND ((Mask & (1 << AdrType))==0)) + BEGIN + AdrCnt=0; AdrType=ModNone; WrError(1350); + END +END + + static void DecodeAdr(char *Asc, Word Mask) +BEGIN + LongInt DispAcc; + String RegPart; + char *p; + Boolean OK; + + AdrCnt=0; AdrType=ModNone; + + /* Datenregister 8 Bit */ + + if ((strlen(Asc)==3) AND (toupper(*Asc)=='R') AND (Asc[1]>='0') AND (Asc[1]<='1') AND + ((toupper(Asc[2])=='L') OR (toupper(Asc[2])=='H'))) + BEGIN + AdrType=ModGen; + AdrMode=((Asc[1]-'0') << 1)+Ord(toupper(Asc[2])=='H'); + SetOpSize(0); + ChkAdr(Mask); return; + END; + + /* Datenregister 16 Bit */ + + if ((strlen(Asc)==2) AND (toupper(*Asc)=='R') AND (Asc[1]>='0') AND (Asc[1]<='3')) + BEGIN + AdrType=ModGen; + AdrMode=Asc[1]-'0'; + SetOpSize(1); + ChkAdr(Mask); return; + END + + /* Datenregister 32 Bit */ + + if (strcasecmp(Asc,"R2R0")==0) + BEGIN + AdrType=ModReg32; AdrMode=0; + SetOpSize(2); + ChkAdr(Mask); return; + END; + + if (strcasecmp(Asc,"R3R1")==0) + BEGIN + AdrType=ModReg32; AdrMode=1; + SetOpSize(2); + ChkAdr(Mask); return; + END + + /* Adressregister */ + + if ((strlen(Asc)==2) AND (toupper(*Asc)=='A') AND (Asc[1]>='0') AND (Asc[1]<='1')) + BEGIN + AdrType=ModGen; + AdrMode=Asc[1]-'0'+4; + ChkAdr(Mask); return; + END + + /* Adressregister 32 Bit */ + + if (strcasecmp(Asc,"A1A0")==0) + BEGIN + AdrType=ModAReg32; + SetOpSize(2); + ChkAdr(Mask); return; + END + + /* indirekt */ + + p=strchr(Asc,'['); + if ((p!=Nil) AND (Asc[strlen(Asc)-1]==']')) + BEGIN + strmaxcpy(RegPart,p+1,255); RegPart[strlen(RegPart)-1]='\0'; + if ((strcasecmp(RegPart,"A0")==0) OR (strcasecmp(RegPart,"A1")==0)) + BEGIN + *p='\0'; + DispAcc=EvalIntExpression(Asc,((Mask & MModDisp20)==0)?Int16:Int20,&OK); + if (OK) + if ((DispAcc==0) AND ((Mask & MModGen)!=0)) + BEGIN + AdrType=ModGen; + AdrMode=RegPart[1]-'0'+6; + END + else if ((DispAcc>=0) AND (DispAcc<=255) AND ((Mask & MModGen)!=0)) + BEGIN + AdrType=ModGen; + AdrVals[0]=DispAcc & 0xff; + AdrCnt=1; + AdrMode=RegPart[1]-'0'+8; + END + else if ((DispAcc>=-32768) AND (DispAcc<=65535) AND ((Mask & MModGen)!=0)) + BEGIN + AdrType=ModGen; + AdrVals[0]=DispAcc & 0xff; AdrVals[1]=(DispAcc >> 8) & 0xff; + AdrCnt=2; + AdrMode=RegPart[1]-'0'+12; + END + else if (strcasecmp(RegPart,"A0")!=0) WrError(1350); + else + BEGIN + AdrType=ModDisp20; + AdrVals[0]=DispAcc & 0xff; + AdrVals[1]=(DispAcc >> 8) & 0xff; + AdrVals[2]=(DispAcc >> 16) & 0x0f; + AdrCnt=3; + AdrMode=RegPart[1]-'0'; + END + END + else if (strcasecmp(RegPart,"SB")==0) + BEGIN + *p='\0'; + DispAcc=EvalIntExpression(Asc,Int16,&OK); + if (OK) + if ((DispAcc>=0) AND (DispAcc<=255)) + BEGIN + AdrType=ModGen; + AdrVals[0]=DispAcc & 0xff; + AdrCnt=1; + AdrMode=10; + END + else + BEGIN + AdrType=ModGen; + AdrVals[0]=DispAcc & 0xff; AdrVals[1]=(DispAcc >> 8) & 0xff; + AdrCnt=2; + AdrMode=14; + END + END + else if (strcasecmp(RegPart,"FB")==0) + BEGIN + *p='\0'; + DispAcc=EvalIntExpression(Asc,SInt8,&OK); + if (OK) + BEGIN + AdrType=ModGen; + AdrVals[0]=DispAcc & 0xff; + AdrCnt=1; + AdrMode=11; + END + END + else if (strcasecmp(RegPart,"SP")==0) + BEGIN + *p='\0'; + DispAcc=EvalIntExpression(Asc,SInt8,&OK); + if (OK) + BEGIN + AdrType=ModSPRel; + AdrVals[0]=DispAcc & 0xff; + AdrCnt=1; + END + END + else if (strcasecmp(RegPart,"A1A0")==0) + BEGIN + *p='\0'; + DispAcc=EvalIntExpression(Asc,SInt8,&OK); + if (OK) + if (DispAcc!=0) WrError(1320); + else AdrType=ModIReg32; + END + ChkAdr(Mask); return; + END + + /* immediate */ + + if (*Asc=='#') + BEGIN + switch (OpSize) + BEGIN + case -1: + WrError(1132); + break; + case 0: + AdrVals[0]=EvalIntExpression(Asc+1,Int8,&OK); + if (OK) + BEGIN + AdrType=ModImm; AdrCnt=1; + END + break; + case 1: + DispAcc=EvalIntExpression(Asc+1,Int16,&OK); + if (OK) + BEGIN + AdrType=ModImm; + AdrVals[0]=DispAcc & 0xff; + AdrVals[1]=(DispAcc >> 8) & 0xff; + AdrCnt=2; + END + break; + END + ChkAdr(Mask); return; + END + + /* dann absolut */ + + DispAcc=EvalIntExpression(Asc,((Mask & MModAbs20)==0)?UInt16:UInt20,&OK); + if ((DispAcc<=0xffff) AND ((Mask & MModGen)!=0)) + BEGIN + AdrType=ModGen; + AdrMode=15; + AdrVals[0]=DispAcc & 0xff; + AdrVals[1]=(DispAcc >> 8) & 0xff; + AdrCnt=2; + END + else + BEGIN + AdrType=ModAbs20; + AdrVals[0]=DispAcc & 0xff; + AdrVals[1]=(DispAcc >> 8) & 0xff; + AdrVals[2]=(DispAcc >> 16) & 0x0f; + AdrCnt=3; + END + + ChkAdr(Mask); +END + + static Boolean DecodeReg(char *Asc, Byte *Erg) +BEGIN + if (strcasecmp(Asc,"FB")==0) *Erg=7; + else if (strcasecmp(Asc,"SB")==0) *Erg=6; + else if ((strlen(Asc)==2) AND (toupper(*Asc)=='A') AND + (Asc[1]>='0') AND (Asc[1]<='1')) *Erg=Asc[1]-'0'+4; + else if ((strlen(Asc)==2) AND (toupper(*Asc)=='R') AND + (Asc[1]>='0') AND (Asc[1]<='3')) *Erg=Asc[1]-'0'; + else return False; + return True; +END + + static Boolean DecodeCReg(char *Asc, Byte *Erg) +BEGIN + if (strcasecmp(Asc,"INTBL")==0) *Erg=1; + else if (strcasecmp(Asc,"INTBH")==0) *Erg=2; + else if (strcasecmp(Asc,"FLG")==0) *Erg=3; + else if (strcasecmp(Asc,"ISP")==0) *Erg=4; + else if (strcasecmp(Asc,"SP")==0) *Erg=5; + else if (strcasecmp(Asc,"SB")==0) *Erg=6; + else if (strcasecmp(Asc,"FB")==0) *Erg=7; + else + BEGIN + WrXError(1440,Asc); return False; + END + return True; +END + + static void DecodeDisp(char *Asc, IntType Type1, IntType Type2, LongInt *DispAcc, Boolean *OK) +BEGIN + if (ArgCnt==2) *DispAcc+=EvalIntExpression(Asc,Type2,OK)*8; + else *DispAcc=EvalIntExpression(Asc,Type1,OK); +END + + static Boolean DecodeBitAdr(Boolean MayShort) +BEGIN + LongInt DispAcc; + Boolean OK; + char *Pos1; + String Asc,Reg; + + AdrCnt=0; + + /* Nur 1 oder 2 Argumente zugelassen */ + + if ((ArgCnt<1) OR (ArgCnt>2)) + BEGIN + WrError(1110); return False; + END + + /* Ist Teil 1 ein Register ? */ + + if ((DecodeReg(ArgStr[ArgCnt],&AdrMode))) + if (AdrMode<6) + BEGIN + if (ArgCnt!=2) WrError(1110); + else + BEGIN + AdrVals[0]=EvalIntExpression(ArgStr[1],UInt4,&OK); + if (OK) + BEGIN + AdrCnt=1; return True; + END + END + return False; + END + + /* Bitnummer ? */ + + if (ArgCnt==2) + BEGIN + DispAcc=EvalIntExpression(ArgStr[1],UInt16,&OK); /* RMS 02: The displacement can be 16 bits */ + if (NOT OK) return False; + END + else DispAcc=0; + + /* Registerangabe ? */ + + strmaxcpy(Asc,ArgStr[ArgCnt],255); + Pos1=QuotPos(Asc,'['); + + /* nein->absolut */ + + if (Pos1==Nil) + BEGIN + DecodeDisp(Asc,UInt16,UInt13,&DispAcc,&OK); + if ((OK) && (DispAcc<0x10000)) /* RMS 09: This is optional, it detects rollover of the bit address. */ + BEGIN + AdrMode=15; + AdrVals[0]=DispAcc & 0xff; + AdrVals[1]=(DispAcc >> 8) & 0xff; + AdrCnt=2; + return True; + END + WrError(1510); /* RMS 08: Notify user there's a problem with address */ + return False; + END + + /* Register abspalten */ + + if (Asc[strlen(Asc)-1]!=']') + BEGIN + WrError(1350); return False; + END + *Pos1='\0'; strmaxcpy(Reg,Pos1+1,255); Reg[strlen(Reg)-1]='\0'; + + if ((strlen(Reg)==2) AND (toupper(*Reg)=='A') AND (Reg[1]>='0') AND (Reg[1]<='1')) + BEGIN + AdrMode=Reg[1]-'0'; + DecodeDisp(Asc,UInt16,UInt16,&DispAcc,&OK); /* RMS 03: The offset is a full 16 bits */ + if (OK) + BEGIN + if (DispAcc==0) AdrMode+=6; + else if ((DispAcc>0) AND (DispAcc<256)) + BEGIN + AdrMode+=8; AdrVals[0]=DispAcc & 0xff; AdrCnt=1; + END + else + BEGIN + AdrMode+=12; + AdrVals[0]=DispAcc & 0xff; + AdrVals[1]=(DispAcc >> 8) & 0xff; + AdrCnt=2; + END + return True; + END + WrError(1510); /* RMS 08: Notify user there's a problem with the offset */ + return False; + END + else if (strcasecmp(Reg,"SB")==0) + BEGIN + DecodeDisp(Asc,UInt13,UInt16,&DispAcc,&OK); + if (OK) + BEGIN + if ((MayShort) AND (DispAcc<0x7ff)) + BEGIN + AdrMode=16+(DispAcc & 7); + AdrVals[0]=DispAcc >> 3; AdrCnt=1; + END + else if ((DispAcc>0) AND (DispAcc<256)) + BEGIN + AdrMode=10; AdrVals[0]=DispAcc & 0xff; AdrCnt=1; + END + else + BEGIN + AdrMode=14; + AdrVals[0]=DispAcc & 0xff; + AdrVals[1]=(DispAcc >> 8) & 0xff; + AdrCnt=2; + END + return True; + END + WrError(1510); /* RMS 08: Notify user there's a problem with the offset */ + return False; + END + else if (strcasecmp(Reg,"FB")==0) + BEGIN + DecodeDisp(Asc,SInt5,SInt8,&DispAcc,&OK); + if (OK) + BEGIN + AdrMode=11; AdrVals[0]=DispAcc & 0xff; AdrCnt=1; + return True; + END + WrError(1510); /* RMS 08: Notify user there's a problem with the offset */ + return False; + END + else + BEGIN + WrXError(1445,Reg); + return False; + END +END + +/*------------------------------------------------------------------------*/ + + static Boolean CheckFormat(char *FSet) +BEGIN + char *p; + + if (strcmp(Format," ")==0) + BEGIN + FormatCode=0; return True; + END + else + BEGIN + p=strchr(FSet,*Format); + if (p==Nil) WrError(1090); + else FormatCode=p-FSet+1; + return (p!=0); + END +END + + static Integer ImmVal(void) +BEGIN + if (OpSize==0) return (ShortInt)AdrVals[0]; + else return (((Integer)AdrVals[1]) << 8)+AdrVals[0]; +END + + static Boolean IsShort(Byte GenMode, Byte *SMode) +BEGIN + switch (GenMode) + BEGIN + case 0: *SMode=4; break; + case 1: *SMode=3; break; + case 10: *SMode=5; break; + case 11: *SMode=6; break; + case 15: *SMode=7; break; + default: return False; + END + return True; +END + +/*------------------------------------------------------------------------*/ + + static Boolean DecodePseudo(void) +BEGIN + return False; +END + + static void CopyAdr(void) +BEGIN + AdrType2=AdrType; + AdrMode2=AdrMode; + AdrCnt2=AdrCnt; + memcpy(AdrVals2,AdrVals,AdrCnt2); +END + + static void CodeGen(Byte GenCode,Byte Imm1Code,Byte Imm2Code) +BEGIN + if (AdrType==ModImm) + BEGIN + BAsmCode[0]=Imm1Code+OpSize; + BAsmCode[1]=Imm2Code+AdrMode2; + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + memcpy(BAsmCode+2+AdrCnt2,AdrVals,AdrCnt); + END + else + BEGIN + BAsmCode[0]=GenCode+OpSize; + BAsmCode[1]=(AdrMode << 4)+AdrMode2; + memcpy(BAsmCode+2,AdrVals,AdrCnt); + memcpy(BAsmCode+2+AdrCnt,AdrVals2,AdrCnt2); + END + CodeLen=2+AdrCnt+AdrCnt2; +END + + static Boolean CodeData(void) +BEGIN + Integer Num1; + int z; + Boolean OK; + Byte SMode; + + if (Memo("MOV")) + BEGIN + if (ArgCnt!=2) WrError(1110); + else if (CheckFormat("GSQZ")) + BEGIN + DecodeAdr(ArgStr[2],MModGen+MModSPRel); + if (AdrType!=ModNone) + BEGIN + CopyAdr(); DecodeAdr(ArgStr[1],MModGen+MModSPRel+MModImm); + if (AdrType!=ModNone) + if (OpSize==-1) WrError(1132); + else if ((OpSize!=0) AND (OpSize!=1)) WrError(1130); + else + BEGIN + if (FormatCode==0) + if ((AdrType2==ModSPRel) OR (AdrType==ModSPRel)) FormatCode=1; + else if ((OpSize==0) AND (AdrType==ModImm) AND (IsShort(AdrMode2,&SMode))) + FormatCode=(ImmVal()==0) ? 4 : 2; + else if ((AdrType==ModImm) AND (ImmVal()>=-8) AND (ImmVal()<=7)) FormatCode=3; + else if ((AdrType==ModImm) AND ((AdrMode2 & 14)==4)) FormatCode=2; + else if ((OpSize==0) AND (AdrType==ModGen) AND (IsShort(AdrMode,&SMode)) AND ((AdrMode2 & 14)==4) + AND ((AdrMode>=2) OR (Odd(AdrMode ^ AdrMode2)))) FormatCode=2; + else if ((OpSize==0) AND (AdrType==ModGen) AND (AdrMode<=1) AND (IsShort(AdrMode2,&SMode)) + AND ((AdrMode2>=2) OR (Odd(AdrMode ^ AdrMode2)))) FormatCode=2; + else if ((OpSize==0) AND (AdrMode2<=1) AND (AdrType==ModGen) AND (IsShort(AdrMode,&SMode)) + AND ((AdrMode>=2) OR (Odd(AdrMode ^ AdrMode2)))) FormatCode=2; + else FormatCode=1; + switch (FormatCode) + BEGIN + case 1: + if (AdrType==ModSPRel) + BEGIN + BAsmCode[0]=0x74+OpSize; + BAsmCode[1]=0xb0+AdrMode2; + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + memcpy(BAsmCode+2+AdrCnt2,AdrVals,AdrCnt); + CodeLen=2+AdrCnt+AdrCnt2; + END + else if (AdrType2==ModSPRel) + BEGIN + BAsmCode[0]=0x74+OpSize; + BAsmCode[1]=0x30+AdrMode; + memcpy(BAsmCode+2,AdrVals,AdrCnt); + memcpy(BAsmCode+2+AdrCnt,AdrVals2,AdrCnt2); + CodeLen=2+AdrCnt2+AdrCnt; + END + else CodeGen(0x72,0x74,0xc0); + break; + case 2: + if (AdrType==ModImm) + if (AdrType2!=ModGen) WrError(1350); + else if ((AdrMode2 & 14)==4) + BEGIN + BAsmCode[0]=0xe2-(OpSize << 6)+((AdrMode2 & 1) << 3); + memcpy(BAsmCode+1,AdrVals,AdrCnt); + CodeLen=1+AdrCnt; + END + else if (IsShort(AdrMode2,&SMode)) + if (OpSize!=0) WrError(1130); + else + BEGIN + BAsmCode[0]=0xc0+SMode; + memcpy(BAsmCode+1,AdrVals,AdrCnt); + memcpy(BAsmCode+1+AdrCnt,AdrVals2,AdrCnt2); + CodeLen=1+AdrCnt+AdrCnt2; + END + else WrError(1350); + else if ((AdrType==ModGen) AND (IsShort(AdrMode,&SMode))) + if (AdrType2!=ModGen) WrError(1350); + else if ((AdrMode2 & 14)==4) + if ((AdrMode<=1) AND (NOT Odd(AdrMode ^ AdrMode2))) WrError(1350); + else + BEGIN + if (SMode==3) SMode++; + BAsmCode[0]=0x30+((AdrMode2 & 1) << 2)+(SMode & 3); + memcpy(BAsmCode+1,AdrVals,AdrCnt); + CodeLen=1+AdrCnt; + END + else if ((AdrMode2 & 14)==0) + if ((AdrMode<=1) AND (NOT Odd(AdrMode ^ AdrMode2))) WrError(1350); + else + BEGIN + if (SMode==3) SMode++; + BAsmCode[0]=0x08+((AdrMode2 & 1) << 2)+(SMode & 3); + memcpy(BAsmCode+1,AdrVals,AdrCnt); + CodeLen=1+AdrCnt; + END + else if (((AdrMode & 14)!=0) OR (NOT IsShort(AdrMode2,&SMode))) WrError(1350); + else if ((AdrMode2<=1) AND (NOT Odd(AdrMode ^ AdrMode2))) WrError(1350); + else + BEGIN + if (SMode==3) SMode++; + BAsmCode[0]=0x00+((AdrMode & 1) << 2)+(SMode & 3); + memcpy(BAsmCode+1,AdrVals,AdrCnt2); + CodeLen=1+AdrCnt2; + END + else WrError(1350); + break; + case 3: + if (AdrType!=ModImm) WrError(1350); + else + BEGIN + Num1=ImmVal(); + if (ChkRange(Num1,-8,7)) + BEGIN + BAsmCode[0]=0xd8+OpSize; + BAsmCode[1]=(Num1 << 4)+AdrMode2; + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + CodeLen=2+AdrCnt2; + END + END + break; + case 4: + if (OpSize!=0) WrError(1130); + else if (AdrType!=ModImm) WrError(1350); + else if (NOT IsShort(AdrMode2,&SMode)) WrError(1350); + else + BEGIN + Num1=ImmVal(); + if (ChkRange(Num1,0,0)) + BEGIN + BAsmCode[0]=0xb0+SMode; + memcpy(BAsmCode+1,AdrVals2,AdrCnt2); + CodeLen=1+AdrCnt2; + END + END + break; + END + END; + END; + END + return True; + END + + if ((Memo("LDC")) OR (Memo("STC"))) + BEGIN + if (ArgCnt!=2) WrError(1110); + else if (CheckFormat("G")) + BEGIN + if (Memo("STC")) + BEGIN + strcpy(ArgStr[3],ArgStr[1]); + strcpy(ArgStr[1],ArgStr[2]); + strcpy(ArgStr[2],ArgStr[3]); + z=1; + END + else z=0; + if (strcasecmp(ArgStr[2],"PC")==0) + if (Memo("LDC")) WrError(1350); + else + BEGIN + DecodeAdr(ArgStr[1],MModGen+MModReg32+MModAReg32); + if (AdrType==ModAReg32) AdrMode=4; + if ((AdrType==ModGen) AND (AdrMode<6)) WrError(1350); + else + BEGIN + BAsmCode[0]=0x7c; BAsmCode[1]=0xc0+AdrMode; + memcpy(BAsmCode+2,AdrVals,AdrCnt); + CodeLen=2+AdrCnt; + END + END + else if (DecodeCReg(ArgStr[2],&SMode)) + BEGIN + SetOpSize(1); + DecodeAdr(ArgStr[1],MModGen+(Memo("LDC")?MModImm:0)); + if (AdrType==ModImm) + BEGIN + BAsmCode[0]=0xeb; BAsmCode[1]=SMode << 4; + memcpy(BAsmCode+2,AdrVals,AdrCnt); + CodeLen=2+AdrCnt; + END + else if (AdrType==ModGen) + BEGIN + BAsmCode[0]=0x7a+z; BAsmCode[1]=0x80+(SMode << 4)+AdrMode; + memcpy(BAsmCode+2,AdrVals,AdrCnt); + CodeLen=2+AdrCnt; + END + END + END + return True; + END + + if ((Memo("LDCTX")) OR (Memo("STCTX"))) + BEGIN + if (ArgCnt!=2) WrError(1110); + else if (*AttrPart!='\0') WrError(1100); + else + BEGIN + DecodeAdr(ArgStr[1],MModGen); + if (AdrType==ModGen) + if (AdrMode!=15) WrError(1350); + else + BEGIN + memcpy(BAsmCode+2,AdrVals,AdrCnt); + DecodeAdr(ArgStr[2],MModAbs20); + if (AdrType==ModAbs20) + BEGIN + memcpy(BAsmCode+4,AdrVals,AdrCnt); + BAsmCode[0]=0x7c+Ord(Memo("STCTX")); + BAsmCode[1]=0xf0; + CodeLen=7; + END + END + END + return True; + END + + if ((Memo("LDE")) OR (Memo("STE"))) + BEGIN + if (ArgCnt!=2) WrError(1110); + else if (CheckFormat("G")) + BEGIN + if (Memo("LDE")) + BEGIN + strcpy(ArgStr[3],ArgStr[1]); + strcpy(ArgStr[1],ArgStr[2]); + strcpy(ArgStr[2],ArgStr[3]); + z=1; + END + else z=0; + DecodeAdr(ArgStr[1],MModGen); + if (AdrType!=ModNone) + if (OpSize==-1) WrError(1132); + else if (OpSize>1) WrError(1130); + else + BEGIN + CopyAdr(); DecodeAdr(ArgStr[2],MModAbs20+MModDisp20+MModIReg32); + if (AdrType!=ModNone) + BEGIN + BAsmCode[0]=0x74+OpSize; + BAsmCode[1]=(z << 7)+AdrMode2; + switch (AdrType) + BEGIN + case ModDisp20: BAsmCode[1]+=0x10; break; + case ModIReg32: BAsmCode[1]+=0x20; break; + END + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + memcpy(BAsmCode+2+AdrCnt2,AdrVals,AdrCnt); + CodeLen=2+AdrCnt2+AdrCnt; + END + END + END + return True; + END + + if (Memo("MOVA")) + BEGIN + if (ArgCnt!=2) WrError(1110); + else if (CheckFormat("G")) + BEGIN + DecodeAdr(ArgStr[1],MModGen); + if (AdrType!=ModNone) + if (AdrMode<8) WrError(1350); + else + BEGIN + CopyAdr(); DecodeAdr(ArgStr[2],MModGen); + if (AdrType!=ModNone) + if (AdrMode>5) WrError(1350); + else + BEGIN + BAsmCode[0]=0xeb; + BAsmCode[1]=(AdrMode << 4)+AdrMode2; + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + CodeLen=2+AdrCnt2; + END + END + END + return True; + END + + for (z=0; z0) WrError(1130); + else if (CheckFormat("G")) + BEGIN + OK=True; Num1=0; + if (strcasecmp(ArgStr[2],"R0L")==0); + else if (strcasecmp(ArgStr[1],"R0L")==0) Num1=1; + else OK=False; + if (NOT OK) WrError(1350); + else + BEGIN + DecodeAdr(ArgStr[Num1+1],MModGen); + if (AdrType!=ModNone) + if (((AdrMode & 14)==4) OR ((AdrMode==0) AND (Num1==1))) WrError(1350); + else + BEGIN + BAsmCode[0]=0x7c; BAsmCode[1]=(Num1 << 7)+(z << 4)+AdrMode; + memcpy(BAsmCode+2,AdrVals,AdrCnt); + CodeLen=2+AdrCnt; + END + END + END + return True; + END + + if ((Memo("PUSH")) OR (Memo("POP"))) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (CheckFormat("GS")) + BEGIN + z=Ord(Memo("POP")); + DecodeAdr(ArgStr[1],MModGen+((Memo("PUSH"))?MModImm:0)); + if (AdrType!=ModNone) + if (OpSize==-1) WrError(1132); + else if (OpSize>1) WrError(1130); + else + BEGIN + if (FormatCode==0) + if ((AdrType!=ModGen)) FormatCode=1; + else if ((OpSize==0) AND (AdrMode<2)) FormatCode=2; + else if ((OpSize==1) AND ((AdrMode & 14)==4)) FormatCode=2; + else FormatCode=1; + switch (FormatCode) + BEGIN + case 1: + if (AdrType==ModImm) + BEGIN + BAsmCode[0]=0x7c+OpSize; + BAsmCode[1]=0xe2; + END + else + BEGIN + BAsmCode[0]=0x74+OpSize; + BAsmCode[1]=0x40+(z*0x90)+AdrMode; + END + memcpy(BAsmCode+2,AdrVals,AdrCnt); + CodeLen=2+AdrCnt; + break; + case 2: + if (AdrType!=ModGen) WrError(1350); + else if ((OpSize==0) AND (AdrMode<2)) + BEGIN + BAsmCode[0]=0x82+(AdrMode << 3)+(z << 4); + CodeLen=1; + END + else if ((OpSize==1) AND ((AdrMode & 14)==4)) + BEGIN + BAsmCode[0]=0xc2+((AdrMode & 1) << 3)+(z << 4); + CodeLen=1; + END + else WrError(1350); + break; + END + END + END + return True; + END + + if ((Memo("PUSHC")) OR (Memo("POPC"))) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (CheckFormat("G")) + if (DecodeCReg(ArgStr[1],&SMode)) + BEGIN + BAsmCode[0]=0xeb; + BAsmCode[1]=0x02+Ord(Memo("POPC"))+(SMode << 4); + CodeLen=2; + END + return True; + END + + if ((Memo("PUSHM")) OR (Memo("POPM"))) + BEGIN + if (ArgCnt<1) WrError(1110); + else + BEGIN + BAsmCode[1]=0; OK=True; z=1; + while ((OK) AND (z<=ArgCnt)) + BEGIN + OK=DecodeReg(ArgStr[z],&SMode); + if (OK) + BEGIN + BAsmCode[1]|=(1<<((Memo("POPM"))?SMode:7-SMode)); + z++; + END + END + if (NOT OK) WrXError(1440,ArgStr[z]); + else + BEGIN + BAsmCode[0]=0xec+Ord(Memo("POPM")); + CodeLen=2; + END + END + return True; + END + + if (Memo("PUSHA")) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (CheckFormat("G")) + BEGIN + DecodeAdr(ArgStr[1],MModGen); + if (AdrType!=ModNone) + if (AdrMode<8) WrError(1350); + else + BEGIN + BAsmCode[0]=0x7d; + BAsmCode[1]=0x90+AdrMode; + memcpy(BAsmCode+2,AdrVals,AdrCnt); + CodeLen=2+AdrCnt; + END + END + return True; + END + + if (Memo("XCHG")) + BEGIN + if (ArgCnt!=2) WrError(1110); + else if (CheckFormat("G")) + BEGIN + DecodeAdr(ArgStr[1],MModGen); + if (AdrType!=ModNone) + BEGIN + CopyAdr(); DecodeAdr(ArgStr[2],MModGen); + if (AdrType!=ModNone) + if (OpSize==-1) WrError(1132); + else if (OpSize>1) WrError(1130); + else if (AdrMode<4) + BEGIN + BAsmCode[0]=0x7a+OpSize; + BAsmCode[1]=(AdrMode << 4)+AdrMode2; + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + CodeLen=2+AdrCnt2; + END + else if (AdrMode2<4) + BEGIN + BAsmCode[0]=0x7a+OpSize; + BAsmCode[1]=(AdrMode2 << 4)+AdrMode; + memcpy(BAsmCode+2,AdrVals,AdrCnt); + CodeLen=2+AdrCnt; + END + else WrError(1350); + END + END + return True; + END + + if ((Memo("STZ")) OR (Memo("STNZ"))) + BEGIN + if (ArgCnt!=2) WrError(1110); + else if (CheckFormat("G")) + BEGIN + if (OpSize==-1) OpSize++; + DecodeAdr(ArgStr[2],MModGen); + if (AdrType!=ModNone) + if (NOT IsShort(AdrMode,&SMode)) WrError(1350); + else + BEGIN + CopyAdr(); DecodeAdr(ArgStr[1],MModImm); + if (AdrType!=ModNone) + BEGIN + BAsmCode[0]=0xc8+(Ord(Memo("STNZ")) << 3)+SMode; + BAsmCode[1]=AdrVals[0]; + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + CodeLen=2+AdrCnt2; + END + END + END + return True; + END + + if ((Memo("STZX"))) + BEGIN + if (ArgCnt!=3) WrError(1110); + else if (CheckFormat("G")) + BEGIN + if (OpSize==-1) OpSize++; + DecodeAdr(ArgStr[3],MModGen); + if (AdrType!=ModNone) + if (NOT IsShort(AdrMode,&SMode)) WrError(1350); + else + BEGIN + CopyAdr(); DecodeAdr(ArgStr[1],MModImm); + if (AdrType!=ModNone) + BEGIN + Num1=AdrVals[0]; DecodeAdr(ArgStr[2],MModImm); + if (AdrType!=ModNone) + BEGIN + BAsmCode[0]=0xd8+SMode; + BAsmCode[1]=Num1; + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + BAsmCode[2+AdrCnt2]=AdrVals[0]; + CodeLen=3+AdrCnt2; + END + END + END + END + return True; + END + + return False; +END + + static void MakeCode_M16C(void) +BEGIN + Integer Num1; + int z; + char *p; + LongInt AdrLong,Diff; + Boolean OK,MayShort; + Byte SMode; + ShortInt OpSize2; + + OpSize=(-1); + + /* zu ignorierendes */ + + if (Memo("")) return; + + /* Formatangabe abspalten */ + + switch (AttrSplit) + BEGIN + case '.': + p=strchr(AttrPart,':'); + if (p!=Nil) + BEGIN + if (p1) WrError(1130); + else + BEGIN + AdrLong=ImmVal(); + if (FormatCode==0) + if ((AdrLong>=-8) AND (AdrLong<=7)) FormatCode=2; + else FormatCode=1; + switch (FormatCode) + BEGIN + case 1: + BAsmCode[0]=0x7c+OpSize; + BAsmCode[1]=0xeb; + memcpy(BAsmCode+2,AdrVals,AdrCnt); + CodeLen=2+AdrCnt; + break; + case 2: + if (ChkRange(AdrLong,-8,7)) + BEGIN + BAsmCode[0]=0x7d; + BAsmCode[1]=0xb0+(AdrLong & 15); + CodeLen=2; + END + break; + END + END + END + END + else if (CheckFormat("GQS")) + BEGIN + DecodeAdr(ArgStr[2],MModGen); + if (AdrType!=ModNone) + BEGIN + CopyAdr(); + DecodeAdr(ArgStr[1],MModImm+MModGen); + if (AdrType!=ModNone) + if (OpSize==-1) WrError(1132); + else if ((OpSize!=0) AND (OpSize!=1)) WrError(1130); + else + BEGIN + if (FormatCode==0) + if (AdrType==ModImm) + if ((ImmVal()>=-8) AND (ImmVal()<=7)) FormatCode=2; + else if ((IsShort(AdrMode2,&SMode)) AND (OpSize==0)) FormatCode=3; + else FormatCode=1; + else + if ((OpSize==0) AND (IsShort(AdrMode,&SMode)) AND (AdrMode2<=1) AND + ((AdrMode>1) OR (Odd(AdrMode ^ AdrMode2)))) FormatCode=3; + else FormatCode=1; + switch (FormatCode) + BEGIN + case 1: + CodeGen(0xa0,0x76,0x40); + break; + case 2: + if (AdrType!=ModImm) WrError(1350); + else + BEGIN + Num1=ImmVal(); + if (ChkRange(Num1,-8,7)) + BEGIN + BAsmCode[0]=0xc8+OpSize; + BAsmCode[1]=(Num1 << 4)+AdrMode2; + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + CodeLen=2+AdrCnt2; + END + END + break; + case 3: + if (OpSize!=0) WrError(1130); + else if (NOT IsShort(AdrMode2,&SMode)) WrError(1350); + else if (AdrType==ModImm) + BEGIN + BAsmCode[0]=0x80+SMode; BAsmCode[1]=AdrVals[0]; + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + CodeLen=2+AdrCnt2; + END + else if ((AdrMode2>=2) OR (NOT IsShort(AdrMode,&SMode))) WrError(1350); + else if ((AdrMode<2) AND (NOT Odd(AdrMode ^ AdrMode2))) WrError(1350); + else + BEGIN + if (SMode==3) SMode++; + BAsmCode[0]=0x20+((AdrMode2 & 1) << 2)+(SMode & 3); /* RMS 05: Just like #04 */ + memcpy(BAsmCode+1,AdrVals,AdrCnt); + CodeLen=1+AdrCnt; + END + break; + END + END + END + END + return; + END + + if (Memo("CMP")) + BEGIN + if (ArgCnt!=2) WrError(1110); + else if (CheckFormat("GQS")) + BEGIN + DecodeAdr(ArgStr[2],MModGen); + if (AdrType!=ModNone) + BEGIN + CopyAdr(); DecodeAdr(ArgStr[1],MModImm+MModGen); + if (AdrType!=ModNone) + if (OpSize==-1) WrError(1132); + else if ((OpSize!=0) AND (OpSize!=1)) WrError(1130); + else + BEGIN + if (FormatCode==0) + if (AdrType==ModImm) + if ((ImmVal()>=-8) AND (ImmVal()<=7)) FormatCode=2; + else if ((IsShort(AdrMode2,&SMode)) AND (OpSize==0)) FormatCode=3; + else FormatCode=1; + else + if ((OpSize==0) AND (IsShort(AdrMode,&SMode)) AND (AdrMode2<=1) AND + ((AdrMode>1) OR (Odd(AdrMode ^ AdrMode2)))) FormatCode=3; + else FormatCode=1; + switch (FormatCode) + BEGIN + case 1: + CodeGen(0xc0,0x76,0x80); + break; + case 2: + if (AdrType!=ModImm) WrError(1350); + else + BEGIN + Num1=ImmVal(); + if (ChkRange(Num1,-8,7)) + BEGIN + BAsmCode[0]=0xd0+OpSize; + BAsmCode[1]=(Num1 << 4)+AdrMode2; + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + CodeLen=2+AdrCnt2; + END + END + break; + case 3: + if (OpSize!=0) WrError(1130); + else if (NOT IsShort(AdrMode2,&SMode)) WrError(1350); + else if (AdrType==ModImm) + BEGIN + BAsmCode[0]=0xe0+SMode; BAsmCode[1]=AdrVals[0]; + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + CodeLen=2+AdrCnt2; + END + else if ((AdrMode2>=2) OR (NOT IsShort(AdrMode,&SMode))) WrError(1350); + else if ((AdrMode<2) AND (NOT Odd(AdrMode ^ AdrMode2))) WrError(1350); + else + BEGIN + if (SMode==3) SMode++; + BAsmCode[0]=0x38+((AdrMode2 & 1) << 2)+(SMode & 3); /* RMS 04: destination reg is bit 2! */ + memcpy(BAsmCode+1,AdrVals,AdrCnt); + CodeLen=1+AdrCnt; + END + break; + END + END + END + END + return; + END + + if (Memo("SUB")) + BEGIN + if (ArgCnt!=2) WrError(1110); + else if (CheckFormat("GQS")) + BEGIN + DecodeAdr(ArgStr[2],MModGen); + if (AdrType!=ModNone) + BEGIN + CopyAdr(); DecodeAdr(ArgStr[1],MModImm+MModGen); + if (AdrType!=ModNone) + if (OpSize==-1) WrError(1132); + else if ((OpSize!=0) AND (OpSize!=1)) WrError(1130); + else + BEGIN + if (FormatCode==0) + if (AdrType==ModImm) + if ((ImmVal()>=-7) AND (ImmVal()<=8)) FormatCode=2; + else if ((IsShort(AdrMode2,&SMode)) AND (OpSize==0)) FormatCode=3; + else FormatCode=1; + else + if ((OpSize==0) AND (IsShort(AdrMode,&SMode)) AND (AdrMode2<=1) AND + ((AdrMode>1) OR (Odd(AdrMode ^ AdrMode2)))) FormatCode=3; + else FormatCode=1; + switch (FormatCode) + BEGIN + case 1: + CodeGen(0xa8,0x76,0x50); + break; + case 2: + if (AdrType!=ModImm) WrError(1350); + else + BEGIN + Num1=ImmVal(); + if (ChkRange(Num1,-7,8)) + BEGIN + BAsmCode[0]=0xc8+OpSize; + BAsmCode[1]=((-Num1) << 4)+AdrMode2; + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + CodeLen=2+AdrCnt2; + END + END + break; + case 3: + if (OpSize!=0) WrError(1130); + else if (NOT IsShort(AdrMode2,&SMode)) WrError(1350); + else if (AdrType==ModImm) + BEGIN + BAsmCode[0]=0x88+SMode; BAsmCode[1]=AdrVals[0]; + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + CodeLen=2+AdrCnt2; + END + else if ((AdrMode2>=2) OR (NOT IsShort(AdrMode,&SMode))) WrError(1350); + else if ((AdrMode<2) AND (NOT Odd(AdrMode ^ AdrMode2))) WrError(1350); + else + BEGIN + if (SMode==3) SMode++; + BAsmCode[0]=0x28+((AdrMode2 & 1) << 2)+(SMode & 3); /* RMS 06: just like RMS 04 */ + memcpy(BAsmCode+1,AdrVals,AdrCnt); + CodeLen=1+AdrCnt; + END + break; + END + END + END + END + return; + END + + for (z=0; z=3) AND (AdrMode<=5))) WrError(1350); + else + BEGIN + BAsmCode[0]=0x7c; + BAsmCode[1]=0x60+AdrMode; + memcpy(BAsmCode+2,AdrVals,AdrCnt); + CodeLen=2+AdrCnt; + END + else if (OpSize==1) + if (AdrMode!=0) WrError(1350); + else + BEGIN + BAsmCode[0]=0x7c; BAsmCode[1]=0xf3; + CodeLen=2; + END + else WrError(1130); + END + return; + END + + if (Memo("NOT")) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (CheckFormat("GS")) + BEGIN + DecodeAdr(ArgStr[1],MModGen); + if (AdrType!=ModNone) + if (OpSize==-1) WrError(1132); + else if (OpSize>1) WrError(1130); + else + BEGIN + if (FormatCode==0) + if ((OpSize==0) AND (IsShort(AdrMode,&SMode))) FormatCode=2; + else FormatCode=1; + switch (FormatCode) + BEGIN + case 1: + BAsmCode[0]=0x74+OpSize; + BAsmCode[1]=0x70+AdrMode; + memcpy(BAsmCode+2,AdrVals,AdrCnt); + CodeLen=2+AdrCnt; + break; + case 2: + if (OpSize!=0) WrError(1130); + else if (NOT IsShort(AdrMode,&SMode)) WrError(1350); + else + BEGIN + BAsmCode[0]=0xb8+SMode; + memcpy(BAsmCode+1,AdrVals,AdrCnt); + CodeLen=1+AdrCnt; + END + break; + END + END + END + return; + END + + /* Logik*/ + + if ((Memo("AND")) OR (Memo("OR"))) + BEGIN + z=Ord(Memo("OR")); + if (ArgCnt!=2) WrError(1110); + else if (CheckFormat("GS")) /* RMS 01: The format codes are G and S, not G and Q */ + BEGIN + DecodeAdr(ArgStr[2],MModGen); + if (AdrType!=ModNone) + BEGIN + CopyAdr(); DecodeAdr(ArgStr[1],MModGen+MModImm); + if (AdrType!=ModNone) + if (OpSize==-1) WrError(1132); + else if (OpSize>1) WrError(1130); + else + BEGIN + if (FormatCode==0) + if (AdrType==ModImm) + if ((OpSize==0) AND (IsShort(AdrMode2,&SMode))) FormatCode=2; + else FormatCode=1; + else + if ((AdrMode2<=1) AND (IsShort(AdrMode,&SMode)) AND ((AdrMode>1) OR Odd(AdrMode ^ AdrMode2))) FormatCode=2; + else FormatCode=1; + switch (FormatCode) + BEGIN + case 1: + CodeGen(0x90+(z << 3),0x76,0x20+(z << 4)); + break; + case 2: + if (OpSize!=0) WrError(1130); + else if (AdrType==ModImm) + if (NOT IsShort(AdrMode2,&SMode)) WrError(1350); + else + BEGIN + BAsmCode[0]=0x90+(z << 3)+SMode; + BAsmCode[1]=ImmVal(); + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + CodeLen=2+AdrCnt2; + END + else if ((NOT IsShort(AdrMode,&SMode)) OR (AdrMode2>1)) WrError(1350); + else if ((AdrMode<=1) AND (NOT Odd(AdrMode ^ AdrMode2))) WrError(1350); + else + BEGIN + if (SMode==3) SMode++; + BAsmCode[0]=0x10+(z << 3)+((AdrMode2 & 1) << 2)+(SMode & 3); + memcpy(BAsmCode+1,AdrVals,AdrCnt); + CodeLen=1+AdrCnt; + END + END + END + END + END + return; + END + + if (Memo("ROT")) + BEGIN + if (ArgCnt!=2) WrError(1110); + else if (CheckFormat("G")) + BEGIN + DecodeAdr(ArgStr[2],MModGen); + if (AdrType!=ModNone) + if (OpSize==-1) WrError(1132); + else if (OpSize>1) WrError(1130); + else + BEGIN + OpSize2=OpSize; OpSize=0; CopyAdr(); + DecodeAdr(ArgStr[1],MModGen+MModImm); + if (AdrType==ModGen) + if (AdrMode!=3) WrError(1350); + else if (AdrMode2+2*OpSize2==3) WrError(1350); + else + BEGIN + BAsmCode[0]=0x74+OpSize2; + BAsmCode[1]=0x60+AdrMode2; + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + CodeLen=2+AdrCnt2; + END + else if (AdrType==ModImm) + BEGIN + Num1=ImmVal(); + if (Num1==0) WrError(1315); + else if (ChkRange(Num1,-8,8)) + BEGIN + if (Num1>0) Num1--; else Num1=(-9)-Num1; + BAsmCode[0]=0xe0+OpSize2; + BAsmCode[1]=(Num1 << 4)+AdrMode2; + memcpy(BAsmCode+2,AdrVals2,AdrCnt); + CodeLen=2+AdrCnt2; + END + END + END + END + return; + END + + if ((Memo("SHA")) OR (Memo("SHL"))) + BEGIN + if (ArgCnt!=2) WrError(1110); + else if (CheckFormat("G")) + BEGIN + z=Ord(Memo("SHA")); + DecodeAdr(ArgStr[2],MModGen+MModReg32); + if (AdrType!=ModNone) + if (OpSize==-1) WrError(1132); + else if ((OpSize>2) OR ((OpSize==2) AND (AdrType==ModGen))) WrError(1130); + else + BEGIN + CopyAdr(); OpSize2=OpSize; OpSize=0; + DecodeAdr(ArgStr[1],MModImm+MModGen); + if (AdrType==ModGen) + if (AdrMode!=3) WrError(1350); + else if (AdrMode2*2+OpSize2==3) WrError(1350); + else + BEGIN + if (OpSize2==2) + BEGIN + BAsmCode[0]=0xeb; + BAsmCode[1]=0x01+(AdrMode2 << 4)+(z << 5); + END + else + BEGIN + BAsmCode[0]=0x74+OpSize2; + BAsmCode[1]=0xe0+(z << 4)+AdrMode2; + END + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + CodeLen=2+AdrCnt2; + END + else if (AdrType==ModImm) + BEGIN + Num1=ImmVal(); + if (Num1==0) WrError(1315); + else if (ChkRange(Num1,-8,8)) + BEGIN + if (Num1>0) Num1--; else Num1=(-9)-Num1; + if (OpSize2==2) + BEGIN + BAsmCode[0]=0xeb; + BAsmCode[1]=0x80+(AdrMode2 << 4)+(z << 5)+(Num1 & 15); + END + else + BEGIN + BAsmCode[0]=0xe8+(z << 3)+OpSize2; + BAsmCode[1]=(Num1 << 4)+AdrMode2; + END + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + CodeLen=2+AdrCnt2; + END + END + END + END + return; + END + + /* Bitoperationen */ + + for (z=0; z=16) + BEGIN + BAsmCode[0]=0x40+((BitOrders[z].Code-8) << 3)+(AdrMode & 7); + BAsmCode[1]=AdrVals[0]; + CodeLen=2; + END + else + BEGIN + BAsmCode[0]=0x7e; + BAsmCode[1]=(BitOrders[z].Code << 4)+AdrMode; + memcpy(BAsmCode+2,AdrVals,AdrCnt); + CodeLen=2+AdrCnt; + END + return; + END + + if (strncmp(OpPart,"BM",2)==0) + for (z=0; z=4) AND (z<12)) z^=12; + if (z>=8) z+=0xf0; + BAsmCode[2+AdrCnt]=z; + CodeLen=3+AdrCnt; + END + return; + END + + if ((Memo("FCLR")) OR (Memo("FSET"))) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (strlen(ArgStr[1])!=1) WrError(1350); + else + BEGIN + p=strchr(Flags,toupper(*ArgStr[1])); + if (p==Nil) WrXError(1440,ArgStr[1]); + else + BEGIN + BAsmCode[0]=0xeb; + BAsmCode[1]=0x04+Ord(Memo("FCLR"))+((p-Flags) << 4); + CodeLen=2; + END + END + return; + END + + /* Spruenge */ + + if (Memo("JMP")) + BEGIN + if (ArgCnt!=1) WrError(1110); + else + BEGIN + FirstPassUnknown=False; /* RMS 12: Mod to allow JMP.S to work */ + AdrLong=EvalIntExpression(ArgStr[1],UInt20,&OK); + Diff=AdrLong-EProgCounter(); + +/* RMS 12: Repaired JMP.S forward-label as follows: + + If it's an unknown symbol, make PC+2 the "safe" value, otherwise + the user will get OUT OF RANGE errors on every attempt to use JMP.S + Since the instruction can only branch forward, and AS stuffs the PC + back for a "temp" forward reference value, the range-checking will + always fail. + + One side-effect also is that for auto-determination purposes, one + fewer pass is needed. Before, the first pass would signal JMP.B, + then once the forward reference is known, it'd signal JMP.S, which + would cause a "phase error" forcing another pass. +*/ + if ( (FirstPassUnknown) AND (Diff == 0) ) + Diff = 2; + + if (OpSize==-1) + BEGIN + if ((Diff>=2) AND (Diff<=9)) OpSize=4; + else if ((Diff>=-127) AND (Diff<=128)) OpSize=0; + else if ((Diff>=-32767) AND (Diff<=32768)) OpSize=1; + else OpSize=7; + END +/* + The following code is to deal with a silicon bug in the first generation of + M16C CPUs (the so-called M16C/60 group). It has been observed that this + silicon bug has been fixed as of the M16C/61, so we disable JMP.S promotion + to JMP.B when the target crosses a 64k boundary for those CPUs. + + Since M16C is a "generic" specification, we do JMP.S promotion for that + CPU specification, as follows: + + RMS 11: According to Mitsubishi App Note M16C-06-9612 + JMP.S cannot cross a 64k boundary.. so trim up to JMP.B + + It is admittedly a very low likelihood of occurrence [JMP.S has only 8 + possible targets, being a 3 bit "jump addressing mode"], but since the + occurrence of this bug could cause such evil debugging issues, I have + taken the liberty of addressing it in the assembler. Heck, it's JUST one + extra byte. One byte's worth the peace of mind, isn't it? :) + +*/ + if (!( ( strcmp(MomCPUIdent,"M16C") ) && ( strcmp(MomCPUIdent,"M30600M8")))) + if (OpSize == 4) + BEGIN + if ( (AdrLong & 0x0f0000) != (EProgCounter() & 0x0f0000) ) + OpSize = 0; + END /* NOTE! This not an ASX bug, but rather in the CPU!! */ + switch (OpSize) + BEGIN + case 4: + if (((Diff<2) OR (Diff>9)) AND (NOT SymbolQuestionable) ) WrError(1370); + else + BEGIN + BAsmCode[0]=0x60+((Diff-2) & 7); CodeLen=1; + END + break; + case 0: + if (((Diff<-127) OR (Diff>128)) AND (NOT SymbolQuestionable)) WrError(1370); + else + BEGIN + BAsmCode[0]=0xfe; + BAsmCode[1]=(Diff-1) & 0xff; + CodeLen=2; + END + break; + case 1: + if (((Diff<-32767) OR (Diff>32768)) AND (NOT SymbolQuestionable)) WrError(1370); + else + BEGIN + BAsmCode[0]=0xf4; Diff--; + BAsmCode[1]=Diff & 0xff; + BAsmCode[2]=(Diff >> 8) & 0xff; + CodeLen=3; + END + break; + case 7: + BAsmCode[0]=0xfc; + BAsmCode[1]=AdrLong & 0xff; + BAsmCode[2]=(AdrLong >> 8) & 0xff; + BAsmCode[3]=(AdrLong >> 16) & 0xff; + CodeLen=4; + break; + default: + WrError(1130); + END + END + return; + END + + if (Memo("JSR")) + BEGIN + if (ArgCnt!=1) WrError(1110); + else + BEGIN + AdrLong=EvalIntExpression(ArgStr[1],UInt20,&OK); + Diff=AdrLong-EProgCounter(); + if (OpSize==-1) + BEGIN + if ((Diff>=-32767) AND (Diff<=32768)) OpSize=1; + else OpSize=7; + END + switch (OpSize) + BEGIN + case 1: + if (((Diff<-32767) OR (Diff>32768)) AND (NOT SymbolQuestionable)) WrError(1370); + else + BEGIN + BAsmCode[0]=0xf5; Diff--; + BAsmCode[1]=Diff & 0xff; + BAsmCode[2]=(Diff >> 8) & 0xff; + CodeLen=3; + END + break; + case 7: + BAsmCode[0]=0xfd; + BAsmCode[1]=AdrLong & 0xff; + BAsmCode[2]=(AdrLong >> 8) & 0xff; + BAsmCode[3]=(AdrLong >> 16) & 0xff; + CodeLen=4; + break; + default: + WrError(1130); + END + END + return; + END + + if ((Memo("JMPI")) OR (Memo("JSRI"))) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (CheckFormat("G")) + BEGIN + if (OpSize==7) OpSize=2; + DecodeAdr(ArgStr[1],MModGen+MModDisp20+MModReg32+MModAReg32); + if ((AdrType==ModGen) AND ((AdrMode & 14)==12)) + AdrVals[AdrCnt++]=0; + if ((AdrType==ModGen) AND ((AdrMode & 14)==4)) + if (OpSize==-1) OpSize=1; + else if (OpSize!=1) + BEGIN + AdrType=ModNone; WrError(1131); + END + if (AdrType==ModAReg32) AdrMode=4; + if (AdrType!=ModNone) + if (OpSize==-1) WrError(1132); + else if ((OpSize!=1) AND (OpSize!=2)) WrError(1130); + else + BEGIN + BAsmCode[0]=0x7d; + BAsmCode[1]=(Ord(Memo("JSRI")) << 4)+(Ord(OpSize==1) << 5)+AdrMode; + memcpy(BAsmCode+2,AdrVals,AdrCnt); + CodeLen=2+AdrCnt; + END + END + return; + END + + if ((Memo("JMPS")) OR (Memo("JSRS"))) + BEGIN + if (ArgCnt!=1) WrError(1110); + else + BEGIN + OpSize=0; + FirstPassUnknown=False; + DecodeAdr(ArgStr[1],MModImm); + if ((FirstPassUnknown) AND (AdrVals[0]<18)) AdrVals[0]=18; + if (AdrType!=ModNone) + if (AdrVals[0]<18) WrError(1315); + else + BEGIN + BAsmCode[0]=0xee + Ord(Memo("JSRS")); /* ANSI :-O */ + BAsmCode[1]=AdrVals[0]; + CodeLen=2; + END + END + return; + END + + if (*OpPart=='J') + for (z=0; z=8); + if (ArgCnt!=1) WrError(1110); + else if (*AttrPart!='\0') WrError(1100); + else if (strcmp(Format," ")!=0) WrError(1090); + else + BEGIN + AdrLong=EvalIntExpression(ArgStr[1],UInt20,&OK)-(EProgCounter()+Num1); + if (OK) + if ((NOT SymbolQuestionable) AND ((AdrLong>127) OR (AdrLong<-128))) WrError(1370); + else if (Conditions[z].Code>=8) + BEGIN + BAsmCode[0]=0x7d; BAsmCode[1]=0xc0+Conditions[z].Code; + BAsmCode[2]=AdrLong & 0xff; + CodeLen=3; + END + else + BEGIN + BAsmCode[0]=0x68+Conditions[z].Code; BAsmCode[1]=AdrLong & 0xff; + CodeLen=2; + END + END + return; + END + + if ((Memo("ADJNZ")) OR (Memo("SBJNZ"))) + BEGIN + if (ArgCnt!=3) WrError(1110); + else if (CheckFormat("G")) + BEGIN + DecodeAdr(ArgStr[2],MModGen); + if (AdrType!=ModNone) + if (OpSize==-1) WrError(1132); + else if (OpSize>1) WrError(1130); + else + BEGIN + CopyAdr(); OpSize2=OpSize; OpSize=0; + FirstPassUnknown=False; + DecodeAdr(ArgStr[1],MModImm); Num1=ImmVal(); + if (FirstPassUnknown) Num1=0; + if (Memo("SBJNZ")) Num1=(-Num1); + if (ChkRange(Num1,-8,7)) + BEGIN + AdrLong=EvalIntExpression(ArgStr[3],UInt20,&OK)-(EProgCounter()+2); + if (OK) + if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT SymbolQuestionable)) WrError(1370); + else + BEGIN + BAsmCode[0]=0xf8+OpSize2; + BAsmCode[1]=(Num1 << 4)+AdrMode2; + memcpy(BAsmCode+2,AdrVals2,AdrCnt2); + BAsmCode[2+AdrCnt2]=AdrLong & 0xff; + CodeLen=3+AdrCnt2; + END + END + END + END + return; + END + + if (Memo("INT")) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (*AttrPart!='\0') WrError(1100); + else if (*ArgStr[1]!='#') WrError(1350); + else + BEGIN + BAsmCode[1]=0xc0+EvalIntExpression(ArgStr[1]+1,UInt6,&OK); + if (OK) + BEGIN + BAsmCode[0]=0xeb; CodeLen=2; + END + END + return; + END + + /* Miszellaneen */ + + if (Memo("ENTER")) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (*AttrPart!='\0') WrError(1100); + else if (*ArgStr[1]!='#') WrError(1350); + else + BEGIN + BAsmCode[2]=EvalIntExpression(ArgStr[1]+1,UInt8,&OK); + if (OK) + BEGIN + BAsmCode[0]=0x7c; BAsmCode[1]=0xf2; CodeLen=3; + END + END + return; + END + + if (Memo("LDINTB")) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (*AttrPart!='\0') WrError(1100); + else if (*ArgStr[1]!='#') WrError(1350); + else + BEGIN + AdrLong=EvalIntExpression(ArgStr[1]+1,UInt20,&OK); + if (OK) + BEGIN + BAsmCode[0]=0xeb; BAsmCode[1]=0x20; + BAsmCode[2]=(AdrLong >> 16) & 0xff; BAsmCode[3]=0; + BAsmCode[4]=0xeb; BAsmCode[5]=0x10; + BAsmCode[7]=(AdrLong >> 8) & 0xff; BAsmCode[6]=AdrLong & 0xff; /* RMS 07: needs to be LSB, MSB order */ + CodeLen=8; + END + END + return; + END + + if (Memo("LDIPL")) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (*AttrPart!='\0') WrError(1100); + else if (*ArgStr[1]!='#') WrError(1350); + else + BEGIN + BAsmCode[1]=0xa0+EvalIntExpression(ArgStr[1]+1,UInt3,&OK); + if (OK) + BEGIN + BAsmCode[0]=0x7d; CodeLen=2; + END + END + return; + END + + WrXError(1200,OpPart); +END + + static Boolean IsDef_M16C(void) +BEGIN + return False; +END + + static void SwitchFrom_M16C(void) +BEGIN + DeinitFields(); +END + + static void SwitchTo_M16C(void) +BEGIN + TurnWords=True; ConstMode=ConstModeIntel; SetIsOccupied=False; + + PCSymbol="$"; HeaderID=0x14; NOPCode=0x04; + DivideChars=","; HasAttrs=True; AttrChars=".:"; + + ValidSegs=1<