888 lines
25 KiB
C
888 lines
25 KiB
C
/* code29k.c */
|
|
/*****************************************************************************/
|
|
/* AS-Portierung */
|
|
/* */
|
|
/* Codegenerator AM29xxx-Familie */
|
|
/* */
|
|
/* Historie: 18.11.1996 Grundsteinlegung */
|
|
/* 3. 1.1999 ChkPC-Anpassung */
|
|
/* */
|
|
/*****************************************************************************/
|
|
|
|
#include "stdinc.h"
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
|
|
#include "nls.h"
|
|
#include "strutil.h"
|
|
#include "bpemu.h"
|
|
#include "stringlists.h"
|
|
#include "asmdef.h"
|
|
#include "asmsub.h"
|
|
#include "asmpars.h"
|
|
#include "asmallg.h"
|
|
#include "codepseudo.h"
|
|
#include "codevars.h"
|
|
|
|
typedef struct
|
|
{
|
|
char *Name;
|
|
Boolean MustSup;
|
|
CPUVar MinCPU;
|
|
LongWord Code;
|
|
} StdOrder;
|
|
|
|
typedef struct
|
|
{
|
|
char *Name;
|
|
Boolean HasReg,HasInd;
|
|
CPUVar MinCPU;
|
|
LongWord Code;
|
|
} JmpOrder;
|
|
|
|
typedef struct
|
|
{
|
|
char *Name;
|
|
LongWord Code;
|
|
} SPReg;
|
|
|
|
#define StdOrderCount 51
|
|
#define NoImmOrderCount 22
|
|
#define VecOrderCount 10
|
|
#define JmpOrderCount 5
|
|
#define FixedOrderCount 2
|
|
#define MemOrderCount 7
|
|
#define SPRegCount 28
|
|
|
|
static StdOrder *StdOrders;
|
|
static StdOrder *NoImmOrders;
|
|
static StdOrder *VecOrders;
|
|
static JmpOrder *JmpOrders;
|
|
static StdOrder *FixedOrders;
|
|
static StdOrder *MemOrders;
|
|
static SPReg *SPRegs;
|
|
|
|
|
|
static CPUVar CPU29000,CPU29240,CPU29243,CPU29245;
|
|
static LongInt Reg_RBP;
|
|
static StringList Emulations;
|
|
static SimpProc SaveInitProc;
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
static void AddStd(char *NName, CPUVar NMin, Boolean NSup, LongWord NCode)
|
|
BEGIN
|
|
if (InstrZ>=StdOrderCount) exit(255);
|
|
StdOrders[InstrZ].Name=NName;
|
|
StdOrders[InstrZ].Code=NCode;
|
|
StdOrders[InstrZ].MustSup=NSup;
|
|
StdOrders[InstrZ++].MinCPU=NMin;
|
|
END
|
|
|
|
static void AddNoImm(char *NName, CPUVar NMin, Boolean NSup, LongWord NCode)
|
|
BEGIN
|
|
if (InstrZ>=NoImmOrderCount) exit(255);
|
|
NoImmOrders[InstrZ].Name=NName;
|
|
NoImmOrders[InstrZ].Code=NCode;
|
|
NoImmOrders[InstrZ].MustSup=NSup;
|
|
NoImmOrders[InstrZ++].MinCPU=NMin;
|
|
END
|
|
|
|
static void AddVec(char *NName, CPUVar NMin, Boolean NSup, LongWord NCode)
|
|
BEGIN
|
|
if (InstrZ>=VecOrderCount) exit(255);
|
|
VecOrders[InstrZ].Name=NName;
|
|
VecOrders[InstrZ].Code=NCode;
|
|
VecOrders[InstrZ].MustSup=NSup;
|
|
VecOrders[InstrZ++].MinCPU=NMin;
|
|
END
|
|
|
|
static void AddJmp(char *NName, CPUVar NMin, Boolean NHas, Boolean NInd, LongWord NCode)
|
|
BEGIN
|
|
if (InstrZ>=JmpOrderCount) exit(255);
|
|
JmpOrders[InstrZ].Name=NName;
|
|
JmpOrders[InstrZ].HasReg=NHas;
|
|
JmpOrders[InstrZ].HasInd=NInd;
|
|
JmpOrders[InstrZ].Code=NCode;
|
|
JmpOrders[InstrZ++].MinCPU=NMin;
|
|
END
|
|
|
|
static void AddFixed(char *NName, CPUVar NMin, Boolean NSup, LongWord NCode)
|
|
BEGIN
|
|
if (InstrZ>=FixedOrderCount) exit(255);
|
|
FixedOrders[InstrZ].Name=NName;
|
|
FixedOrders[InstrZ].Code=NCode;
|
|
FixedOrders[InstrZ].MustSup=NSup;
|
|
FixedOrders[InstrZ++].MinCPU=NMin;
|
|
END
|
|
|
|
static void AddMem(char *NName, CPUVar NMin, Boolean NSup, LongWord NCode)
|
|
BEGIN
|
|
if (InstrZ>=MemOrderCount) exit(255);
|
|
MemOrders[InstrZ].Name=NName;
|
|
MemOrders[InstrZ].Code=NCode;
|
|
MemOrders[InstrZ].MustSup=NSup;
|
|
MemOrders[InstrZ++].MinCPU=NMin;
|
|
END
|
|
|
|
static void AddSP(char *NName, LongWord NCode)
|
|
BEGIN
|
|
if (InstrZ>=SPRegCount) exit(255);
|
|
SPRegs[InstrZ].Name=NName;
|
|
SPRegs[InstrZ++].Code=NCode;
|
|
END
|
|
|
|
static void InitFields(void)
|
|
BEGIN
|
|
StdOrders=(StdOrder *) malloc(sizeof(StdOrder)*StdOrderCount); InstrZ=0;
|
|
AddStd("ADD" ,CPU29245,False,0x14); AddStd("ADDC" ,CPU29245,False,0x1c);
|
|
AddStd("ADDCS" ,CPU29245,False,0x18); AddStd("ADDCU" ,CPU29245,False,0x1a);
|
|
AddStd("ADDS" ,CPU29245,False,0x10); AddStd("ADDU" ,CPU29245,False,0x12);
|
|
AddStd("AND" ,CPU29245,False,0x90); AddStd("ANDN" ,CPU29245,False,0x9c);
|
|
AddStd("CPBYTE" ,CPU29245,False,0x2e); AddStd("CPEQ" ,CPU29245,False,0x60);
|
|
AddStd("CPGE" ,CPU29245,False,0x4c); AddStd("CPGEU" ,CPU29245,False,0x4e);
|
|
AddStd("CPGT" ,CPU29245,False,0x48); AddStd("CPGTU" ,CPU29245,False,0x4a);
|
|
AddStd("CPLE" ,CPU29245,False,0x44); AddStd("CPLEU" ,CPU29245,False,0x46);
|
|
AddStd("CPLT" ,CPU29245,False,0x40); AddStd("CPLTU" ,CPU29245,False,0x42);
|
|
AddStd("CPNEQ" ,CPU29245,False,0x62); AddStd("DIV" ,CPU29245,False,0x6a);
|
|
AddStd("DIV0" ,CPU29245,False,0x68); AddStd("DIVL" ,CPU29245,False,0x6c);
|
|
AddStd("DIVREM" ,CPU29245,False,0x6e); AddStd("EXBYTE" ,CPU29245,False,0x0a);
|
|
AddStd("EXHW" ,CPU29245,False,0x7c); AddStd("EXTRACT",CPU29245,False,0x7a);
|
|
AddStd("INBYTE" ,CPU29245,False,0x0c); AddStd("INHW" ,CPU29245,False,0x78);
|
|
AddStd("MUL" ,CPU29245,False,0x64); AddStd("MULL" ,CPU29245,False,0x66);
|
|
AddStd("MULU" ,CPU29245,False,0x74); AddStd("NAND" ,CPU29245,False,0x9a);
|
|
AddStd("NOR" ,CPU29245,False,0x98); AddStd("OR" ,CPU29245,False,0x92);
|
|
AddStd("SLL" ,CPU29245,False,0x80); AddStd("SRA" ,CPU29245,False,0x86);
|
|
AddStd("SRL" ,CPU29245,False,0x82); AddStd("SUB" ,CPU29245,False,0x24);
|
|
AddStd("SUBC" ,CPU29245,False,0x2c); AddStd("SUBCS" ,CPU29245,False,0x28);
|
|
AddStd("SUBCU" ,CPU29245,False,0x2a); AddStd("SUBR" ,CPU29245,False,0x34);
|
|
AddStd("SUBRC" ,CPU29245,False,0x3c); AddStd("SUBRCS" ,CPU29245,False,0x38);
|
|
AddStd("SUBRCU" ,CPU29245,False,0x3a); AddStd("SUBRS" ,CPU29245,False,0x30);
|
|
AddStd("SUBRU" ,CPU29245,False,0x32); AddStd("SUBS" ,CPU29245,False,0x20);
|
|
AddStd("SUBU" ,CPU29245,False,0x22); AddStd("XNOR" ,CPU29245,False,0x96);
|
|
AddStd("XOR" ,CPU29245,False,0x94);
|
|
|
|
NoImmOrders=(StdOrder *) malloc(sizeof(StdOrder)*NoImmOrderCount); InstrZ=0;
|
|
AddNoImm("DADD" ,CPU29000,False,0xf1); AddNoImm("DDIV" ,CPU29000,False,0xf7);
|
|
AddNoImm("DEQ" ,CPU29000,False,0xeb); AddNoImm("DGE" ,CPU29000,False,0xef);
|
|
AddNoImm("DGT" ,CPU29000,False,0xed); AddNoImm("DIVIDE" ,CPU29000,False,0xe1);
|
|
AddNoImm("DIVIDU" ,CPU29000,False,0xe3); AddNoImm("DMUL" ,CPU29000,False,0xf5);
|
|
AddNoImm("DSUB" ,CPU29000,False,0xf3); AddNoImm("FADD" ,CPU29000,False,0xf0);
|
|
AddNoImm("FDIV" ,CPU29000,False,0xf6); AddNoImm("FDMUL" ,CPU29000,False,0xf9);
|
|
AddNoImm("FEQ" ,CPU29000,False,0xea); AddNoImm("FGE" ,CPU29000,False,0xee);
|
|
AddNoImm("FGT" ,CPU29000,False,0xec); AddNoImm("FMUL" ,CPU29000,False,0xf4);
|
|
AddNoImm("FSUB" ,CPU29000,False,0xf2); AddNoImm("MULTIPLU",CPU29243,False,0xe2);
|
|
AddNoImm("MULTIPLY",CPU29243,False,0xe0); AddNoImm("MULTM" ,CPU29243,False,0xde);
|
|
AddNoImm("MULTMU" ,CPU29243,False,0xdf); AddNoImm("SETIP" ,CPU29245,False,0x9e);
|
|
|
|
VecOrders=(StdOrder *) malloc(sizeof(StdOrder)*VecOrderCount); InstrZ=0;
|
|
AddVec("ASEQ" ,CPU29245,False,0x70); AddVec("ASGE" ,CPU29245,False,0x5c);
|
|
AddVec("ASGEU" ,CPU29245,False,0x5e); AddVec("ASGT" ,CPU29245,False,0x58);
|
|
AddVec("ASGTU" ,CPU29245,False,0x5a); AddVec("ASLE" ,CPU29245,False,0x54);
|
|
AddVec("ASLEU" ,CPU29245,False,0x56); AddVec("ASLT" ,CPU29245,False,0x50);
|
|
AddVec("ASLTU" ,CPU29245,False,0x52); AddVec("ASNEQ" ,CPU29245,False,0x72);
|
|
|
|
JmpOrders=(JmpOrder *) malloc(sizeof(JmpOrder)*JmpOrderCount); InstrZ=0;
|
|
AddJmp("CALL" ,CPU29245,True ,True ,0xa8); AddJmp("JMP" ,CPU29245,False,True ,0xa0);
|
|
AddJmp("JMPF" ,CPU29245,True ,True ,0xa4); AddJmp("JMPFDEC",CPU29245,True ,False,0xb4);
|
|
AddJmp("JMPT" ,CPU29245,True ,True ,0xac);
|
|
|
|
FixedOrders=(StdOrder *) malloc(sizeof(StdOrder)*FixedOrderCount); InstrZ=0;
|
|
AddFixed("HALT" ,CPU29245,True,0x89); AddFixed("IRET" ,CPU29245,True,0x88);
|
|
|
|
MemOrders=(StdOrder *) malloc(sizeof(StdOrder)*MemOrderCount); InstrZ=0;
|
|
AddMem("LOAD" ,CPU29245,False,0x16); AddMem("LOADL" ,CPU29245,False,0x06);
|
|
AddMem("LOADM" ,CPU29245,False,0x36); AddMem("LOADSET",CPU29245,False,0x26);
|
|
AddMem("STORE" ,CPU29245,False,0x1e); AddMem("STOREL" ,CPU29245,False,0x0e);
|
|
AddMem("STOREM" ,CPU29245,False,0x3e);
|
|
|
|
SPRegs=(SPReg *) malloc(sizeof(SPReg)*SPRegCount); InstrZ=0;
|
|
AddSP("VAB", 0);
|
|
AddSP("OPS", 1);
|
|
AddSP("CPS", 2);
|
|
AddSP("CFG", 3);
|
|
AddSP("CHA", 4);
|
|
AddSP("CHD", 5);
|
|
AddSP("CHC", 6);
|
|
AddSP("RBP", 7);
|
|
AddSP("TMC", 8);
|
|
AddSP("TMR", 9);
|
|
AddSP("PC0", 10);
|
|
AddSP("PC1", 11);
|
|
AddSP("PC2", 12);
|
|
AddSP("MMU", 13);
|
|
AddSP("LRU", 14);
|
|
AddSP("CIR", 29);
|
|
AddSP("CDR", 30);
|
|
AddSP("IPC", 128);
|
|
AddSP("IPA", 129);
|
|
AddSP("IPB", 130);
|
|
AddSP("Q", 131);
|
|
AddSP("ALU", 132);
|
|
AddSP("BP", 133);
|
|
AddSP("FC", 134);
|
|
AddSP("CR", 135);
|
|
AddSP("FPE", 160);
|
|
AddSP("INTE",161);
|
|
AddSP("FPS", 162);
|
|
END
|
|
|
|
static void DeinitFields(void)
|
|
BEGIN
|
|
free(StdOrders);
|
|
free(NoImmOrders);
|
|
free(VecOrders);
|
|
free(JmpOrders);
|
|
free(FixedOrders);
|
|
free(MemOrders);
|
|
free(SPRegs);
|
|
END
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
static void ChkSup(void)
|
|
BEGIN
|
|
if (NOT SupAllowed) WrError(50);
|
|
END
|
|
|
|
static Boolean IsSup(LongWord RegNo)
|
|
BEGIN
|
|
return ((RegNo<0x80) OR (RegNo>=0xa0));
|
|
END
|
|
|
|
static Boolean ChkCPU(CPUVar Min)
|
|
BEGIN
|
|
if (MomCPU>=Min) return True;
|
|
else return (StringListPresent(Emulations,OpPart));
|
|
END
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
static Boolean DecodeReg(char *Asc, LongWord *Erg)
|
|
BEGIN
|
|
Boolean io,OK;
|
|
|
|
if ((strlen(Asc)>=2) AND (toupper(*Asc)=='R'))
|
|
BEGIN
|
|
*Erg=ConstLongInt(Asc+1,&io);
|
|
OK=((io) AND (*Erg<=255));
|
|
END
|
|
else if ((strlen(Asc)>=3) AND (toupper(*Asc)=='G') AND (toupper(Asc[1])=='R'))
|
|
BEGIN
|
|
*Erg=ConstLongInt(Asc+2,&io);
|
|
OK=((io) AND (*Erg<=127));
|
|
END
|
|
else if ((strlen(Asc)>=3) AND (toupper(*Asc)=='L') AND (toupper(Asc[1])=='R'))
|
|
BEGIN
|
|
*Erg=ConstLongInt(Asc+2,&io);
|
|
OK=((io) AND (*Erg<=127));
|
|
*Erg+=128;
|
|
END
|
|
else OK=False;
|
|
if (OK)
|
|
if ((*Erg<127) AND (Odd(Reg_RBP >> ((*Erg) >> 4)))) ChkSup();
|
|
return OK;
|
|
END
|
|
|
|
static Boolean DecodeSpReg(char *Asc_O, LongWord *Erg)
|
|
BEGIN
|
|
int z;
|
|
String Asc;
|
|
|
|
strmaxcpy(Asc,Asc_O,255); NLS_UpString(Asc);
|
|
for (z=0; z<SPRegCount; z++)
|
|
if (strcmp(Asc,SPRegs[z].Name)==0)
|
|
BEGIN
|
|
*Erg=SPRegs[z].Code;
|
|
break;
|
|
END
|
|
return (z<SPRegCount);
|
|
END
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
static Boolean DecodePseudo(void)
|
|
BEGIN
|
|
#define ASSUME29KCount 1
|
|
static ASSUMERec ASSUME29Ks[ASSUME29KCount]=
|
|
{{"RBP", &Reg_RBP, 0, 0xff, 0x00000000}};
|
|
|
|
int z;
|
|
|
|
if (Memo("ASSUME"))
|
|
BEGIN
|
|
CodeASSUME(ASSUME29Ks,ASSUME29KCount);
|
|
return True;
|
|
END
|
|
|
|
if (Memo("EMULATED"))
|
|
BEGIN
|
|
if (ArgCnt<1) WrError(1110);
|
|
else
|
|
for (z=1; z<=ArgCnt; z++)
|
|
BEGIN
|
|
NLS_UpString(ArgStr[z]);
|
|
if (NOT StringListPresent(Emulations,ArgStr[z]))
|
|
AddStringListLast(&Emulations,ArgStr[z]);
|
|
END
|
|
return True;
|
|
END
|
|
|
|
return False;
|
|
END
|
|
|
|
static void MakeCode_29K(void)
|
|
BEGIN
|
|
int z,l;
|
|
LongWord Dest,Src1,Src2,Src3,AdrLong;
|
|
LongInt AdrInt;
|
|
Boolean OK;
|
|
|
|
CodeLen=0; DontPrint=False;
|
|
|
|
/* Nullanweisung */
|
|
|
|
if (Memo("") AND (*AttrPart=='\0') AND (ArgCnt==0)) return;
|
|
|
|
/* Pseudoanweisungen */
|
|
|
|
if (DecodePseudo()) return;
|
|
|
|
if (DecodeIntelPseudo(True)) return;
|
|
|
|
/* Variante 1: Register <-- Register op Register/uimm8 */
|
|
|
|
for (z=0; z<StdOrderCount; z++)
|
|
if (Memo(StdOrders[z].Name))
|
|
BEGIN
|
|
if ((ArgCnt>3) OR (ArgCnt<2)) WrError(1110);
|
|
else if (NOT DecodeReg(ArgStr[1],&Dest)) WrXError(1445,ArgStr[1]);
|
|
else
|
|
BEGIN
|
|
OK=True;
|
|
if (ArgCnt==2) Src1=Dest;
|
|
else OK=DecodeReg(ArgStr[2],&Src1);
|
|
if (NOT OK) WrXError(1445,ArgStr[2]);
|
|
else
|
|
BEGIN
|
|
if (DecodeReg(ArgStr[ArgCnt],&Src2))
|
|
BEGIN
|
|
OK=True; Src3=0;
|
|
END
|
|
else
|
|
BEGIN
|
|
Src2=EvalIntExpression(ArgStr[ArgCnt],UInt8,&OK);
|
|
Src3=0x1000000;
|
|
END
|
|
if (OK)
|
|
BEGIN
|
|
CodeLen=4;
|
|
DAsmCode[0]=(StdOrders[z].Code << 24)+Src3+(Dest << 16)+(Src1 << 8)+Src2;
|
|
if (StdOrders[z].MustSup) ChkSup();
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
/* Variante 2: Register <-- Register op Register */
|
|
|
|
for (z=0; z<NoImmOrderCount; z++)
|
|
if (Memo(NoImmOrders[z].Name))
|
|
BEGIN
|
|
if ((ArgCnt>3) OR (ArgCnt<2)) WrError(1110);
|
|
else if (NOT DecodeReg(ArgStr[1],&Dest)) WrXError(1445,ArgStr[1]);
|
|
else
|
|
BEGIN
|
|
OK=True;
|
|
if (ArgCnt==2) Src1=Dest;
|
|
else OK=DecodeReg(ArgStr[2],&Src1);
|
|
if (NOT OK) WrError(1445);
|
|
else if (NOT DecodeReg(ArgStr[ArgCnt],&Src2)) WrError(1445);
|
|
else
|
|
BEGIN
|
|
CodeLen=4;
|
|
DAsmCode[0]=(NoImmOrders[z].Code << 24)+(Dest << 16)+(Src1 << 8)+Src2;
|
|
if (NoImmOrders[z].MustSup) ChkSup();
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
/* Variante 3: Vektor <-- Register op Register/uimm8 */
|
|
|
|
for (z=0; z<VecOrderCount; z++)
|
|
if (Memo(VecOrders[z].Name))
|
|
BEGIN
|
|
if (ArgCnt!=3) WrError(1110);
|
|
else
|
|
BEGIN
|
|
FirstPassUnknown=False;
|
|
Dest=EvalIntExpression(ArgStr[1],UInt8,&OK);
|
|
if (FirstPassUnknown) Dest=64;
|
|
if (OK)
|
|
if (NOT DecodeReg(ArgStr[2],&Src1)) WrError(1445);
|
|
else
|
|
BEGIN
|
|
if (DecodeReg(ArgStr[ArgCnt],&Src2))
|
|
BEGIN
|
|
OK=True; Src3=0;
|
|
END
|
|
else
|
|
BEGIN
|
|
Src2=EvalIntExpression(ArgStr[ArgCnt],UInt8,&OK);
|
|
Src3=0x1000000;
|
|
END
|
|
if (OK)
|
|
BEGIN
|
|
CodeLen=4;
|
|
DAsmCode[0]=(VecOrders[z].Code << 24)+Src3+(Dest << 16)+(Src1 << 8)+Src2;
|
|
if ((VecOrders[z].MustSup) OR (Dest<=63)) ChkSup();
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
/* Variante 4: ohne Operanden */
|
|
|
|
for (z=0; z<FixedOrderCount; z++)
|
|
if (Memo(FixedOrders[z].Name))
|
|
BEGIN
|
|
if (ArgCnt!=0) WrError(1110);
|
|
else
|
|
BEGIN
|
|
CodeLen=4; DAsmCode[0]=FixedOrders[z].Code << 24;
|
|
if (FixedOrders[z].MustSup) ChkSup();
|
|
END
|
|
return;
|
|
END
|
|
|
|
/* Variante 5 : [0], Speichersteuerwort, Register, Register/uimm8 */
|
|
|
|
for (z=0; z<MemOrderCount; z++)
|
|
if (Memo(MemOrders[z].Name))
|
|
BEGIN
|
|
if ((ArgCnt!=3) AND (ArgCnt!=4)) WrError(1110);
|
|
else
|
|
BEGIN
|
|
if (ArgCnt==3)
|
|
BEGIN
|
|
OK=True; AdrLong=0;
|
|
END
|
|
else
|
|
BEGIN
|
|
AdrLong=EvalIntExpression(ArgStr[1],Int32,&OK);
|
|
if (OK) OK=ChkRange(AdrLong,0,0);
|
|
END
|
|
if (OK)
|
|
BEGIN
|
|
Dest=EvalIntExpression(ArgStr[ArgCnt-2],UInt7,&OK);
|
|
if (OK)
|
|
if (DecodeReg(ArgStr[ArgCnt-1],&Src1))
|
|
BEGIN
|
|
if (DecodeReg(ArgStr[ArgCnt],&Src2))
|
|
BEGIN
|
|
OK=True; Src3=0;
|
|
END
|
|
else
|
|
BEGIN
|
|
Src2=EvalIntExpression(ArgStr[ArgCnt],UInt8,&OK);
|
|
Src3=0x1000000;
|
|
END
|
|
if (OK)
|
|
BEGIN
|
|
CodeLen=4;
|
|
DAsmCode[0]=(MemOrders[z].Code << 24)+Src3+(Dest << 16)+(Src1 << 8)+Src2;
|
|
if (MemOrders[z].MustSup) ChkSup();
|
|
END
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
/* Sprungbefehle */
|
|
|
|
for (z=0; z<JmpOrderCount; z++)
|
|
BEGIN
|
|
l=strlen(JmpOrders[z].Name);
|
|
if ((strncmp(OpPart,JmpOrders[z].Name,l)==0) AND ((OpPart[l]=='\0') OR (OpPart[l]=='I')))
|
|
BEGIN
|
|
if (ArgCnt!=1+Ord(JmpOrders[z].HasReg)) WrError(1110);
|
|
else if (DecodeReg(ArgStr[ArgCnt],&Src1))
|
|
BEGIN
|
|
if (NOT JmpOrders[z].HasReg)
|
|
BEGIN
|
|
Dest=0; OK=True;
|
|
END
|
|
else OK=DecodeReg(ArgStr[1],&Dest);
|
|
if (OK)
|
|
BEGIN
|
|
CodeLen=4;
|
|
DAsmCode[0]=((JmpOrders[z].Code+0x20) << 24)+(Dest << 8)+Src1;
|
|
END
|
|
END
|
|
else if (OpPart[l]=='I') WrError(1445);
|
|
else
|
|
BEGIN
|
|
if (NOT JmpOrders[z].HasReg)
|
|
BEGIN
|
|
Dest=0; OK=True;
|
|
END
|
|
else OK=DecodeReg(ArgStr[1],&Dest);
|
|
if (OK)
|
|
BEGIN
|
|
AdrLong=EvalIntExpression(ArgStr[ArgCnt],Int32,&OK);
|
|
AdrInt=AdrLong-EProgCounter();
|
|
if (OK)
|
|
if ((AdrLong & 3)!=0) WrError(1325);
|
|
else if ((AdrInt<=0x1ffff) AND (AdrInt>=-0x20000))
|
|
BEGIN
|
|
CodeLen=4;
|
|
AdrLong-=EProgCounter();
|
|
DAsmCode[0]=(JmpOrders[z].Code << 24)
|
|
+((AdrLong & 0x3fc00) << 6)
|
|
+(Dest << 8)+((AdrLong & 0x3fc) >> 2);
|
|
END
|
|
else if ((NOT SymbolQuestionable) AND (AdrLong>0x3fffff)) WrError(1370);
|
|
else
|
|
BEGIN
|
|
CodeLen=4;
|
|
DAsmCode[0]=((JmpOrders[z].Code+1) << 24)
|
|
+((AdrLong & 0x3fc00) << 6)
|
|
+(Dest << 8)+((AdrLong & 0x3fc) >> 2);
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
END
|
|
|
|
/* Sonderfaelle */
|
|
|
|
if (Memo("CLASS"))
|
|
BEGIN
|
|
if (ArgCnt!=3) WrError(1110);
|
|
else if (NOT ChkCPU(CPU29000)) WrError(1500);
|
|
else if (NOT DecodeReg(ArgStr[1],&Dest)) WrError(1445);
|
|
else if (NOT DecodeReg(ArgStr[2],&Src1)) WrError(1445);
|
|
else
|
|
BEGIN
|
|
Src2=EvalIntExpression(ArgStr[3],UInt2,&OK);
|
|
if (OK)
|
|
BEGIN
|
|
CodeLen=4;
|
|
DAsmCode[0]=0xe6000000+(Dest << 16)+(Src1 << 8)+Src2;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("EMULATE"))
|
|
BEGIN
|
|
if (ArgCnt!=3) WrError(1110);
|
|
else
|
|
BEGIN
|
|
FirstPassUnknown=False;
|
|
Dest=EvalIntExpression(ArgStr[1],UInt8,&OK);
|
|
if (FirstPassUnknown) Dest=64;
|
|
if (OK)
|
|
if (NOT DecodeReg(ArgStr[2],&Src1)) WrError(1445);
|
|
else if (NOT DecodeReg(ArgStr[ArgCnt],&Src2)) WrError(1445);
|
|
else
|
|
BEGIN
|
|
CodeLen=4;
|
|
DAsmCode[0]=0xd7000000+(Dest << 16)+(Src1 << 8)+Src2;
|
|
if (Dest<=63) ChkSup();
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("SQRT"))
|
|
BEGIN
|
|
if ((ArgCnt!=3) AND (ArgCnt!=2)) WrError(1110);
|
|
else if (NOT ChkCPU(CPU29000)) WrError(1500);
|
|
else if (NOT DecodeReg(ArgStr[1],&Dest)) WrError(1445);
|
|
else
|
|
BEGIN
|
|
if (ArgCnt==2)
|
|
BEGIN
|
|
OK=True; Src1=Dest;
|
|
END
|
|
else OK=DecodeReg(ArgStr[2],&Src1);
|
|
if (NOT OK) WrError(1445);
|
|
else
|
|
BEGIN
|
|
Src2=EvalIntExpression(ArgStr[ArgCnt],UInt2,&OK);
|
|
if (OK)
|
|
BEGIN
|
|
CodeLen=4;
|
|
DAsmCode[0]=0xe5000000+(Dest << 16)+(Src1 << 8)+Src2;
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("CLZ"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if (NOT DecodeReg(ArgStr[1],&Dest)) WrError(1445);
|
|
else
|
|
BEGIN
|
|
if (DecodeReg(ArgStr[2],&Src1))
|
|
BEGIN
|
|
OK=True; Src3=0;
|
|
END
|
|
else
|
|
BEGIN
|
|
Src1=EvalIntExpression(ArgStr[2],UInt8,&OK);
|
|
Src3=0x1000000;
|
|
END
|
|
if (OK)
|
|
BEGIN
|
|
CodeLen=4;
|
|
DAsmCode[0]=0x08000000+Src3+(Dest << 16)+Src1;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("CONST"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if (NOT DecodeReg(ArgStr[1],&Dest)) WrError(1445);
|
|
else
|
|
BEGIN
|
|
AdrLong=EvalIntExpression(ArgStr[2],Int32,&OK);
|
|
if (OK)
|
|
BEGIN
|
|
CodeLen=4;
|
|
DAsmCode[0]=((AdrLong & 0xff00) << 8)+(Dest << 8)+(AdrLong & 0xff);
|
|
AdrLong=AdrLong >> 16;
|
|
if (AdrLong==0xffff) DAsmCode[0]+=0x01000000;
|
|
else
|
|
BEGIN
|
|
DAsmCode[0]+=0x03000000;
|
|
if (AdrLong!=0)
|
|
BEGIN
|
|
CodeLen=8;
|
|
DAsmCode[1]=0x02000000+((AdrLong & 0xff00) << 16)+(Dest << 8)+(AdrLong & 0xff);
|
|
END
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if ((Memo("CONSTH")) OR (Memo("CONSTN")))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if (NOT DecodeReg(ArgStr[1],&Dest)) WrError(1445);
|
|
else
|
|
BEGIN
|
|
FirstPassUnknown=False;
|
|
AdrLong=EvalIntExpression(ArgStr[2],Int32,&OK);
|
|
if (FirstPassUnknown) AdrLong&=0xffff;
|
|
if ((Memo("CONSTN")) AND ((AdrLong >> 16)==0xffff)) AdrLong&=0xffff;
|
|
if (ChkRange(AdrLong,0,0xffff))
|
|
BEGIN
|
|
CodeLen=4;
|
|
DAsmCode[0]=0x1000000+((AdrLong & 0xff00) << 8)+(Dest << 8)+(AdrLong & 0xff);
|
|
if (Memo("CONSTH")) DAsmCode[0]+=0x1000000;
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("CONVERT"))
|
|
BEGIN
|
|
if (ArgCnt!=6) WrError(1110);
|
|
else if (NOT ChkCPU(CPU29000)) WrError(1500);
|
|
else if (NOT DecodeReg(ArgStr[1],&Dest)) WrError(1445);
|
|
else if (NOT DecodeReg(ArgStr[2],&Src1)) WrError(1445);
|
|
else
|
|
BEGIN
|
|
Src2=0;
|
|
Src2+=EvalIntExpression(ArgStr[3],UInt1,&OK) << 7;
|
|
if (OK)
|
|
BEGIN
|
|
Src2+=EvalIntExpression(ArgStr[4],UInt3,&OK) << 4;
|
|
if (OK)
|
|
BEGIN
|
|
Src2+=EvalIntExpression(ArgStr[5],UInt2,&OK) << 2;
|
|
if (OK)
|
|
BEGIN
|
|
Src2+=EvalIntExpression(ArgStr[6],UInt2,&OK);
|
|
if (OK)
|
|
BEGIN
|
|
CodeLen=4;
|
|
DAsmCode[0]=0xe4000000+(Dest << 16)+(Src1 << 8)+Src2;
|
|
END
|
|
END
|
|
END
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("EXHWS"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if (NOT DecodeReg(ArgStr[1],&Dest)) WrError(1445);
|
|
else if (NOT DecodeReg(ArgStr[2],&Src1)) WrError(1445);
|
|
else
|
|
BEGIN
|
|
CodeLen=4;
|
|
DAsmCode[0]=0x7e000000+(Dest << 16)+(Src1 << 8);
|
|
END
|
|
return;
|
|
END
|
|
|
|
if ((Memo("INV")) OR (Memo("IRETINV")))
|
|
BEGIN
|
|
if (ArgCnt>1) WrError(1110);
|
|
else
|
|
BEGIN
|
|
if (ArgCnt==0)
|
|
BEGIN
|
|
Src1=0; OK=True;
|
|
END
|
|
else Src1=EvalIntExpression(ArgStr[1],UInt2,&OK);
|
|
if (OK)
|
|
BEGIN
|
|
CodeLen=4;
|
|
DAsmCode[0]=Src1 << 16;
|
|
if (Memo("INV")) DAsmCode[0]+=0x9f000000;
|
|
else DAsmCode[0]+=0x8c000000;
|
|
ChkSup();
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("MFSR"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if (NOT DecodeReg(ArgStr[1],&Dest)) WrXError(1445,ArgStr[1]);
|
|
else if (NOT DecodeSpReg(ArgStr[2],&Src1)) WrXError(1440,ArgStr[2]);
|
|
else
|
|
BEGIN
|
|
DAsmCode[0]=0xc6000000+(Dest << 16)+(Src1 << 8);
|
|
CodeLen=4; if (IsSup(Src1)) ChkSup();
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("MTSR"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if (NOT DecodeSpReg(ArgStr[1],&Dest)) WrXError(1440,ArgStr[1]);
|
|
else if (NOT DecodeReg(ArgStr[2],&Src1)) WrXError(1445,ArgStr[2]);
|
|
else
|
|
BEGIN
|
|
DAsmCode[0]=0xce000000+(Dest << 8)+Src1;
|
|
CodeLen=4; if (IsSup(Dest)) ChkSup();
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("MTSRIM"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if (NOT DecodeSpReg(ArgStr[1],&Dest)) WrXError(1440,ArgStr[1]);
|
|
else
|
|
BEGIN
|
|
Src1=EvalIntExpression(ArgStr[2],UInt16,&OK);
|
|
if (OK)
|
|
BEGIN
|
|
DAsmCode[0]=0x04000000+((Src1 & 0xff00) << 8)+(Dest << 8)+Lo(Src1);
|
|
CodeLen=4; if (IsSup(Dest)) ChkSup();
|
|
END
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("MFTLB"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if (NOT DecodeReg(ArgStr[1],&Dest)) WrXError(1445,ArgStr[1]);
|
|
else if (NOT DecodeReg(ArgStr[2],&Src1)) WrXError(1445,ArgStr[2]);
|
|
else
|
|
BEGIN
|
|
DAsmCode[0]=0xb6000000+(Dest << 16)+(Src1 << 8);
|
|
CodeLen=4; ChkSup();
|
|
END
|
|
return;
|
|
END
|
|
|
|
if (Memo("MTTLB"))
|
|
BEGIN
|
|
if (ArgCnt!=2) WrError(1110);
|
|
else if (NOT DecodeReg(ArgStr[1],&Dest)) WrXError(1445,ArgStr[1]);
|
|
else if (NOT DecodeReg(ArgStr[2],&Src1)) WrXError(1445,ArgStr[2]);
|
|
else
|
|
BEGIN
|
|
DAsmCode[0]=0xbe000000+(Dest << 8)+Src1;
|
|
CodeLen=4; ChkSup();
|
|
END
|
|
return;
|
|
END
|
|
|
|
/* unbekannter Befehl */
|
|
|
|
WrXError(1200,OpPart);
|
|
END
|
|
|
|
static void InitCode_29K(void)
|
|
BEGIN
|
|
SaveInitProc();
|
|
Reg_RBP=0; ClearStringList(&Emulations);
|
|
END
|
|
|
|
static Boolean IsDef_29K(void)
|
|
BEGIN
|
|
return False;
|
|
END
|
|
|
|
static void SwitchFrom_29K(void)
|
|
BEGIN
|
|
DeinitFields(); ClearONOFF();
|
|
END
|
|
|
|
static void SwitchTo_29K(void)
|
|
BEGIN
|
|
TurnWords=True; ConstMode=ConstModeC; SetIsOccupied=False;
|
|
|
|
PCSymbol="$"; HeaderID=0x29; NOPCode=0x000000000;
|
|
DivideChars=","; HasAttrs=False;
|
|
|
|
ValidSegs=1<<SegCode;
|
|
Grans[SegCode]=1; ListGrans[SegCode]=4; SegInits[SegCode]=0;
|
|
#ifdef __STDC__
|
|
SegLimits[SegCode] = 0xfffffffful;
|
|
#else
|
|
SegLimits[SegCode] = 0xffffffffl;
|
|
#endif
|
|
|
|
MakeCode=MakeCode_29K; IsDef=IsDef_29K;
|
|
AddONOFF("SUPMODE", &SupAllowed, SupAllowedName,False);
|
|
|
|
SwitchFrom=SwitchFrom_29K; InitFields();
|
|
END
|
|
|
|
void code29k_init(void)
|
|
BEGIN
|
|
CPU29245=AddCPU("AM29245",SwitchTo_29K);
|
|
CPU29243=AddCPU("AM29243",SwitchTo_29K);
|
|
CPU29240=AddCPU("AM29240",SwitchTo_29K);
|
|
CPU29000=AddCPU("AM29000",SwitchTo_29K);
|
|
|
|
Emulations=Nil;
|
|
|
|
SaveInitProc=InitPassProc; InitPassProc=InitCode_29K;
|
|
END
|
|
|