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/codest9.c

1879 lines
54 KiB
C

/* codest9.c */
/*****************************************************************************/
/* AS-Portierung */
/* */
/* Codegenerator SGS-Thomson ST9 */
/* */
/* Historie: 10. 2.1997 Grundsteinlegung */
/* 1. 7.1998 Warnungen bei is...()-Funktionen beseitigt */
/* 2. 1.1999 ChkPC umgestellt */
/* 30. 1.1999 Formate maschinenunabhaengig gemacht */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <ctype.h>
#include <string.h>
#include "bpemu.h"
#include "strutil.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "codepseudo.h"
#include "codevars.h"
typedef struct
{
char *Name;
Word Code;
} FixedOrder;
typedef struct
{
char *Name;
int len;
Word Code;
} ALUOrder;
#define WorkOfs 0xd0
#define ModNone (-1)
#define ModReg 0
#define MModReg (1l << ModReg) /* Rn */
#define ModWReg 1
#define MModWReg (1l << ModWReg) /* rn */
#define ModRReg 2
#define MModRReg (1l << ModRReg) /* RRn */
#define ModWRReg 3
#define MModWRReg (1l << ModWRReg) /* rrn */
#define ModIReg 4
#define MModIReg (1l << ModIReg) /* (Rn) */
#define ModIWReg 5
#define MModIWReg (1l << ModIWReg) /* (rn) */
#define ModIRReg 6
#define MModIRReg (1l << ModIRReg) /* (RRn) */
#define ModIWRReg 7
#define MModIWRReg (1l << ModIWRReg) /* (rrn) */
#define ModIncWReg 8
#define MModIncWReg (1l << ModIncWReg) /* (rn)+ */
#define ModIncWRReg 9
#define MModIncWRReg (1l << ModIncWRReg) /* (rrn)+ */
#define ModDecWRReg 10
#define MModDecWRReg (1l << ModDecWRReg) /* -(rrn) */
#define ModDisp8WReg 11
#define MModDisp8WReg (1l << ModDisp8WReg) /* d8(rn) */
#define ModDisp8WRReg 12
#define MModDisp8WRReg (1l << ModDisp8WRReg) /* d8(rrn) */
#define ModDisp16WRReg 13
#define MModDisp16WRReg (1l << ModDisp16WRReg) /* d16(rrn) */
#define ModDispRWRReg 14
#define MModDispRWRReg (1l << ModDispRWRReg) /* rrm(rrn */
#define ModAbs 15
#define MModAbs (1l << ModAbs) /* NN */
#define ModImm 16
#define MModImm (1l << ModImm) /* #N/#NN */
#define ModDisp8RReg 17
#define MModDisp8RReg (1l << ModDisp8RReg) /* d8(RRn) */
#define ModDisp16RReg 18
#define MModDisp16RReg (1l << ModDisp16RReg) /* d16(RRn) */
#define FixedOrderCnt 12
#define ALUOrderCnt 10
#define RegOrderCnt 13
#define Reg16OrderCnt 8
#define Bit2OrderCnt 4
#define Bit1OrderCnt 4
#define ConditionCnt 20
#define LoadOrderCnt 4
static CPUVar CPUST9020,CPUST9030,CPUST9040,CPUST9050;
static FixedOrder *FixedOrders;
static ALUOrder *ALUOrders;
static FixedOrder *RegOrders;
static FixedOrder *Reg16Orders;
static FixedOrder *Bit2Orders;
static FixedOrder *Bit1Orders;
static FixedOrder *Conditions;
static FixedOrder *LoadOrders;
static ShortInt AdrMode,AbsSeg;
static Byte AdrPart,OpSize;
static Byte AdrVals[3];
static SimpProc SaveInitProc;
static LongInt DPAssume;
/*--------------------------------------------------------------------------*/
static void AddFixed(char *NName, Word NCode)
BEGIN
if (InstrZ>=FixedOrderCnt) exit(255);
FixedOrders[InstrZ].Name=NName;
FixedOrders[InstrZ++].Code=NCode;
END
static void AddALU(char *NName, Word NCode)
BEGIN
if (InstrZ>=ALUOrderCnt) exit(255);
ALUOrders[InstrZ].Name=NName;
ALUOrders[InstrZ].len=strlen(NName);
ALUOrders[InstrZ++].Code=NCode;
END
static void AddReg(char *NName, Word NCode)
BEGIN
if (InstrZ>=RegOrderCnt) exit(255);
RegOrders[InstrZ].Name=NName;
RegOrders[InstrZ++].Code=NCode;
END
static void AddReg16(char *NName, Word NCode)
BEGIN
if (InstrZ>=Reg16OrderCnt) exit(255);
Reg16Orders[InstrZ].Name=NName;
Reg16Orders[InstrZ++].Code=NCode;
END
static void AddBit2(char *NName, Word NCode)
BEGIN
if (InstrZ>=Bit2OrderCnt) exit(255);
Bit2Orders[InstrZ].Name=NName;
Bit2Orders[InstrZ++].Code=NCode;
END
static void AddBit1(char *NName, Word NCode)
BEGIN
if (InstrZ>=Bit1OrderCnt) exit(255);
Bit1Orders[InstrZ].Name=NName;
Bit1Orders[InstrZ++].Code=NCode;
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 AddLoad(char *NName, Word NCode)
BEGIN
if (InstrZ>=LoadOrderCnt) exit(255);
LoadOrders[InstrZ].Name=NName;
LoadOrders[InstrZ++].Code=NCode;
END
static void InitFields(void)
BEGIN
FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); InstrZ=0;
AddFixed("CCF" ,0x0061); AddFixed("DI" ,0x0010);
AddFixed("EI" ,0x0000); AddFixed("HALT",0xbf01);
AddFixed("IRET",0x00d3); AddFixed("NOP" ,0x00ff);
AddFixed("RCF" ,0x0011); AddFixed("RET" ,0x0046);
AddFixed("SCF" ,0x0001); AddFixed("SDM" ,0x00fe);
AddFixed("SPM" ,0x00ee); AddFixed("WFI" ,0xef01);
ALUOrders=(ALUOrder *) malloc(sizeof(ALUOrder)*ALUOrderCnt); InstrZ=0;
AddALU("ADC", 3); AddALU("ADD", 4); AddALU("AND", 1);
AddALU("CP" , 9); AddALU("OR" , 0); AddALU("SBC", 2);
AddALU("SUB", 5); AddALU("TCM", 8); AddALU("TM" ,10);
AddALU("XOR", 6);
RegOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*RegOrderCnt); InstrZ=0;
AddReg("CLR" ,0x90); AddReg("CPL" ,0x80); AddReg("DA" ,0x70);
AddReg("DEC" ,0x40); AddReg("INC" ,0x50); AddReg("POP" ,0x76);
AddReg("POPU",0x20); AddReg("RLC" ,0xb0); AddReg("ROL" ,0xa0);
AddReg("ROR" ,0xc0); AddReg("RRC" ,0xd0); AddReg("SRA" ,0xe0);
AddReg("SWAP",0xf0);
Reg16Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*Reg16OrderCnt); InstrZ=0;
AddReg16("DECW" ,0xcf); AddReg16("EXT" ,0xc6);
AddReg16("INCW" ,0xdf); AddReg16("POPUW",0xb7);
AddReg16("POPW" ,0x75); AddReg16("RLCW" ,0x8f);
AddReg16("RRCW" ,0x36); AddReg16("SRAW" ,0x2f);
Bit2Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*Bit2OrderCnt); InstrZ=0;
AddBit2("BAND",0x1f); AddBit2("BLD" ,0xf2);
AddBit2("BOR" ,0x0f); AddBit2("BXOR",0x6f);
Bit1Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*Bit1OrderCnt); InstrZ=0;
AddBit1("BCPL",0x6f); AddBit1("BRES" ,0x1f);
AddBit1("BSET",0x0f); AddBit1("BTSET",0xf2);
Conditions=(FixedOrder *) malloc(sizeof(FixedOrder)*ConditionCnt); InstrZ=0;
AddCondition("F" ,0x0); AddCondition("T" ,0x8);
AddCondition("C" ,0x7); AddCondition("NC" ,0xf);
AddCondition("Z" ,0x6); AddCondition("NZ" ,0xe);
AddCondition("PL" ,0xd); AddCondition("MI" ,0x5);
AddCondition("OV" ,0x4); AddCondition("NOV" ,0xc);
AddCondition("EQ" ,0x6); AddCondition("NE" ,0xe);
AddCondition("GE" ,0x9); AddCondition("LT" ,0x1);
AddCondition("GT" ,0xa); AddCondition("LE" ,0x2);
AddCondition("UGE" ,0xf); AddCondition("UL" ,0x7);
AddCondition("UGT" ,0xb); AddCondition("ULE" ,0x3);
LoadOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*LoadOrderCnt); InstrZ=0;
AddLoad("LDPP",0x00); AddLoad("LDDP",0x10);
AddLoad("LDPD",0x01); AddLoad("LDDD",0x11);
END
static void DeinitFields(void)
BEGIN
free(FixedOrders);
free(ALUOrders);
free(RegOrders);
free(Reg16Orders);
free(Bit2Orders);
free(Bit1Orders);
free(Conditions);
free(LoadOrders);
END
/*--------------------------------------------------------------------------*/
static Boolean DecodeReg(char *Asc_O, Byte *Erg, Byte *Size)
BEGIN
Boolean Res;
char *Asc;
Asc=Asc_O;
if (strlen(Asc)<2) return False;
if (*Asc!='r') return False; Asc++;
if (*Asc=='r')
BEGIN
if (strlen(Asc)<2) return False;
*Size=1; Asc++;
END
else *Size=0;
*Erg=ConstLongInt(Asc,&Res);
if ((NOT Res) OR (*Erg>15)) return False;
if ((*Size==1) AND (Odd(*Erg))) return False;
return True;
END
static void ChkAdr(LongWord Mask)
BEGIN
if ((AdrMode!=ModNone) AND (((1l << AdrMode) & Mask)==0))
BEGIN
WrError(1350); AdrMode=ModNone; AdrCnt=0;
END
END
static void DecodeAdr(char *Asc_O, LongWord Mask)
BEGIN
Word AdrWord;
int level;
Byte flg,Size;
Boolean OK;
String Reg,Asc;
char *p;
AdrMode=ModNone; AdrCnt=0;
strmaxcpy(Asc,Asc_O,255);
/* immediate */
if (*Asc=='#')
BEGIN
switch (OpSize)
BEGIN
case 0:
AdrVals[0]=EvalIntExpression(Asc+1,Int8,&OK);
break;
case 1:
AdrWord=EvalIntExpression(Asc+1,Int16,&OK);
AdrVals[0]=Hi(AdrWord); AdrVals[1]=Lo(AdrWord);
break;
END
if (OK)
BEGIN
AdrMode=ModImm; AdrCnt=OpSize+1;
END
ChkAdr(Mask); return;
END
/* Arbeitsregister */
if (DecodeReg(Asc,&AdrPart,&Size))
BEGIN
if (Size==0)
if ((Mask & MModWReg)!=0) AdrMode=ModWReg;
else
BEGIN
AdrVals[0]=WorkOfs+AdrPart; AdrCnt=1; AdrMode=ModReg;
END
else
if ((Mask & MModWRReg)!=0) AdrMode=ModWRReg;
else
BEGIN
AdrVals[0]=WorkOfs+AdrPart; AdrCnt=1; AdrMode=ModRReg;
END
ChkAdr(Mask); return;
END
/* Postinkrement */
if (Asc[strlen(Asc)-1]=='+')
BEGIN
if ((*Asc!='(') OR (Asc[strlen(Asc)-2]!=')')) WrError(1350);
else
BEGIN
strcpy(Asc,Asc+1); Asc[strlen(Asc)-2]='\0';
if (NOT DecodeReg(Asc,&AdrPart,&Size)) WrXError(1445,Asc);
AdrMode=(Size==0) ? ModIncWReg : ModIncWRReg;
END
ChkAdr(Mask); return;
END
/* Predekrement */
if ((*Asc=='-') AND (Asc[1]=='(') AND (Asc[strlen(Asc)-1]==')'))
BEGIN
strcpy(Reg,Asc+2); Reg[strlen(Reg)-1]='\0';
if (DecodeReg(Reg,&AdrPart,&Size))
BEGIN
if (Size==0) WrError(1350); else AdrMode=ModDecWRReg;
ChkAdr(Mask); return;
END
END
/* indirekt<->direkt */
if ((Asc[strlen(Asc)-1]!=')') OR (strlen(Asc)<3))
BEGIN
OK=False; p=Asc;
END
else
BEGIN
level=0; p=Asc+strlen(Asc)-2; flg=0;
while ((p>=Asc) AND (level>=0))
BEGIN
switch (*p)
BEGIN
case '(': if (flg==0) level--; break;
case ')': if (flg==0) level++; break;
case '\'': if (((flg & 2)==0)) flg^=1; break;
case '"': if (((flg & 1)==0)) flg^=2; break;
END
p--;
END
OK=(level==-1) AND ((p<Asc) OR ((*p=='.') OR (*p=='_') OR (isdigit(((unsigned int)*p)&0xff)) OR (isalpha(((unsigned int)*p)&0xff))));
END
/* indirekt */
if (OK)
BEGIN
strcpy(Reg,p+2); Reg[strlen(Reg)-1]='\0'; p[1]='\0';
if (DecodeReg(Reg,&AdrPart,&Size))
if (Size==0) /* d(r) */
BEGIN
AdrVals[0]=EvalIntExpression(Asc,Int8,&OK);
if (OK)
BEGIN
if (((Mask & MModIWReg)!=0) AND (AdrVals[0]==0)) AdrMode=ModIWReg;
else if (((Mask & MModIReg)!=0) AND (AdrVals[0]==0))
BEGIN
AdrVals[0]=WorkOfs+AdrPart; AdrMode=ModIReg; AdrCnt=1;
END
else
BEGIN
AdrMode=ModDisp8WReg; AdrCnt=1;
END
END
END
else /* ...(rr) */
BEGIN
if (DecodeReg(Asc,AdrVals,&Size))
BEGIN /* rr(rr) */
if (Size!=1) WrError(1350);
else
BEGIN
AdrMode=ModDispRWRReg; AdrCnt=1;
END
END
else
BEGIN /* d(rr) */
AdrWord=EvalIntExpression(Asc,Int16,&OK);
if ((AdrWord==0) AND ((Mask & (MModIRReg+MModIWRReg))!=0))
BEGIN
if (((Mask & MModIWRReg)!=0)) AdrMode=ModIWRReg;
else
BEGIN
AdrMode=ModIRReg; AdrVals[0]=AdrPart+WorkOfs; AdrCnt=1;
END
END
else if ((AdrWord<0x100) AND ((Mask & (MModDisp8WRReg+MModDisp8RReg))!=0))
BEGIN
if (((Mask & MModDisp8WRReg)!=0))
BEGIN
AdrVals[0]=Lo(AdrWord); AdrCnt=1; AdrMode=ModDisp8WRReg;
END
else
BEGIN
AdrVals[0]=AdrPart+WorkOfs; AdrVals[1]=Lo(AdrWord);
AdrCnt=2; AdrMode=ModDisp8RReg;
END
END
else if (((Mask & MModDisp16WRReg)!=0))
BEGIN
AdrVals[0]=Hi(AdrWord); AdrVals[1]=Lo(AdrWord);
AdrCnt=2; AdrMode=ModDisp16WRReg;
END
else
BEGIN
AdrVals[0]=AdrPart+WorkOfs;
AdrVals[2]=Hi(AdrWord); AdrVals[1]=Lo(AdrWord);
AdrCnt=3; AdrMode=ModDisp16RReg;
END
END
END
else /* ...(RR) */
BEGIN
AdrWord=EvalIntExpression(Reg,UInt9,&OK);
if (((TypeFlag & (1 << SegReg))==0)) WrError(1350);
else if (AdrWord<0xff)
BEGIN
AdrVals[0]=Lo(AdrWord);
AdrWord=EvalIntExpression(Asc,Int8,&OK);
if (AdrWord!=0) WrError(1320);
else
BEGIN
AdrCnt=1; AdrMode=ModIReg;
END
END
else if ((AdrWord>0x1ff) OR (Odd(AdrWord))) WrError(1350);
else
BEGIN
AdrVals[0]=Lo(AdrWord);
AdrWord=EvalIntExpression(Asc,Int16,&OK);
if ((AdrWord==0) AND ((Mask & MModIRReg)!=0))
BEGIN
AdrCnt=1; AdrMode=ModIRReg;
END
else if ((AdrWord<0x100) AND ((Mask & MModDisp8RReg)!=0))
BEGIN
AdrVals[1]=Lo(AdrWord); AdrCnt=2; AdrMode=ModDisp8RReg;
END
else
BEGIN
AdrVals[2]=Hi(AdrWord); AdrVals[1]=Lo(AdrWord);
AdrCnt=3; AdrMode=ModDisp16RReg;
END
END
END
ChkAdr(Mask); return;
END
/* direkt */
AdrWord=EvalIntExpression(Asc,UInt16,&OK);
if (OK)
if (((TypeFlag & (1 << SegReg)))==0)
BEGIN
AdrMode=ModAbs;
AdrVals[0]=Hi(AdrWord); AdrVals[1]=Lo(AdrWord);
AdrCnt=2; ChkSpace(AbsSeg);
END
else if (AdrWord<0xff)
BEGIN
AdrMode=ModReg; AdrVals[0]=Lo(AdrWord); AdrCnt=1;
END
else if ((AdrWord>0x1ff) OR (Odd(AdrWord))) WrError(1350);
else
BEGIN
AdrMode=ModRReg; AdrVals[0]=Lo(AdrWord); AdrCnt=1;
END
ChkAdr(Mask);
END
static Boolean SplitBit(char *Asc, Byte *Erg)
BEGIN
char *p;
Integer val;
Boolean OK,Inv;
p=RQuotPos(Asc,'.');
if ((p==Nil) OR (p==Asc+strlen(Asc)+1))
BEGIN
if (*Asc=='!')
BEGIN
Inv=True; strcpy(Asc,Asc+1);
END
else Inv=False;
val=EvalIntExpression(Asc,UInt8,&OK);
if (OK)
BEGIN
*Erg=val & 15; if (Inv) *Erg^=1;
sprintf(Asc, "r%d", (int)(val >> 4));
return True;
END
return False;
END
if (p[1]=='!')
*Erg=1+(EvalIntExpression(p+2,UInt3,&OK) << 1);
else
*Erg=EvalIntExpression(p+1,UInt3,&OK) << 1;
*p='\0';
return OK;
END
/*--------------------------------------------------------------------------*/
static Boolean DecodePseudo(void)
BEGIN
#define ASSUMEST9Count 1
static ASSUMERec ASSUMEST9s[ASSUMEST9Count]=
{{"DP", &DPAssume, 0, 1, 0x0}};
Byte Bit;
if (Memo("REG"))
BEGIN
CodeEquate(SegReg,0,0x1ff);
return True;
END
if (Memo("BIT"))
BEGIN
if (ArgCnt!=1) WrError(1110);
else if (SplitBit(ArgStr[1],&Bit))
BEGIN
DecodeAdr(ArgStr[1],MModWReg);
if (AdrMode==ModWReg)
BEGIN
PushLocHandle(-1);
EnterIntSymbol(LabPart,(AdrPart << 4)+Bit,SegNone,False);
PopLocHandle();
sprintf(ListLine,"=r%d.%s%c", (int)AdrPart,
(Odd(Bit))?"!":"", (Bit >> 1)+AscOfs);
END
END
return True;
END
if (Memo("ASSUME"))
BEGIN
CodeASSUME(ASSUMEST9s,ASSUMEST9Count);
return True;
END
return False;
END
static void MakeCode_ST9(void)
BEGIN
Integer AdrInt;
int z;
Boolean OK;
Byte HReg,HPart;
Word Mask1,Mask2,AdrWord;
CodeLen=0; DontPrint=False; OpSize=0;
AbsSeg=(DPAssume==1) ? SegData : SegCode;
/* zu ignorierendes */
if (Memo("")) return;
/* Pseudoanweisungen */
if (DecodePseudo()) return;
if (DecodeIntelPseudo(True)) return;
/* ohne Argument */
for (z=0; z<FixedOrderCnt; z++)
if (Memo(FixedOrders[z].Name))
BEGIN
if (ArgCnt!=0) WrError(1110);
else
BEGIN
OK=Hi(FixedOrders[z].Code)!=0;
if (OK) BAsmCode[0]=Hi(FixedOrders[z].Code);
CodeLen=Ord(OK);
BAsmCode[CodeLen++]=Lo(FixedOrders[z].Code);
END
return;
END
/* Datentransfer */
if ((Memo("LD")) OR (Memo("LDW")))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
if (OpPart[strlen(OpPart)-1]=='W')
BEGIN
OpSize=1; Mask1=MModWRReg; Mask2=MModRReg;
END
else
BEGIN
Mask1=MModWReg; Mask2=MModReg;
END;
DecodeAdr(ArgStr[1],Mask1+Mask2+MModIWReg+MModDisp8WReg+MModIncWReg+
MModIWRReg+MModIncWRReg+MModDecWRReg+MModDisp8WRReg+
MModDisp16WRReg+MModDispRWRReg+MModAbs+MModIRReg);
switch (AdrMode)
BEGIN
case ModWReg:
case ModWRReg:
HReg=AdrPart;
DecodeAdr(ArgStr[2],Mask1+Mask2+MModIWReg+MModDisp8WReg+MModIWRReg+
MModIncWRReg+MModDecWRReg+MModDispRWRReg+MModDisp8WRReg+
MModDisp16WRReg+MModAbs+MModImm);
switch (AdrMode)
BEGIN
case ModWReg:
BAsmCode[0]=(HReg << 4)+8; BAsmCode[1]=WorkOfs+AdrPart;
CodeLen=2;
break;
case ModWRReg:
BAsmCode[0]=0xe3; BAsmCode[1]=(HReg << 4)+AdrPart;
CodeLen=2;
break;
case ModReg:
BAsmCode[0]=(HReg << 4)+8; BAsmCode[1]=AdrVals[0];
CodeLen=2;
break;
case ModRReg:
BAsmCode[0]=0xef; BAsmCode[1]=AdrVals[0];
BAsmCode[2]=HReg+WorkOfs; CodeLen=3;
break;
case ModIWReg:
if (OpSize==0)
BEGIN
BAsmCode[0]=0xe4; BAsmCode[1]=(HReg << 4)+AdrPart;
CodeLen=2;
END
else
BEGIN
BAsmCode[0]=0xa6; BAsmCode[1]=0xf0+AdrPart;
BAsmCode[2]=WorkOfs+HReg; CodeLen=3;
END
break;
case ModDisp8WReg:
BAsmCode[0]=0xb3+(OpSize*0x2b);
BAsmCode[1]=(HReg << 4)+AdrPart;
BAsmCode[2]=AdrVals[0]; CodeLen=3;
break;
case ModIWRReg:
BAsmCode[0]=0xb5+(OpSize*0x2e);
BAsmCode[1]=(HReg << 4)+AdrPart+OpSize;
CodeLen=2;
break;
case ModIncWRReg:
BAsmCode[0]=0xb4+(OpSize*0x21);
BAsmCode[1]=0xf1+AdrPart;
BAsmCode[2]=WorkOfs+HReg; CodeLen=3;
break;
case ModDecWRReg:
BAsmCode[0]=0xc2+OpSize;
BAsmCode[1]=0xf1+AdrPart;
BAsmCode[2]=WorkOfs+HReg; CodeLen=3;
break;
case ModDispRWRReg:
BAsmCode[0]=0x60;
BAsmCode[1]=(0x10*(1-OpSize))+(AdrVals[0] << 4)+AdrPart;
BAsmCode[2]=0xf0+HReg; CodeLen=3;
break;
case ModDisp8WRReg:
BAsmCode[0]=0x7f+(OpSize*7);
BAsmCode[1]=0xf1+AdrPart;
BAsmCode[2]=AdrVals[0]; BAsmCode[3]=HReg+WorkOfs;
CodeLen=4;
break;
case ModDisp16WRReg:
BAsmCode[0]=0x7f+(OpSize*7);
BAsmCode[1]=0xf0+AdrPart;
memcpy(BAsmCode+2,AdrVals,AdrCnt); BAsmCode[2+AdrCnt]=HReg+WorkOfs;
CodeLen=3+AdrCnt;
break;
case ModAbs:
BAsmCode[0]=0xc4+(OpSize*0x1e);
BAsmCode[1]=0xf0+AdrPart;
memcpy(BAsmCode+2,AdrVals,AdrCnt);
CodeLen=2+AdrCnt;
break;
case ModImm:
if (OpSize==0)
BEGIN
BAsmCode[0]=(HReg << 4)+0x0c;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
CodeLen=1+AdrCnt;
END
else
BEGIN
BAsmCode[0]=0xbf; BAsmCode[1]=WorkOfs+HReg;
memcpy(BAsmCode+2,AdrVals,AdrCnt);
CodeLen=2+AdrCnt;
END
break;
END
break;
case ModReg:
case ModRReg:
HReg=AdrVals[0];
DecodeAdr(ArgStr[2],Mask1+Mask2+MModIWReg+MModIWRReg+MModIncWRReg+
MModDecWRReg+MModDispRWRReg+MModDisp8WRReg+MModDisp16WRReg+
MModImm);
switch (AdrMode)
BEGIN
case ModWReg:
BAsmCode[0]=(AdrPart << 4)+0x09; BAsmCode[1]=HReg; CodeLen=2;
break;
case ModWRReg:
BAsmCode[0]=0xef; BAsmCode[1]=WorkOfs+AdrPart;
BAsmCode[2]=HReg; CodeLen=3;
break;
case ModReg:
case ModRReg:
BAsmCode[0]=0xf4-(OpSize*5);
BAsmCode[1]=AdrVals[0];
BAsmCode[2]=HReg; CodeLen=3;
break;
case ModIWReg:
BAsmCode[0]=0xe7-(0x41*OpSize); BAsmCode[1]=0xf0+AdrPart;
BAsmCode[2]=HReg; CodeLen=3;
break;
case ModIWRReg:
BAsmCode[0]=0x72+(OpSize*12);
BAsmCode[1]=0xf1+AdrPart-OpSize; BAsmCode[2]=HReg;
CodeLen=3;
break;
case ModIncWRReg:
BAsmCode[0]=0xb4+(0x21*OpSize);
BAsmCode[1]=0xf1+AdrPart; BAsmCode[2]=HReg;
CodeLen=3;
break;
case ModDecWRReg:
BAsmCode[0]=0xc2+OpSize;
BAsmCode[1]=0xf1+AdrPart; BAsmCode[2]=HReg;
CodeLen=3;
break;
case ModDisp8WRReg:
BAsmCode[0]=0x7f+(OpSize*7);
BAsmCode[1]=0xf1+AdrPart;
BAsmCode[2]=AdrVals[0];
BAsmCode[3]=HReg; CodeLen=4;
break;
case ModDisp16WRReg:
BAsmCode[0]=0x7f+(OpSize*7);
BAsmCode[1]=0xf0+AdrPart;
memcpy(BAsmCode+2,AdrVals,AdrCnt);
BAsmCode[2+AdrCnt]=HReg; CodeLen=3+AdrCnt;
break;
case ModImm:
BAsmCode[0]=0xf5-(OpSize*0x36);
BAsmCode[1]=HReg;
memcpy(BAsmCode+2,AdrVals,2); CodeLen=2+AdrCnt;
break;
END
break;
case ModIWReg:
HReg=AdrPart;
DecodeAdr(ArgStr[2],Mask2+Mask1);
switch (AdrMode)
BEGIN
case ModWReg:
BAsmCode[0]=0xe5; BAsmCode[1]=(HReg << 4)+AdrPart; CodeLen=2;
break;
case ModWRReg:
BAsmCode[0]=0x96; BAsmCode[1]=WorkOfs+AdrPart;
BAsmCode[2]=0xf0+HReg; CodeLen=3;
break;
case ModReg:
case ModRReg:
BAsmCode[0]=0xe6-(0x50*OpSize); BAsmCode[1]=AdrVals[0];
BAsmCode[2]=0xf0+HReg; CodeLen=3;
break;
END
break;
case ModDisp8WReg:
BAsmCode[2]=AdrVals[0]; HReg=AdrPart;
DecodeAdr(ArgStr[2],Mask1);
switch (AdrMode)
BEGIN
case ModWReg:
case ModWRReg:
BAsmCode[0]=0xb2+(OpSize*0x2c);
BAsmCode[1]=(AdrPart << 4)+(OpSize << 4)+HReg;
CodeLen=3;
break;
END
break;
case ModIncWReg:
HReg=AdrPart;
DecodeAdr(ArgStr[2],MModIncWRReg*(1-OpSize));
switch (AdrMode)
BEGIN
case ModIncWRReg:
BAsmCode[0]=0xd7; BAsmCode[1]=(HReg << 4)+AdrPart+1; CodeLen=2;
break;
END
break;
case ModIWRReg:
HReg=AdrPart;
DecodeAdr(ArgStr[2],(MModIWReg*(1-OpSize))+Mask1+Mask2+MModIWRReg+MModImm);
switch (AdrMode)
BEGIN
case ModIWReg:
BAsmCode[0]=0xb5; BAsmCode[1]=(AdrPart << 4)+HReg+1; CodeLen=2;
break;
case ModWReg:
BAsmCode[0]=0x72; BAsmCode[1]=0xf0+HReg;
BAsmCode[2]=AdrPart+WorkOfs;
CodeLen=3;
break;
case ModWRReg:
BAsmCode[0]=0xe3; BAsmCode[1]=(HReg << 4)+0x10+AdrPart;
CodeLen=2;
break;
case ModReg:
case ModRReg:
BAsmCode[0]=0x72+(OpSize*0x4c);
BAsmCode[1]=0xf0+HReg+OpSize; BAsmCode[2]=AdrVals[0];
CodeLen=3;
break;
case ModIWRReg:
if (OpSize==0)
BEGIN
BAsmCode[0]=0x73;
BAsmCode[1]=0xf0+AdrPart;
BAsmCode[2]=WorkOfs+HReg; CodeLen=3;
END
else
BEGIN
BAsmCode[0]=0xe3; BAsmCode[1]=0x11+(HReg << 4)+AdrPart;
CodeLen=2;
END
break;
case ModImm:
BAsmCode[0]=0xf3-(OpSize*0x35);
BAsmCode[1]=0xf0+HReg;
memcpy(BAsmCode+2,AdrVals,AdrCnt); CodeLen=2+AdrCnt;
break;
END
break;
case ModIncWRReg:
HReg=AdrPart;
DecodeAdr(ArgStr[2],Mask2+(MModIncWReg*(1-OpSize)));
switch (AdrMode)
BEGIN
case ModReg:
case ModRReg:
BAsmCode[0]=0xb4+(OpSize*0x21);
BAsmCode[1]=0xf0+HReg; BAsmCode[2]=AdrVals[0];
CodeLen=3;
break;
case ModIncWReg:
BAsmCode[0]=0xd7; BAsmCode[1]=(AdrPart << 4)+HReg;
CodeLen=2;
break;
END;
break;
case ModDecWRReg:
HReg=AdrPart;
DecodeAdr(ArgStr[2],Mask2);
switch (AdrMode)
BEGIN
case ModReg:
case ModRReg:
BAsmCode[0]=0xc2+OpSize;
BAsmCode[1]=0xf0+HReg; BAsmCode[2]=AdrVals[0];
CodeLen=3;
break;
END
break;
case ModDispRWRReg:
HReg=AdrPart; HPart=AdrVals[0];
DecodeAdr(ArgStr[2],Mask1);
switch (AdrMode)
BEGIN
case ModWReg:
case ModWRReg:
BAsmCode[0]=0x60;
BAsmCode[1]=(0x10*(1-OpSize))+0x01+(HPart << 4)+HReg;
BAsmCode[2]=0xf0+AdrPart;
CodeLen=3;
break;
END
break;
case ModDisp8WRReg:
BAsmCode[2]=AdrVals[0]; HReg=AdrPart;
DecodeAdr(ArgStr[2],Mask2+(OpSize*MModImm));
switch (AdrMode)
BEGIN
case ModReg:
case ModRReg:
BAsmCode[0]=0x26+(OpSize*0x60);
BAsmCode[1]=0xf1+HReg; BAsmCode[3]=AdrVals[0];
CodeLen=4;
break;
case ModImm:
BAsmCode[0]=0x06; BAsmCode[1]=0xf1+HReg;
memcpy(BAsmCode+3,AdrVals,AdrCnt); CodeLen=3+AdrCnt;
break;
END
break;
case ModDisp16WRReg:
memcpy(BAsmCode+2,AdrVals,2); HReg=AdrPart;
DecodeAdr(ArgStr[2],Mask2+(OpSize*MModImm));
switch (AdrMode)
BEGIN
case ModReg:
case ModRReg:
BAsmCode[0]=0x26+(OpSize*0x60);
BAsmCode[1]=0xf0+HReg; BAsmCode[4]=AdrVals[0];
CodeLen=5;
break;
case ModImm:
BAsmCode[0]=0x06; BAsmCode[1]=0xf0+HReg;
memcpy(BAsmCode+4,AdrVals,AdrCnt); CodeLen=4+AdrCnt;
break;
END
break;
case ModAbs:
memcpy(BAsmCode+2,AdrVals,2);
DecodeAdr(ArgStr[2],Mask1+MModImm);
switch (AdrMode)
BEGIN
case ModWReg:
case ModWRReg:
BAsmCode[0]=0xc5+(OpSize*0x1d);
BAsmCode[1]=0xf0+AdrPart+OpSize;
CodeLen=4;
break;
case ModImm:
memmove(BAsmCode+2+AdrCnt,BAsmCode+2,2); BAsmCode[0]=0x2f+(OpSize*7);
BAsmCode[1]=0xf1; memcpy(BAsmCode+2,AdrVals,AdrCnt);
CodeLen=4+AdrCnt;
break;
END
break;
case ModIRReg:
HReg=AdrVals[0];
DecodeAdr(ArgStr[2],MModIWRReg*(1-OpSize));
switch (AdrMode)
BEGIN
case ModIWRReg:
BAsmCode[0]=0x73; BAsmCode[1]=0xf0+AdrPart; BAsmCode[2]=HReg;
CodeLen=3;
break;
END
break;
END
END
return;
END
for (z=0; z<LoadOrderCnt; z++)
if (Memo(LoadOrders[z].Name))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModIncWRReg);
if (AdrMode==ModIncWRReg)
BEGIN
HReg=AdrPart << 4;
DecodeAdr(ArgStr[2],MModIncWRReg);
if (AdrMode==ModIncWRReg)
BEGIN
BAsmCode[0]=0xd6;
BAsmCode[1]=LoadOrders[z].Code+HReg+AdrPart;
CodeLen=2;
END
END
END
return;
END
if ((Memo("PEA")) OR (Memo("PEAU")))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModDisp8RReg+MModDisp16RReg);
if (AdrMode!=ModNone)
BEGIN
BAsmCode[0]=0x8f;
BAsmCode[1]=0x01+(2*Ord(Memo("PEAU")));
memcpy(BAsmCode+2,AdrVals,AdrCnt);
BAsmCode[2]+=AdrCnt-2;
CodeLen=2+AdrCnt;
END
END
return;
END
if ((Memo("PUSH")) OR (Memo("PUSHU")))
BEGIN
z=Ord(Memo("PUSHU"));
if (ArgCnt!=1) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg+MModIReg+MModImm);
switch (AdrMode)
BEGIN
case ModReg:
BAsmCode[0]=0x66-(z*0x36); BAsmCode[1]=AdrVals[0];
CodeLen=2;
break;
case ModIReg:
BAsmCode[0]=0xf7-(z*0xc6); BAsmCode[1]=AdrVals[0];
CodeLen=2;
break;
case ModImm:
BAsmCode[0]=0x8f; BAsmCode[1]=0xf1+(z*2);
BAsmCode[2]=AdrVals[0]; CodeLen=3;
break;
END
END
return;
END
if ((Memo("PUSHW")) OR (Memo("PUSHUW")))
BEGIN
z=Ord(Memo("PUSHUW")); OpSize=1;
if (ArgCnt!=1) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModRReg+MModImm);
switch (AdrMode)
BEGIN
case ModRReg:
BAsmCode[0]=0x74+(z*0x42); BAsmCode[1]=AdrVals[0];
CodeLen=2;
break;
case ModImm:
BAsmCode[0]=0x8f; BAsmCode[1]=0xc1+(z*2);
memcpy(BAsmCode+2,AdrVals,AdrCnt); CodeLen=2+AdrCnt;
break;
END
END
return;
END
if (Memo("XCH"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg);
if (AdrMode==ModReg)
BEGIN
BAsmCode[2]=AdrVals[0];
DecodeAdr(ArgStr[2],MModReg);
if (AdrMode==ModReg)
BEGIN
BAsmCode[1]=AdrVals[0];
BAsmCode[0]=0x16;
CodeLen=3;
END
END
END
return;
END
/* Arithmetik */
for (z=0; z<ALUOrderCnt; z++)
if ((strncmp(OpPart,ALUOrders[z].Name,ALUOrders[z].len)==0) AND ((OpPart[ALUOrders[z].len]=='\0') OR (OpPart[ALUOrders[z].len]=='W')))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
if (OpPart[strlen(OpPart)-1]=='W')
BEGIN
OpSize=1; Mask1=MModWRReg; Mask2=MModRReg;
END
else
BEGIN
Mask1=MModWReg; Mask2=MModReg;
END
DecodeAdr(ArgStr[1],Mask1+Mask2+MModIWReg+MModIWRReg+MModIncWRReg+
MModDecWRReg+MModDispRWRReg+MModDisp8WRReg+MModDisp16WRReg+
MModAbs+MModIRReg);
switch (AdrMode)
BEGIN
case ModWReg:
case ModWRReg:
HReg=AdrPart;
DecodeAdr(ArgStr[2],Mask1+MModIWReg+Mask2+MModIWRReg+MModIncWRReg+
MModDecWRReg+MModDispRWRReg+MModDisp8WRReg+MModDisp16WRReg+
MModAbs+MModImm);
switch (AdrMode)
BEGIN
case ModWReg:
case ModWRReg:
BAsmCode[0]=(ALUOrders[z].Code << 4)+2+(OpSize*12);
BAsmCode[1]=(HReg << 4)+AdrPart;
CodeLen=2;
break;
case ModIWReg:
if (OpSize==0)
BEGIN
BAsmCode[0]=(ALUOrders[z].Code << 4)+3; BAsmCode[1]=(HReg << 4)+AdrPart;
CodeLen=2;
END
else
BEGIN
BAsmCode[0]=0xa6; BAsmCode[1]=(ALUOrders[z].Code << 4)+AdrPart;
BAsmCode[2]=WorkOfs+HReg; CodeLen=3;
END
break;
case ModReg:
case ModRReg:
BAsmCode[0]=(ALUOrders[z].Code << 4)+4+(OpSize*3);
BAsmCode[1]=AdrVals[0]; BAsmCode[2]=HReg+WorkOfs;
CodeLen=3;
break;
case ModIWRReg:
if (OpSize==0)
BEGIN
BAsmCode[0]=0x72; BAsmCode[1]=(ALUOrders[z].Code << 4)+AdrPart+1;
BAsmCode[2]=HReg+WorkOfs;
CodeLen=3;
END
else
BEGIN
BAsmCode[0]=(ALUOrders[z].Code << 4)+0x0e;
BAsmCode[1]=(HReg << 4)+AdrPart+1;
CodeLen=2;
END
break;
case ModIncWRReg:
BAsmCode[0]=0xb4+(OpSize*0x21);
BAsmCode[1]=(ALUOrders[z].Code << 4)+AdrPart+1;
BAsmCode[2]=HReg+WorkOfs;
CodeLen=3;
break;
case ModDecWRReg:
BAsmCode[0]=0xc2+OpSize;
BAsmCode[1]=(ALUOrders[z].Code << 4)+AdrPart+1;
BAsmCode[2]=HReg+WorkOfs;
CodeLen=3;
break;
case ModDispRWRReg:
BAsmCode[0]=0x60;
BAsmCode[1]=0x10*(1-OpSize)+(AdrVals[0] << 4)+AdrPart;
BAsmCode[2]=(ALUOrders[z].Code << 4)+HReg;
CodeLen=3;
break;
case ModDisp8WRReg:
BAsmCode[0]=0x7f+(OpSize*7);
BAsmCode[1]=(ALUOrders[z].Code << 4)+AdrPart+1;
BAsmCode[2]=AdrVals[0]; BAsmCode[3]=WorkOfs+HReg;
CodeLen=4;
break;
case ModDisp16WRReg:
BAsmCode[0]=0x7f+(OpSize*7);
BAsmCode[1]=(ALUOrders[z].Code << 4)+AdrPart;
memcpy(BAsmCode+2,AdrVals,AdrCnt);
BAsmCode[2+AdrCnt]=WorkOfs+HReg;
CodeLen=3+AdrCnt;
break;
case ModAbs:
BAsmCode[0]=0xc4+(OpSize*30);
BAsmCode[1]=(ALUOrders[z].Code << 4)+HReg;
memcpy(BAsmCode+2,AdrVals,AdrCnt);
CodeLen=2+AdrCnt;
break;
case ModImm:
BAsmCode[0]=(ALUOrders[z].Code << 4)+5+(OpSize*2);
BAsmCode[1]=WorkOfs+HReg+OpSize;
memcpy(BAsmCode+2,AdrVals,AdrCnt);
CodeLen=2+AdrCnt;
break;
END
break;
case ModReg:
case ModRReg:
HReg=AdrVals[0];
DecodeAdr(ArgStr[2],Mask2+MModIWReg+MModIWRReg+MModIncWRReg+MModDecWRReg+
MModDisp8WRReg+MModDisp16WRReg+MModImm);
switch (AdrMode)
BEGIN
case ModReg:
case ModRReg:
BAsmCode[0]=(ALUOrders[z].Code << 4)+4+(OpSize*3); CodeLen=3;
BAsmCode[1]=AdrVals[0]; BAsmCode[2]=HReg;
break;
case ModIWReg:
BAsmCode[0]=0xa6+65*(1-OpSize);
BAsmCode[1]=(ALUOrders[z].Code << 4)+AdrPart;
BAsmCode[2]=HReg; CodeLen=3;
break;
case ModIWRReg:
BAsmCode[0]=0x72+(OpSize*12);
BAsmCode[1]=(ALUOrders[z].Code << 4)+AdrPart+(1-OpSize);
BAsmCode[2]=HReg; CodeLen=3;
break;
case ModIncWRReg:
BAsmCode[0]=0xb4+(OpSize*0x21);
BAsmCode[1]=(ALUOrders[z].Code << 4)+AdrPart+1;
BAsmCode[2]=HReg; CodeLen=3;
break;
case ModDecWRReg:
BAsmCode[0]=0xc2+OpSize;
BAsmCode[1]=(ALUOrders[z].Code << 4)+AdrPart+1;
BAsmCode[2]=HReg; CodeLen=3;
break;
case ModDisp8WRReg:
BAsmCode[0]=0x7f+(OpSize*7);
BAsmCode[1]=(ALUOrders[z].Code << 4)+AdrPart+1;
BAsmCode[2]=AdrVals[0]; BAsmCode[3]=HReg; CodeLen=4;
break;
case ModDisp16WRReg:
BAsmCode[0]=0x7f+(OpSize*7);
BAsmCode[1]=(ALUOrders[z].Code << 4)+AdrPart;
memcpy(BAsmCode+2,AdrVals,AdrCnt); BAsmCode[2+AdrCnt]=HReg;
CodeLen=3+AdrCnt;
break;
case ModImm:
BAsmCode[0]=(ALUOrders[z].Code << 4)+5+(OpSize*2);
memcpy(BAsmCode+2,AdrVals,AdrCnt); BAsmCode[1]=HReg+OpSize;
CodeLen=2+AdrCnt;
break;
END
break;
case ModIWReg:
HReg=AdrPart;
DecodeAdr(ArgStr[2],Mask2);
switch (AdrMode)
BEGIN
case ModReg:
case ModRReg:
BAsmCode[0]=0xe6-(OpSize*0x50); BAsmCode[1]=AdrVals[0];
BAsmCode[2]=(ALUOrders[z].Code << 4)+HReg; CodeLen=3;
break;
END
break;
case ModIWRReg:
HReg=AdrPart;
DecodeAdr(ArgStr[2],(OpSize*MModWRReg)+Mask2+MModIWRReg+MModImm);
switch (AdrMode)
BEGIN
case ModWRReg:
BAsmCode[0]=(ALUOrders[z].Code << 4)+0x0e;
BAsmCode[1]=(HReg << 4)+0x10+AdrPart; CodeLen=2;
break;
case ModReg:
case ModRReg:
BAsmCode[0]=0x72+(OpSize*76);
BAsmCode[1]=(ALUOrders[z].Code << 4)+HReg+OpSize;
BAsmCode[2]=AdrVals[0]; CodeLen=3;
break;
case ModIWRReg:
if (OpSize==0)
BEGIN
BAsmCode[0]=0x73; BAsmCode[1]=(ALUOrders[z].Code << 4)+AdrPart;
BAsmCode[2]=HReg+WorkOfs; CodeLen=3;
END
else
BEGIN
BAsmCode[0]=(ALUOrders[z].Code << 4)+0x0e;
BAsmCode[1]=0x11+(HReg << 4)+AdrPart;
CodeLen=2;
END
break;
case ModImm:
BAsmCode[0]=0xf3-(OpSize*0x35);
BAsmCode[1]=(ALUOrders[z].Code << 4)+HReg;
memcpy(BAsmCode+2,AdrVals,AdrCnt); CodeLen=2+AdrCnt;
break;
END
break;
case ModIncWRReg:
HReg=AdrPart;
DecodeAdr(ArgStr[2],Mask2);
switch (AdrMode)
BEGIN
case ModReg:
case ModRReg:
BAsmCode[0]=0xb4+(OpSize*0x21);
BAsmCode[1]=(ALUOrders[z].Code << 4)+HReg;
BAsmCode[2]=AdrVals[0]; CodeLen=3;
break;
END
break;
case ModDecWRReg:
HReg=AdrPart;
DecodeAdr(ArgStr[2],Mask2);
switch (AdrMode)
BEGIN
case ModReg:
case ModRReg:
BAsmCode[0]=0xc2+OpSize;
BAsmCode[1]=(ALUOrders[z].Code << 4)+HReg;
BAsmCode[2]=AdrVals[0]; CodeLen=3;
break;
END
break;
case ModDispRWRReg:
HReg=AdrPart; HPart=AdrVals[0];
DecodeAdr(ArgStr[2],Mask1);
switch (AdrMode)
BEGIN
case ModWReg:
case ModWRReg:
BAsmCode[0]=0x60;
BAsmCode[1]=0x11-(OpSize*0x10)+(HPart << 4)+HReg;
BAsmCode[2]=(ALUOrders[z].Code << 4)+AdrPart; CodeLen=3;
break;
END
break;
case ModDisp8WRReg:
HReg=AdrPart; BAsmCode[2]=AdrVals[0];
DecodeAdr(ArgStr[2],Mask2+(OpSize*MModImm));
switch (AdrMode)
BEGIN
case ModReg:
case ModRReg:
BAsmCode[0]=0x26+(OpSize*0x60);
BAsmCode[1]=(ALUOrders[z].Code << 4)+HReg+1;
BAsmCode[3]=AdrVals[0]+OpSize; CodeLen=4;
break;
case ModImm:
BAsmCode[0]=0x06; BAsmCode[1]=(ALUOrders[z].Code << 4)+HReg+1;
memcpy(BAsmCode+3,AdrVals,AdrCnt); CodeLen=3+AdrCnt;
break;
END
break;
case ModDisp16WRReg:
HReg=AdrPart; memcpy(BAsmCode+2,AdrVals,2);
DecodeAdr(ArgStr[2],Mask2+(OpSize*MModImm));
switch (AdrMode)
BEGIN
case ModReg:
case ModRReg:
BAsmCode[0]=0x26+(OpSize*0x60);
BAsmCode[1]=(ALUOrders[z].Code << 4)+HReg;
BAsmCode[4]=AdrVals[0]+OpSize; CodeLen=5;
break;
case ModImm:
BAsmCode[0]=0x06; BAsmCode[1]=(ALUOrders[z].Code << 4)+HReg;
memcpy(BAsmCode+4,AdrVals,AdrCnt); CodeLen=4+AdrCnt;
break;
END
break;
case ModAbs:
memcpy(BAsmCode+2,AdrVals,2);
DecodeAdr(ArgStr[2],Mask1+MModImm);
switch (AdrMode)
BEGIN
case ModWReg:
case ModWRReg:
BAsmCode[0]=0xc5+(OpSize*29);
BAsmCode[1]=(ALUOrders[z].Code << 4)+AdrPart+OpSize;
CodeLen=4;
break;
case ModImm:
memmove(BAsmCode+2+AdrCnt,BAsmCode+2,2); memcpy(BAsmCode+2,AdrVals,AdrCnt);
BAsmCode[0]=0x2f+(OpSize*7);
BAsmCode[1]=(ALUOrders[z].Code << 4)+1;
CodeLen=4+AdrCnt;
break;
END
break;
case ModIRReg:
HReg=AdrVals[0];
DecodeAdr(ArgStr[2],MModIWRReg*(1-OpSize));
switch (AdrMode)
BEGIN
case ModIWRReg:
BAsmCode[0]=0x73; BAsmCode[1]=(ALUOrders[z].Code << 4)+AdrPart;
BAsmCode[2]=HReg; CodeLen=3;
break;
END
break;
END
END
return;
END
for (z=0; z<RegOrderCnt; z++)
if (Memo(RegOrders[z].Name))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModReg+MModIReg);
switch (AdrMode)
BEGIN
case ModReg:
BAsmCode[0]=RegOrders[z].Code; BAsmCode[1]=AdrVals[0]; CodeLen=2;
break;
case ModIReg:
BAsmCode[0]=RegOrders[z].Code+1; BAsmCode[1]=AdrVals[0]; CodeLen=2;
break;
END
END
return;
END
for (z=0; z<Reg16OrderCnt; z++)
if (Memo(Reg16Orders[z].Name))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModRReg);
switch (AdrMode)
BEGIN
case ModRReg:
BAsmCode[0]=Reg16Orders[z].Code; BAsmCode[1]=AdrVals[0]+Ord(Memo("EXT"));
CodeLen=2;
break;
END
END
return;
END
if ((Memo("DIV")) OR (Memo("MUL")))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModWRReg);
if (AdrMode==ModWRReg)
BEGIN
HReg=AdrPart;
DecodeAdr(ArgStr[2],MModWReg);
if (AdrMode==ModWReg)
BEGIN
BAsmCode[0]=0x5f-(0x10*Ord(Memo("MUL")));
BAsmCode[1]=(HReg << 4)+AdrPart;
CodeLen=2;
END
END
END
return;
END
if (Memo("DIVWS"))
BEGIN
if (ArgCnt!=3) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModWRReg);
if (AdrMode==ModWRReg)
BEGIN
HReg=AdrPart;
DecodeAdr(ArgStr[2],MModWRReg);
if (AdrMode==ModWRReg)
BEGIN
BAsmCode[2]=(HReg << 4)+AdrPart;
DecodeAdr(ArgStr[3],MModRReg);
if (AdrMode==ModRReg)
BEGIN
BAsmCode[0]=0x56; BAsmCode[1]=AdrVals[0];
CodeLen=3;
END
END
END
END
return;
END
/* Bitoperationen */
for (z=0; z<Bit2OrderCnt; z++)
if (Memo(Bit2Orders[z].Name))
BEGIN
if (ArgCnt!=2) WrError(1110);
else if (SplitBit(ArgStr[1],&HReg))
if (Odd(HReg)) WrError(1350);
else
BEGIN
DecodeAdr(ArgStr[1],MModWReg);
if (AdrMode==ModWReg)
BEGIN
HReg=(HReg << 4)+AdrPart;
if (SplitBit(ArgStr[2],&HPart))
BEGIN
DecodeAdr(ArgStr[2],MModWReg);
if (AdrMode==ModWReg)
BEGIN
HPart=(HPart << 4)+AdrPart;
BAsmCode[0]=Bit2Orders[z].Code;
if (Memo("BLD"))
BEGIN
BAsmCode[1]=HPart | 0x10; BAsmCode[2]=HReg | (HPart & 0x10);
END
else if (Memo("BXOR"))
BEGIN
BAsmCode[1]=0x10+HReg; BAsmCode[2]=HPart;
END
else
BEGIN
BAsmCode[1]=0x10+HReg; BAsmCode[2]=HPart ^ 0x10;
END
CodeLen=3;
END
END
END
END
return;
END
for (z=0; z<Bit1OrderCnt; z++)
if (Memo(Bit1Orders[z].Name))
BEGIN
if (ArgCnt!=1) WrError(1110);
else if (SplitBit(ArgStr[1],&HReg))
if (Odd(HReg)) WrError(1350);
else
BEGIN
DecodeAdr(ArgStr[1],MModWReg+(Ord(Memo("BTSET"))*MModIWRReg));
switch (AdrMode)
BEGIN
case ModWReg:
BAsmCode[0]=Bit1Orders[z].Code; BAsmCode[1]=(HReg << 4)+AdrPart;
CodeLen=2;
break;
case ModIWRReg:
BAsmCode[0]=0xf6; BAsmCode[1]=(HReg << 4)+AdrPart;
CodeLen=2;
break;
END
END
return;
END
/* Spruenge */
if ((Memo("BTJF")) OR (Memo("BTJT")))
BEGIN
if (ArgCnt!=2) WrError(1110);
else if (SplitBit(ArgStr[1],&HReg))
if (Odd(HReg)) WrError(1350);
else
BEGIN
DecodeAdr(ArgStr[1],MModWReg);
if (AdrMode==ModWReg)
BEGIN
BAsmCode[1]=(HReg << 4)+AdrPart+(Ord(Memo("BTJF")) << 4);
AdrInt=EvalIntExpression(ArgStr[2],UInt16,&OK)-(EProgCounter()+3);
if (OK)
if ((NOT SymbolQuestionable) AND ((AdrInt<-128) OR (AdrInt>127))) WrError(1370);
else
BEGIN
BAsmCode[0]=0xaf; BAsmCode[2]=AdrInt & 0xff; CodeLen=3;
ChkSpace(SegCode);
END
END
END
return;
END
if ((Memo("JP")) OR (Memo("CALL")))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
AbsSeg=SegCode;
DecodeAdr(ArgStr[1],MModIRReg+MModAbs);
switch (AdrMode)
BEGIN
case ModIRReg:
BAsmCode[0]=0x74+(Ord(Memo("JP"))*0x60);
BAsmCode[1]=AdrVals[0]+Ord(Memo("CALL")); CodeLen=2;
break;
case ModAbs:
BAsmCode[0]=0x8d+(Ord(Memo("CALL"))*0x45);
memcpy(BAsmCode+1,AdrVals,AdrCnt); CodeLen=1+AdrCnt;
break;
END
END
return;
END
if ((Memo("CPJFI")) OR (Memo("CPJTI")))
BEGIN
if (ArgCnt!=3) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModWReg);
if (AdrMode==ModWReg)
BEGIN
HReg=AdrPart;
DecodeAdr(ArgStr[2],MModIWRReg);
if (AdrMode==ModIWRReg)
BEGIN
BAsmCode[1]=(AdrPart << 4)+(Ord(Memo("CPJTI")) << 4)+HReg;
AdrInt=EvalIntExpression(ArgStr[3],UInt16,&OK)-(EProgCounter()+3);
if (OK)
if ((NOT SymbolQuestionable) AND ((AdrInt<-128) OR (AdrInt>127))) WrError(1370);
else
BEGIN
ChkSpace(SegCode);
BAsmCode[0]=0x9f; BAsmCode[2]=AdrInt & 0xff;
CodeLen=3;
END
END
END
END
return;
END
if (Memo("DJNZ"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModWReg);
if (AdrMode==ModWReg)
BEGIN
BAsmCode[0]=(AdrPart << 4)+0x0a;
AdrInt=EvalIntExpression(ArgStr[2],UInt16,&OK)-(EProgCounter()+2);
if (OK)
if ((NOT SymbolQuestionable) AND ((AdrInt<-128) OR (AdrInt>127))) WrError(1370);
else
BEGIN
ChkSpace(SegCode);
BAsmCode[1]=AdrInt & 0xff;
CodeLen=2;
END
END
END
return;
END
if (Memo("DWJNZ"))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModRReg);
if (AdrMode==ModRReg)
BEGIN
BAsmCode[1]=AdrVals[0];
AdrInt=EvalIntExpression(ArgStr[2],UInt16,&OK)-(EProgCounter()+3);
if (OK)
if ((NOT SymbolQuestionable) AND ((AdrInt<-128) OR (AdrInt>127))) WrError(1370);
else
BEGIN
ChkSpace(SegCode);
BAsmCode[0]=0xc6; BAsmCode[2]=AdrInt & 0xff;
CodeLen=3;
END
END
END
return;
END
for (z=0; z<ConditionCnt; z++)
if ((*OpPart=='J') AND (OpPart[1]=='P') AND (strcmp(OpPart+2,Conditions[z].Name)==0))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
AdrWord=EvalIntExpression(ArgStr[1],UInt16,&OK);
if (OK)
BEGIN
ChkSpace(SegCode);
BAsmCode[0]=0x0d+(Conditions[z].Code << 4);
BAsmCode[1]=Hi(AdrWord); BAsmCode[2]=Lo(AdrWord);
CodeLen=3;
END
END
return;
END
else if ((*OpPart=='J') AND (OpPart[1]=='R') AND (strcmp(OpPart+2,Conditions[z].Name)==0))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
AdrInt=EvalIntExpression(ArgStr[1],UInt16,&OK)-(EProgCounter()+2);
if (OK)
if ((NOT SymbolQuestionable) AND ((AdrInt<-128) OR (AdrInt>127))) WrError(1370);
else
BEGIN
ChkSpace(SegCode);
BAsmCode[0]=0x0b+(Conditions[z].Code << 4); BAsmCode[1]=AdrInt & 0xff;
CodeLen=2;
END
END
return;
END
/* Besonderheiten */
if (Memo("SPP"))
BEGIN
if (ArgCnt!=1) WrError(1110);
else if (*ArgStr[1]!='#') WrError(1350);
else
BEGIN
BAsmCode[1]=(EvalIntExpression(ArgStr[1]+1,UInt6,&OK) << 2)+0x02;
if (OK)
BEGIN
BAsmCode[0]=0xc7; CodeLen=2;
END
END
return;
END
if ((Memo("SRP")) OR (Memo("SRP0")) OR (Memo("SRP1")))
BEGIN
if (ArgCnt!=1) WrError(1110);
else if (*ArgStr[1]!='#') WrError(1350);
else
BEGIN
BAsmCode[1]=EvalIntExpression(ArgStr[1]+1,UInt5,&OK) << 3;
if (OK)
BEGIN
BAsmCode[0]=0xc7; CodeLen=2;
if (strlen(OpPart)==4) BAsmCode[1]+=4;
if (OpPart[strlen(OpPart)-1]=='1') BAsmCode[1]++;
END
END
return;
END
/* Fakes... */
if (Memo("SLA"))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModWReg+MModReg+MModIWRReg);
switch (AdrMode)
BEGIN
case ModWReg:
BAsmCode[0]=0x42; BAsmCode[1]=(AdrPart << 4)+AdrPart;
CodeLen=2;
break;
case ModReg:
BAsmCode[0]=0x44;
BAsmCode[1]=AdrVals[0];
BAsmCode[2]=AdrVals[0];
CodeLen=3;
break;
case ModIWRReg:
BAsmCode[0]=0x73; BAsmCode[1]=0x40+AdrPart;
BAsmCode[2]=WorkOfs+AdrPart; CodeLen=3;
break;
END
END
return;
END
if (Memo("SLAW"))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
DecodeAdr(ArgStr[1],MModWRReg+MModRReg+MModIWRReg);
switch (AdrMode)
BEGIN
case ModWRReg:
BAsmCode[0]=0x4e; BAsmCode[1]=(AdrPart << 4)+AdrPart;
CodeLen=2;
break;
case ModRReg:
BAsmCode[0]=0x47;
BAsmCode[1]=AdrVals[0];
BAsmCode[2]=AdrVals[0];
CodeLen=3;
break;
case ModIWRReg:
BAsmCode[0]=0x4e; BAsmCode[1]=0x11+(AdrPart << 4)+AdrPart;
CodeLen=2;
break;
END
END
return;
END
WrXError(1200,OpPart);
END
static void InitCode_ST9(void)
BEGIN
SaveInitProc();
DPAssume=0;
END
static Boolean IsDef_ST9(void)
BEGIN
return (Memo("REG") OR Memo("BIT"));
END
static void SwitchFrom_ST9(void)
BEGIN
DeinitFields();
END
static void InternSymbol_ST9(char *Asc, TempResult *Erg)
BEGIN
String h;
Boolean Err;
Boolean Pair;
Erg->Typ=TempNone;
if ((strlen(Asc)<2) OR (*Asc!='R')) return;
strmaxcpy(h,Asc+1,255);
if (*h=='R')
BEGIN
if (strlen(h)<2) return;
Pair=True; strcpy(h,h+1);
END
else Pair=False;
Erg->Contents.Int=ConstLongInt(h,&Err);
if ((NOT Err) OR (Erg->Contents.Int<0) OR (Erg->Contents.Int>255)) return;
if ((Erg->Contents.Int & 0xf0)==0xd0) return;
if ((Pair) AND (Odd(Erg->Contents.Int))) return;
if (Pair) Erg->Contents.Int+=0x100;
Erg->Typ=TempInt; TypeFlag|=(1 << SegReg);
END
static void SwitchTo_ST9(void)
BEGIN
TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False;
PCSymbol="PC"; HeaderID=0x32; NOPCode=0xff;
DivideChars=","; HasAttrs=False;
ValidSegs=(1<<SegCode)|(1<<SegData)|(1<<SegReg);
Grans[SegCode]=1; ListGrans[SegCode]=1; SegInits[SegCode]=0;
SegLimits[SegCode] = 0xffff;
Grans[SegData]=1; ListGrans[SegData]=1; SegInits[SegData]=0;
SegLimits[SegData] = 0xffff;
Grans[SegReg ]=1; ListGrans[SegReg ]=1; SegInits[SegReg ]=0;
SegLimits[SegReg ] = 0xff;
MakeCode=MakeCode_ST9; IsDef=IsDef_ST9;
SwitchFrom=SwitchFrom_ST9; InternSymbol=InternSymbol_ST9;
InitFields();
END
void codest9_init(void)
BEGIN
CPUST9020=AddCPU("ST9020",SwitchTo_ST9);
CPUST9030=AddCPU("ST9030",SwitchTo_ST9);
CPUST9040=AddCPU("ST9040",SwitchTo_ST9);
CPUST9050=AddCPU("ST9050",SwitchTo_ST9);
SaveInitProc=InitPassProc; InitPassProc=InitCode_ST9;
END