2361 lines
66 KiB
C
2361 lines
66 KiB
C
/* 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
|
|
|
|
|