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

588 lines
16 KiB
C

/* 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