dect
/
asl
Archived
13
0
Fork 0
This repository has been archived on 2022-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
asl/codem16c.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