diff options
Diffstat (limited to 'code7720.c')
-rw-r--r-- | code7720.c | 587 |
1 files changed, 587 insertions, 0 deletions
diff --git a/code7720.c b/code7720.c new file mode 100644 index 0000000..e22b8ec --- /dev/null +++ b/code7720.c @@ -0,0 +1,587 @@ +/* code7720.c */ +/*****************************************************************************/ +/* Makroassembler AS */ +/* */ +/* Codegenerator NEC uPD772x */ +/* */ +/* Historie: 30. 8.1998 Grundsteinlegung */ +/* 31. 8.1998 RET-Anweisung */ +/* 2. 9.1998 Verallgemeinerung auf 77C25 */ +/* 5. 9.1998 Pseudo-Anweisungen */ +/* 11. 9.1998 ROMData-Segment angelegt */ +/* 24. 9.1998 Korrekturen fuer DOS-Compiler */ +/* 2. 1.1999 ChkPC-Anpassung */ +/* */ +/*****************************************************************************/ + +#include "stdinc.h" +#include <string.h> +#include <ctype.h> +#include "strutil.h" +#include "nls.h" +#include "bpemu.h" + +#include "asmdef.h" +#include "asmsub.h" +#include "asmpars.h" +#include "asmcode.h" +#include "asmitree.h" +#include "headids.h" + +/*---------------------------------------------------------------------------*/ + +#define JmpOrderCnt 36 +#define ALU2OrderCnt 8 +#define ALU1OrderCnt 7 + +#define DestRegCnt 16 +#define SrcRegCnt 16 +#define ALUSrcRegCnt 4 + +typedef struct + { + LongWord Code; + } FixedOrder; + +typedef struct + { + char *Name; + LongWord Code; + } TReg; + +typedef enum {MoveField,ALUField,DPLField,DPHField,RPField,RetField} OpComps; + +static CPUVar CPU7720,CPU7725; + +static LongWord ActCode; +static Boolean InOp; +static Byte UsedOpFields; + +static Byte TypePos,ImmValPos,AddrPos,ALUPos,DPLPos,AccPos,ALUSrcPos; +static IntType MemInt; +static Word ROMEnd,DROMEnd,RAMEnd; + +static FixedOrder *JmpOrders,*ALU2Orders,*ALU1Orders; + +static TReg *DestRegs,*SrcRegs,*ALUSrcRegs; + +static PInstTable InstTable, OpTable; + +/*---------------------------------------------------------------------------*/ +/* Hilfsroutinen */ + + static Boolean DecodeReg(char *Asc, LongWord *Code, TReg *Regs, int Cnt) +BEGIN + int z; + + for (z=0; z<Cnt; z++) + if (strcasecmp(Asc,Regs[z].Name)==0) break; + + if (z<Cnt) *Code=Regs[z].Code; + return z<Cnt; +END + + static Boolean ChkOpPresent(OpComps Comp) +BEGIN + if ((UsedOpFields&(1l<<Comp))!=0) + BEGIN + WrError(1355); return False; + END + else + BEGIN + UsedOpFields|=1l<<Comp; return True; + END +END + +/*---------------------------------------------------------------------------*/ +/* Dekoder */ + + static void DecodeJmp(Word Index) +BEGIN + Word Dest; + Boolean OK; + FixedOrder *Op=JmpOrders+Index; + + if (ArgCnt!=1) WrError(1110); + else + BEGIN + Dest=EvalIntExpression(ArgStr[1],MemInt,&OK); + if (OK) + BEGIN + DAsmCode[0]=(2l<<TypePos)+(Op->Code<<13)+(Dest<<AddrPos); + CodeLen=1; + END + END +END + + static void DecodeDATA(Word Index) +BEGIN + LongInt MinV,MaxV,Trans; + TempResult t; + int z,z2,Pos,Max; + Boolean OK; + + if (ActPC==SegCode) MaxV=(MomCPU>=CPU7725) ? 16777215 : 8388607; + else MaxV=65535; + MinV=(-((MaxV+1) >> 1)); + if (ArgCnt==0) WrError(1110); + else + BEGIN + OK=True; z=1; + while ((OK) & (z<=ArgCnt)) + BEGIN + FirstPassUnknown=False; + EvalExpression(ArgStr[z],&t); + if ((FirstPassUnknown) AND (t.Typ==TempInt)) t.Contents.Int&=MaxV; + switch (t.Typ) + BEGIN + case TempInt: + if (ChkRange(t.Contents.Int,MinV,MaxV)) + if (ActPC==SegCode) DAsmCode[CodeLen++]=t.Contents.Int; + else WAsmCode[CodeLen++]=t.Contents.Int; + break; + case TempFloat: + WrError(1135); OK=False; + break; + case TempString: + Max=((ActPC==SegCode) AND (MomCPU>=CPU7725)) ? 3 : 2; Pos=0; + for (z2=0; z2<strlen(t.Contents.Ascii); z2++) + BEGIN + Trans=CharTransTable[((usint) t.Contents.Ascii[z2])&0xff]; + if (ActPC==SegCode) + DAsmCode[CodeLen]=(Pos==0) ? Trans : (DAsmCode[CodeLen]<<8)|Trans; + else + WAsmCode[CodeLen]=(Pos==0) ? Trans : (WAsmCode[CodeLen]<<8)|Trans; + if (++Pos==Max) + BEGIN + Pos=0; CodeLen++; + END + END + if (Pos!=0) CodeLen++; + break; + case TempNone: + OK=False; + END + z++; + END + END +END + + static void DecodeRES(Word Index) +BEGIN + Word Size; + Boolean OK; + + if (ArgCnt!=1) WrError(1110); + else + BEGIN + FirstPassUnknown=False; + Size=EvalIntExpression(ArgStr[1],Int16,&OK); + if (FirstPassUnknown) WrError(1820); + if ((OK) AND (NOT FirstPassUnknown)) + BEGIN + DontPrint=True; + CodeLen=Size; + BookKeeping(); + END + END +END + + static void DecodeALU2(Word Index) +BEGIN + LongWord Acc=0xff,Src; + FixedOrder *Op=ALU2Orders+Index; + char ch; + + if (NOT ChkOpPresent(ALUField)) return; + + if (ArgCnt!=2) WrError(1110); + else if (NOT DecodeReg(ArgStr[2],&Src,ALUSrcRegs,ALUSrcRegCnt)) WrXError(1445,ArgStr[2]); + else + BEGIN + if ((strlen(ArgStr[1])==4) AND (strncasecmp(ArgStr[1],"ACC",3)==0)) + BEGIN + ch=toupper(ArgStr[1][3]); + if ((ch>='A') AND (ch<='B')) Acc=ch-'A'; + END + if (Acc==0xff) WrXError(1445,ArgStr[1]); + else ActCode|=(Op->Code<<ALUPos)+(Acc<<AccPos)+(Src<<ALUSrcPos); + END +END + + static void DecodeALU1(Word Index) +BEGIN + LongWord Acc=0xff; + FixedOrder *Op=ALU1Orders+Index; + char ch; + + if (NOT ChkOpPresent(ALUField)) return; + + if (ArgCnt!=1) WrError(1110); + else + BEGIN + if ((strlen(ArgStr[1])==4) AND (strncasecmp(ArgStr[1],"ACC",3)==0)) + BEGIN + ch=toupper(ArgStr[1][3]); + if ((ch>='A') AND (ch<='B')) Acc=ch-'A'; + END + if (Acc==0xff) WrXError(1445,ArgStr[1]); + else ActCode|=(Op->Code<<ALUPos)+(Acc<<AccPos); + END +END + + static void DecodeNOP(Word Index) +BEGIN + if (NOT ChkOpPresent(ALUField)) return; +END + + static void DecodeDPL(Word Index) +BEGIN + if (NOT ChkOpPresent(DPLField)) return; + + if (ArgCnt!=0) WrError(1110); + else ActCode|=(((LongWord)Index)<<DPLPos); +END + + static void DecodeDPH(Word Index) +BEGIN + if (NOT ChkOpPresent(DPHField)) return; + + if (ArgCnt!=0) WrError(1110); + else ActCode|=(((LongWord)Index)<<9); +END + + static void DecodeRP(Word Index) +BEGIN + if (NOT ChkOpPresent(RPField)) return; + + if (ArgCnt!=0) WrError(1110); + else ActCode|=(((LongWord)Index)<<8); +END + + static void DecodeRET(Word Index) +BEGIN + if (NOT ChkOpPresent(RetField)) return; + + if (ArgCnt!=0) WrError(1110); + else ActCode|=(1l<<TypePos); +END + + static void DecodeLDI(Word Index) +BEGIN + LongWord Value; + LongWord Reg; + Boolean OK; + + if (ArgCnt!=2) WrError(1110); + else if (NOT DecodeReg(ArgStr[1],&Reg,DestRegs,DestRegCnt)) WrXError(1445,ArgStr[1]); + else + BEGIN + Value=EvalIntExpression(ArgStr[2],Int16,&OK); + if (OK) + BEGIN + DAsmCode[0]=(3l<<TypePos)+Reg+(Value<<ImmValPos); + CodeLen=1; + END + END +END + + static void DecodeOP(Word Index) +BEGIN + char *p; + int z; + + UsedOpFields=0; ActCode=0; + + if (ArgCnt>1) + BEGIN + p=FirstBlank(ArgStr[1]); + if (p!=NULL) + BEGIN + *p='\0'; strmaxcpy(OpPart,ArgStr[1],255); + NLS_UpString(OpPart); + strcpy(ArgStr[1],p+1); KillPrefBlanks(ArgStr[1]); + END + else + BEGIN + strmaxcpy(OpPart,ArgStr[1],255); + for (z=1; z<ArgCnt; z++) + strcpy(ArgStr[z],ArgStr[z+1]); + ArgCnt--; + END + if (NOT LookupInstTable(OpTable,OpPart)) WrXError(1200,OpPart); + END + + DAsmCode[0]=ActCode; CodeLen=1; +END + + static void DecodeMOV(Word Index) +BEGIN + LongWord Dest,Src; + + if (NOT ChkOpPresent(MoveField)) return; + + if (ArgCnt!=2) WrError(1110); + else if (NOT DecodeReg(ArgStr[1],&Dest,DestRegs,DestRegCnt)) WrXError(1445,ArgStr[1]); + else if (NOT DecodeReg(ArgStr[2],&Src,SrcRegs,SrcRegCnt)) WrXError(1445,ArgStr[2]); + else ActCode|=Dest+(Src<<4); +END + +/*---------------------------------------------------------------------------*/ +/* Tabellenverwaltung */ + +static int InstrZ; + + static void AddJmp(char *NName, LongWord NCode) +BEGIN + if (InstrZ>=JmpOrderCnt) exit(255); + if ((MomCPU<CPU7725) AND (Odd(NCode))) return; + JmpOrders[InstrZ].Code=(MomCPU==CPU7725) ? NCode : NCode>>1; + AddInstTable(InstTable, NName, InstrZ++, DecodeJmp); +END + + static void AddALU2(char *NName, LongWord NCode) +BEGIN + if (InstrZ>=ALU2OrderCnt) exit(255); + ALU2Orders[InstrZ].Code=NCode; + AddInstTable(OpTable, NName, InstrZ++, DecodeALU2); +END + + static void AddALU1(char *NName, LongWord NCode) +BEGIN + if (InstrZ>=ALU1OrderCnt) exit(255); + ALU1Orders[InstrZ].Code=NCode; + AddInstTable(OpTable, NName, InstrZ++, DecodeALU1); +END + + static void AddDestReg(char *NName, LongWord NCode) +BEGIN + if (InstrZ>=DestRegCnt) exit(255); + DestRegs[InstrZ].Name=NName; + DestRegs[InstrZ++].Code=NCode; +END + + static void AddSrcReg(char *NName, LongWord NCode) +BEGIN + if (InstrZ>=SrcRegCnt) exit(255); + SrcRegs[InstrZ].Name=NName; + SrcRegs[InstrZ++].Code=NCode; +END + + static void AddALUSrcReg(char *NName, LongWord NCode) +BEGIN + if (InstrZ>=ALUSrcRegCnt) exit(255); + ALUSrcRegs[InstrZ].Name=NName; + ALUSrcRegs[InstrZ++].Code=NCode; +END + + static void InitFields(void) +BEGIN + InstTable=CreateInstTable(101); + OpTable=CreateInstTable(79); + + AddInstTable(InstTable,"LDI",0,DecodeLDI); + AddInstTable(InstTable,"LD",0,DecodeLDI); + AddInstTable(InstTable,"OP",0,DecodeOP); + AddInstTable(InstTable,"DATA",0,DecodeDATA); + AddInstTable(InstTable,"RES",0,DecodeRES); + AddInstTable(OpTable,"MOV",0,DecodeMOV); + AddInstTable(OpTable,"NOP",0,DecodeNOP); + AddInstTable(OpTable,"DPNOP",0,DecodeDPL); + AddInstTable(OpTable,"DPINC",1,DecodeDPL); + AddInstTable(OpTable,"DPDEC",2,DecodeDPL); + AddInstTable(OpTable,"DPCLR",3,DecodeDPL); + AddInstTable(OpTable,"M0",0,DecodeDPH); + AddInstTable(OpTable,"M1",1,DecodeDPH); + AddInstTable(OpTable,"M2",2,DecodeDPH); + AddInstTable(OpTable,"M3",3,DecodeDPH); + AddInstTable(OpTable,"M4",4,DecodeDPH); + AddInstTable(OpTable,"M5",5,DecodeDPH); + AddInstTable(OpTable,"M6",6,DecodeDPH); + AddInstTable(OpTable,"M7",7,DecodeDPH); + if (MomCPU>=CPU7725) + BEGIN + AddInstTable(OpTable,"M8",8,DecodeDPH); + AddInstTable(OpTable,"M9",9,DecodeDPH); + AddInstTable(OpTable,"MA",10,DecodeDPH); + AddInstTable(OpTable,"MB",11,DecodeDPH); + AddInstTable(OpTable,"MC",12,DecodeDPH); + AddInstTable(OpTable,"MD",13,DecodeDPH); + AddInstTable(OpTable,"ME",14,DecodeDPH); + AddInstTable(OpTable,"MF",15,DecodeDPH); + END + AddInstTable(OpTable,"RPNOP",0,DecodeRP); + AddInstTable(OpTable,"RPDEC",1,DecodeRP); + AddInstTable(OpTable,"RET",1,DecodeRET); + + JmpOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*JmpOrderCnt); InstrZ=0; + AddJmp("JMP" , 0x100); AddJmp("CALL" , 0x140); + AddJmp("JNCA" , 0x080); AddJmp("JCA" , 0x082); + AddJmp("JNCB" , 0x084); AddJmp("JCB" , 0x086); + AddJmp("JNZA" , 0x088); AddJmp("JZA" , 0x08a); + AddJmp("JNZB" , 0x08c); AddJmp("JZB" , 0x08e); + AddJmp("JNOVA0", 0x090); AddJmp("JOVA0" , 0x092); + AddJmp("JNOVB0", 0x094); AddJmp("JOVB0" , 0x096); + AddJmp("JNOVA1", 0x098); AddJmp("JOVA1" , 0x09a); + AddJmp("JNOVB1", 0x09c); AddJmp("JOVB1" , 0x09e); + AddJmp("JNSA0" , 0x0a0); AddJmp("JSA0" , 0x0a2); + AddJmp("JNSB0" , 0x0a4); AddJmp("JSB0" , 0x0a6); + AddJmp("JNSA1" , 0x0a8); AddJmp("JSA1" , 0x0aa); + AddJmp("JNSB1" , 0x0ac); AddJmp("JSB1" , 0x0ae); + AddJmp("JDPL0" , 0x0b0); AddJmp("JDPLF" , 0x0b2); + AddJmp("JNSIAK", 0x0b4); AddJmp("JSIAK" , 0x0b6); + AddJmp("JNSOAK", 0x0b8); AddJmp("JSOAK" , 0x0ba); + AddJmp("JNRQM" , 0x0bc); AddJmp("JRQM" , 0x0be); + AddJmp("JDPLN0", 0x0b1); AddJmp("JDPLNF" , 0x0b3); + + ALU2Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*ALU2OrderCnt); InstrZ=0; + AddALU2("OR" , 1); AddALU2("AND" , 2); AddALU2("XOR" , 3); + AddALU2("SUB" , 4); AddALU2("ADD" , 5); AddALU2("SBB" , 6); + AddALU2("ADC" , 7); AddALU2("CMP" ,10); + + ALU1Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*ALU1OrderCnt); InstrZ=0; + AddALU1("DEC" , 8); AddALU1("INC" , 9); AddALU1("SHR1",11); + AddALU1("SHL1",12); AddALU1("SHL2",13); AddALU1("SHL4",14); + AddALU1("XCHG",15); + + DestRegs=(TReg *) malloc(sizeof(TReg)*DestRegCnt); InstrZ=0; + AddDestReg("@NON", 0); AddDestReg("@A" , 1); + AddDestReg("@B" , 2); AddDestReg("@TR" , 3); + AddDestReg("@DP" , 4); AddDestReg("@RP" , 5); + AddDestReg("@DR" , 6); AddDestReg("@SR" , 7); + AddDestReg("@SOL", 8); AddDestReg("@SOM", 9); + AddDestReg("@K" , 10); AddDestReg("@KLR", 11); + AddDestReg("@KLM", 12); AddDestReg("@L" , 13); + AddDestReg((MomCPU==CPU7725)?"@TRB":"",14); + AddDestReg("@MEM", 15); + + + SrcRegs=(TReg *) malloc(sizeof(TReg)*SrcRegCnt); InstrZ=0; + AddSrcReg("NON" , 0); AddSrcReg("A" , 1); + AddSrcReg("B" , 2); AddSrcReg("TR" , 3); + AddSrcReg("DP" , 4); AddSrcReg("RP" , 5); + AddSrcReg("RO" , 6); AddSrcReg("SGN" , 7); + AddSrcReg("DR" , 8); AddSrcReg("DRNF", 9); + AddSrcReg("SR" , 10); AddSrcReg("SIM" , 11); + AddSrcReg("SIL" , 12); AddSrcReg("K" , 13); + AddSrcReg("L" , 14); AddSrcReg("MEM" , 15); + + ALUSrcRegs=(TReg *) malloc(sizeof(TReg)*ALUSrcRegCnt); InstrZ=0; + AddALUSrcReg("RAM", 0); AddALUSrcReg("IDB", 1); + AddALUSrcReg("M" , 2); AddALUSrcReg("N" , 3); +END + + static void DeinitFields(void) +BEGIN + DestroyInstTable(InstTable); + DestroyInstTable(OpTable); + free(JmpOrders); + free(ALU2Orders); + free(ALU1Orders); + free(DestRegs); + free(SrcRegs); + free(ALUSrcRegs); +END + +/*---------------------------------------------------------------------------*/ +/* Callbacks */ + + static void MakeCode_7720(void) +BEGIN + Boolean NextOp; + + /* Nullanweisung */ + + if ((Memo("")) AND (*AttrPart=='\0') AND (ArgCnt==0)) return; + + /* direkte Anweisungen */ + + NextOp=Memo("OP"); + if (LookupInstTable(InstTable,OpPart)) + BEGIN + InOp=NextOp; return; + END + + /* wenn eine parallele Op-Anweisung offen ist, noch deren Komponenten testen */ + + if ((InOp) AND (LookupInstTable(OpTable,OpPart))) + BEGIN + RetractWords(1); + DAsmCode[0]=ActCode; CodeLen=1; + return; + END + + /* Hae??? */ + + WrXError(1200,OpPart); +END + + static Boolean IsDef_7720(void) +BEGIN + return False; +END + + static void SwitchFrom_7720(void) +BEGIN + DeinitFields(); +END + + static void SwitchTo_7720(void) +BEGIN + PFamilyDescr FoundDescr; + + TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False; + + if (MomCPU==CPU7725) + BEGIN + FoundDescr=FindFamilyByName("7725"); + MemInt=UInt11; + ROMEnd=0x7ff; DROMEnd=0x3ff; RAMEnd=0xff; + TypePos=22; + ImmValPos=6; + AddrPos=2; + ALUPos=16; + DPLPos=13; + AccPos=15; + ALUSrcPos=20; + END + else + BEGIN + FoundDescr=FindFamilyByName("7720"); + MemInt=UInt9; + ROMEnd=0x1ff; DROMEnd=0x1ff; RAMEnd=0x7f; + TypePos=21; + ImmValPos=5; + AddrPos=4; + ALUPos=15; + DPLPos=12; + AccPos=14; + ALUSrcPos=19; + END + + PCSymbol="$"; HeaderID=FoundDescr->Id; NOPCode=0x000000; + DivideChars=","; HasAttrs=False; + + ValidSegs=(1l<<SegCode)|(1l<<SegData)|(1l<<SegRData); + Grans[SegCode ]=4; ListGrans[SegCode ]=4; SegInits[SegCode ]=0; + SegLimits[SegCode ] = ROMEnd; + Grans[SegData ]=2; ListGrans[SegData ]=2; SegInits[SegData ]=0; + SegLimits[SegData ] = RAMEnd; + Grans[SegRData]=2; ListGrans[SegRData]=2; SegInits[SegRData]=0; + SegLimits[SegRData] = DROMEnd; + + MakeCode=MakeCode_7720; IsDef=IsDef_7720; + SwitchFrom=SwitchFrom_7720; + + InOp=False; UsedOpFields=0; ActCode=0; + InitFields(); +END + +/*---------------------------------------------------------------------------*/ +/* Initialisierung */ + + void code7720_init(void) +BEGIN + CPU7720=AddCPU("7720",SwitchTo_7720); + CPU7725=AddCPU("7725",SwitchTo_7720); +END |