aboutsummaryrefslogtreecommitdiffstats
path: root/codem16c.c
diff options
context:
space:
mode:
Diffstat (limited to 'codem16c.c')
-rw-r--r--codem16c.c2360
1 files changed, 2360 insertions, 0 deletions
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 <ctype.h>
+
+#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; z<DirOrderCnt; z++)
+ if (Memo(DirOrders[z]))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (OpSize>0) 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 (p<AttrPart+strlen(AttrPart)-1) strmaxcpy(Format,p+1,255);
+ *p='\0';
+ END
+ else strcpy(Format," ");
+ break;
+ case ':':
+ p=strchr(AttrPart,'.');
+ if (p==Nil)
+ BEGIN
+ strmaxcpy(Format,AttrPart,255); *AttrPart='\0';
+ END
+ else
+ BEGIN
+ *p='\0';
+ strmaxcpy(Format,(p==AttrPart)?" ":AttrPart,255);
+ END
+ break;
+ default:
+ strcpy(Format," ");
+ END
+
+ /* Attribut abarbeiten */
+
+ switch (toupper(*AttrPart))
+ BEGIN
+ case '\0': OpSize=(-1); break;
+ case 'B': OpSize=0; break;
+ case 'W': OpSize=1; break;
+ case 'L': OpSize=2; break;
+ case 'Q': OpSize=3; break;
+ case 'S': OpSize=4; break;
+ case 'D': OpSize=5; break;
+ case 'X': OpSize=6; break;
+ case 'A': OpSize=7; break;
+ default:
+ WrError(1107); return;
+ END
+ NLS_UpString(Format);
+
+ /* Pseudoanweisungen */
+
+ if (DecodePseudo()) return;
+
+ if (DecodeIntelPseudo(False)) return;
+
+ /* ohne Argument */
+
+ for (z=0; z<FixedOrderCnt; z++)
+ if (Memo(FixedOrders[z].Name))
+ BEGIN
+ if (ArgCnt!=0) WrError(1110);
+ else if (*AttrPart!='\0') WrError(1100);
+ else if (strcmp(Format," ")!=0) WrError(1090);
+ else if (Hi(FixedOrders[z].Code)==0)
+ BEGIN
+ BAsmCode[0]=Lo(FixedOrders[z].Code); CodeLen=1;
+ END
+ else
+ BEGIN
+ BAsmCode[0]=Hi(FixedOrders[z].Code);
+ BAsmCode[1]=Lo(FixedOrders[z].Code); CodeLen=2;
+ END;
+ return;
+ END
+
+ for (z=0; z<StringOrderCnt; z++)
+ if (Memo(StringOrders[z].Name))
+ BEGIN
+ if (OpSize==-1) OpSize=1;
+ if (ArgCnt!=0) WrError(1110);
+ else if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
+ else if (strcmp(Format," ")!=0) WrError(1090);
+ else if (Hi(StringOrders[z].Code)==0)
+ BEGIN
+ BAsmCode[0]=Lo(StringOrders[z].Code)+OpSize; CodeLen=1;
+ END
+ else
+ BEGIN
+ BAsmCode[0]=Hi(StringOrders[z].Code)+OpSize;
+ BAsmCode[1]=Lo(StringOrders[z].Code); CodeLen=2;
+ END
+ return;
+ END
+
+ /* Datentransfer */
+
+ if (CodeData()) return;
+
+ /* Arithmetik */
+
+ if (Memo("ADD"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (strcasecmp(ArgStr[2],"SP")==0)
+ BEGIN
+ if (OpSize==-1) OpSize=1;
+ if (CheckFormat("GQ"))
+ BEGIN
+ DecodeAdr(ArgStr[1],MModImm);
+ if (AdrType!=ModNone)
+ if (OpSize==-1) WrError(1132);
+ else if (OpSize>1) 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<Gen1OrderCnt; z++)
+ if (Memo(Gen1Orders[z].Name))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (CheckFormat("G"))
+ BEGIN
+ DecodeAdr(ArgStr[1],MModGen);
+ if (AdrType!=ModNone)
+ if (OpSize==-1) WrError(1132);
+ else if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
+ else
+ BEGIN
+ BAsmCode[0]=Hi(Gen1Orders[z].Code)+OpSize;
+ BAsmCode[1]=Lo(Gen1Orders[z].Code)+AdrMode;
+ memcpy(BAsmCode+2,AdrVals,AdrCnt);
+ CodeLen=2+AdrCnt;
+ END
+ END
+ return;
+ END
+
+ for (z=0; z<Gen2OrderCnt; z++)
+ if (Memo(Gen2Orders[z].Name))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (CheckFormat("G"))
+ 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!=0) AND (OpSize!=1)) WrError(1130);
+ else if ((*OpPart=='M') AND ((AdrMode2==3) OR (AdrMode2==5) OR (AdrMode2-OpSize==1))) WrError(1350);
+ else CodeGen(Gen2Orders[z].Code1,Gen2Orders[z].Code2,Gen2Orders[z].Code3);
+ END
+ END
+ return;
+ END
+
+ if ((Memo("INC")) OR (Memo("DEC")))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (CheckFormat("G"))
+ BEGIN
+ DecodeAdr(ArgStr[1],MModGen);
+ if (AdrType!=ModNone)
+ if (OpSize==-1) WrError(1132);
+ else if ((OpSize==1) AND ((AdrMode & 14)==4))
+ BEGIN
+ BAsmCode[0]=0xb2+(Ord(Memo("DEC")) << 6)+((AdrMode & 1) << 3);
+ CodeLen=1;
+ END
+ else if (NOT IsShort(AdrMode,&SMode)) WrError(1350);
+ else if (OpSize!=0) WrError(1130);
+ else
+ BEGIN
+ BAsmCode[0]=0xa0+(Ord(Memo("DEC")) << 3)+SMode;
+ memcpy(BAsmCode+1,AdrVals,AdrCnt);
+ CodeLen=1+AdrCnt;
+ END
+ END
+ return;
+ END
+
+ for (z=0; z<DivOrderCnt; z++)
+ if (Memo(DivOrders[z].Name))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (CheckFormat("G"))
+ BEGIN
+ DecodeAdr(ArgStr[1],MModImm+MModGen);
+ if (AdrType!=ModNone)
+ if (OpSize==-1) WrError(1132);
+ else if ((OpSize!=0) AND (OpSize!=1)) WrError(1130);
+ else if (AdrType==ModImm)
+ BEGIN
+ BAsmCode[0]=0x7c+OpSize;
+ BAsmCode[1]=DivOrders[z].Code1;
+ memcpy(BAsmCode+2,AdrVals,AdrCnt);
+ CodeLen=2+AdrCnt;
+ END
+ else
+ BEGIN
+ BAsmCode[0]=DivOrders[z].Code2+OpSize;
+ BAsmCode[1]=DivOrders[z].Code3+AdrMode;
+ memcpy(BAsmCode+2,AdrVals,AdrCnt);
+ CodeLen=2+AdrCnt;
+ END
+ END
+ return;
+ END
+
+ for (z=0; z<BCDOrderCnt; z++)
+ if (Memo(BCDOrders[z]))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[2],MModGen);
+ if (AdrType!=ModNone)
+ if (AdrMode!=0) WrError(1350);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1],MModGen+MModImm);
+ if (AdrType!=ModNone)
+ if (AdrType==ModImm)
+ BEGIN
+ BAsmCode[0]=0x7c+OpSize;
+ BAsmCode[1]=0xec+z;
+ memcpy(BAsmCode+2,AdrVals,AdrCnt);
+ CodeLen=2+AdrCnt;
+ END
+ else if (AdrMode!=1) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0]=0x7c+OpSize;
+ BAsmCode[1]=0xe4+z;
+ CodeLen=2;
+ END
+ END
+ END
+ return;
+ END
+
+ if (Memo("EXTS"))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (CheckFormat("G"))
+ BEGIN
+ DecodeAdr(ArgStr[1],MModGen);
+ if (OpSize==-1) OpSize=0;
+ if (AdrType!=ModNone)
+ if (OpSize==0)
+ if ((AdrMode==1) OR ((AdrMode>=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<BitOrderCnt; z++)
+ if (Memo(BitOrders[z].Name))
+ BEGIN
+ MayShort=(BitOrders[z].Code & 12)==8;
+ if (CheckFormat(MayShort?"GS":"G"))
+ if (DecodeBitAdr((FormatCode!=1) AND (MayShort)))
+ if (AdrMode>=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<ConditionCnt; z++)
+ if (strcmp(OpPart+2,Conditions[z].Name)==0)
+ BEGIN
+ if ((ArgCnt==1) AND (strcasecmp(ArgStr[1],"C")==0))
+ BEGIN
+ BAsmCode[0]=0x7d; BAsmCode[1]=0xd0+Conditions[z].Code;
+ CodeLen=2;
+ END
+ else if (DecodeBitAdr(False))
+ BEGIN
+ BAsmCode[0]=0x7e;
+ BAsmCode[1]=0x20+AdrMode;
+ memcpy(BAsmCode+2,AdrVals,AdrCnt); z=Conditions[z].Code;
+ if ((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<ConditionCnt; z++)
+ if (strcmp(Conditions[z].Name,OpPart+1)==0)
+ BEGIN
+ Num1=1+Ord(Conditions[z].Code>=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<<SegCode;
+ Grans[SegCode]=1; ListGrans[SegCode]=1; SegInits[SegCode]=0;
+ SegLimits[SegCode] = 0xfffff; /* RMS 10: Probably a typo (was 0xffff) */
+
+ MakeCode=MakeCode_M16C; IsDef=IsDef_M16C;
+ SwitchFrom=SwitchFrom_M16C; InitFields();
+END
+
+ void codem16c_init(void)
+BEGIN
+ CPUM16C=AddCPU("M16C",SwitchTo_M16C);
+ CPUM30600M8=AddCPU("M30600M8",SwitchTo_M16C);
+ CPUM30610=AddCPU("M30610",SwitchTo_M16C);
+ CPUM30620=AddCPU("M30620",SwitchTo_M16C);
+
+ AddCopyright("Mitsubishi M16C-Generator also (C) 1999 RMS");
+END
+
+