From 333b605b2afd472b823aeda0adf0e8b1ea9843c0 Mon Sep 17 00:00:00 2001 From: fishsoupisgood Date: Mon, 27 May 2019 02:41:51 +0100 Subject: initial commit from asl-1.41r8.tar.gz --- code78k0.c | 1228 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1228 insertions(+) create mode 100644 code78k0.c (limited to 'code78k0.c') diff --git a/code78k0.c b/code78k0.c new file mode 100644 index 0000000..3a03e94 --- /dev/null +++ b/code78k0.c @@ -0,0 +1,1228 @@ +/* code78k0.c */ +/*****************************************************************************/ +/* AS-Portierung */ +/* */ +/* Codegenerator 78K0-Familie */ +/* */ +/* Historie: 1.12.1996 Grundsteinlegung */ +/* 3. 1.1999 ChkPC-Anpassung */ +/* */ +/*****************************************************************************/ + +#include "stdinc.h" +#include +#include + +#include "bpemu.h" +#include "strutil.h" +#include "asmdef.h" +#include "asmsub.h" +#include "asmpars.h" +#include "codepseudo.h" +#include "codevars.h" + + +#define ModNone (-1) +#define ModReg8 0 +#define MModReg8 (1 << ModReg8) +#define ModReg16 1 +#define MModReg16 (1 << ModReg16) +#define ModImm 2 +#define MModImm (1 << ModImm) +#define ModShort 3 +#define MModShort (1 << ModShort) +#define ModSFR 4 +#define MModSFR (1 << ModSFR) +#define ModAbs 5 +#define MModAbs (1 << ModAbs) +#define ModIReg 6 +#define MModIReg (1 << ModIReg) +#define ModIndex 7 +#define MModIndex (1 << ModIndex) +#define ModDisp 8 +#define MModDisp (1 << ModDisp) + +#define AccReg 1 +#define AccReg16 0 + +#define FixedOrderCount 11 +#define AriOrderCount 8 +#define Ari16OrderCount 3 +#define ShiftOrderCount 4 +#define Bit2OrderCount 3 +#define RelOrderCount 4 +#define BRelOrderCount 3 + +typedef struct + { + char *Name; + Word Code; + } FixedOrder; + +static FixedOrder *FixedOrders; +static char **AriOrders; +static char **Ari16Orders; +static char **ShiftOrders; +static char **Bit2Orders; +static char **RelOrders; +static char **BRelOrders; + +static Byte OpSize,AdrPart; +static Byte AdrVals[2]; +static ShortInt AdrMode; + +static CPUVar CPU78070; + + +/*-------------------------------------------------------------------------*/ +/* dynamische Codetabellenverwaltung */ + + static void AddFixed(char *NewName, Word NewCode) +BEGIN + if (InstrZ>=FixedOrderCount) exit(255); + FixedOrders[InstrZ].Name=NewName; + FixedOrders[InstrZ++].Code=NewCode; +END + + static void AddAri(char *NewName) +BEGIN + if (InstrZ>=AriOrderCount) exit(255); + AriOrders[InstrZ++]=NewName; +END + + static void AddAri16(char *NewName) +BEGIN + if (InstrZ>=Ari16OrderCount) exit(255); + Ari16Orders[InstrZ++]=NewName; +END + + static void AddShift(char *NewName) +BEGIN + if (InstrZ>=ShiftOrderCount) exit(255); + ShiftOrders[InstrZ++]=NewName; +END + + static void AddBit2(char *NewName) +BEGIN + if (InstrZ>=Bit2OrderCount) exit(255); + Bit2Orders[InstrZ++]=NewName; +END + + static void AddRel(char *NewName) +BEGIN + if (InstrZ>=RelOrderCount) exit(255); + RelOrders[InstrZ++]=NewName; +END + + static void AddBRel(char *NewName) +BEGIN + if (InstrZ>=BRelOrderCount) exit(255); + BRelOrders[InstrZ++]=NewName; +END + + static void InitFields(void) +BEGIN + FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCount); InstrZ=0; + AddFixed("BRK" ,0x00bf); + AddFixed("RET" ,0x00af); + AddFixed("RETB" ,0x009f); + AddFixed("RETI" ,0x008f); + AddFixed("HALT" ,0x7110); + AddFixed("STOP" ,0x7100); + AddFixed("NOP" ,0x0000); + AddFixed("EI" ,0x7a1e); + AddFixed("DI" ,0x7b1e); + AddFixed("ADJBA",0x6180); + AddFixed("ADJBS",0x6190); + + AriOrders=(char **) malloc(sizeof(char *)*AriOrderCount); InstrZ=0; + AddAri("ADD" ); AddAri("SUB" ); AddAri("ADDC"); AddAri("SUBC"); + AddAri("CMP" ); AddAri("AND" ); AddAri("OR" ); AddAri("XOR" ); + + Ari16Orders=(char **) malloc(sizeof(char *)*Ari16OrderCount); InstrZ=0; + AddAri16("ADDW"); AddAri16("SUBW"); AddAri16("CMPW"); + + ShiftOrders=(char **) malloc(sizeof(char *)*ShiftOrderCount); InstrZ=0; + AddShift("ROR"); AddShift("RORC"); AddShift("ROL"); AddShift("ROLC"); + + Bit2Orders=(char **) malloc(sizeof(char *)*Bit2OrderCount); InstrZ=0; + AddBit2("AND1"); AddBit2("OR1"); AddBit2("XOR1"); + + RelOrders=(char **) malloc(sizeof(char *)*RelOrderCount); InstrZ=0; + AddRel("BC"); AddRel("BNC"); AddRel("BZ"); AddRel("BNZ"); + + BRelOrders=(char **) malloc(sizeof(char *)*BRelOrderCount); InstrZ=0; + AddBRel("BTCLR"); AddBRel("BT"); AddBRel("BF"); +END + + static void DeinitFields(void) +BEGIN + free(FixedOrders); + free(AriOrders); + free(Ari16Orders); + free(ShiftOrders); + free(Bit2Orders); + free(RelOrders); + free(BRelOrders); +END + +/*-------------------------------------------------------------------------*/ +/* Adressausdruck parsen */ + + static void ChkAdr(Word Mask) +BEGIN + if ((AdrMode!=ModNone) AND ((Mask & (1 << AdrMode))==0)) + BEGIN + WrError(1350); + AdrMode=ModNone; AdrCnt=0; + END +END + + static void DecodeAdr(char *Asc, Word Mask) +BEGIN + static char *RegNames[8]={"X","A","C","B","E","D","L","H"}; + + Word AdrWord; + int z; + Boolean OK,LongFlag; + + AdrMode=ModNone; AdrCnt=0; + + /* Register */ + + for (z=0; z<8; z++) + if (strcasecmp(Asc,RegNames[z])==0) + BEGIN + AdrMode=ModReg8; AdrPart=z; ChkAdr(Mask); return; + END + + if (toupper(*Asc)=='R') + if ((strlen(Asc)==2) AND (Asc[1]>='0') AND (Asc[1]<='7')) + BEGIN + AdrMode=ModReg8; AdrPart=Asc[1]-'0'; ChkAdr(Mask); return; + END + else if ((strlen(Asc)==3) AND (toupper(Asc[1])=='P') AND (Asc[2]>='0') AND (Asc[2]<='3')) + BEGIN + AdrMode=ModReg16; AdrPart=Asc[2]-'0'; ChkAdr(Mask); return; + END + + if (strlen(Asc)==2) + for (z=0; z<4; z++) + if ((toupper(*Asc)==*RegNames[(z<<1)+1]) AND (toupper(Asc[1])==*RegNames[z<<1])) + BEGIN + AdrMode=ModReg16; AdrPart=z; ChkAdr(Mask); return; + END + + /* 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); + if (OK) + BEGIN + AdrVals[0]=Lo(AdrWord); AdrVals[1]=Hi(AdrWord); + END + break; + END + if (OK) + BEGIN + AdrMode=ModImm; AdrCnt=OpSize+1; + END + ChkAdr(Mask); return; + END + + /* indirekt */ + + if ((*Asc=='[') AND (Asc[strlen(Asc)-1]==']')) + BEGIN + strcpy(Asc,Asc+1); Asc[strlen(Asc)-1]='\0'; + + if ((strcasecmp(Asc,"DE")==0) OR (strcasecmp(Asc,"RP2")==0)) + BEGIN + AdrMode=ModIReg; AdrPart=0; + END + else if ((strncasecmp(Asc,"HL",2)!=0) AND (strncasecmp(Asc,"RP3",3)!=0)) WrXError(1445,Asc); + else + BEGIN + strcpy(Asc,Asc+2); if (*Asc=='3') strcpy(Asc,Asc+1); + if ((strcasecmp(Asc,"+B")==0) OR (strcasecmp(Asc,"+R3")==0)) + BEGIN + AdrMode=ModIndex; AdrPart=1; + END + else if ((strcasecmp(Asc,"+C")==0) OR (strcasecmp(Asc,"+R2")==0)) + BEGIN + AdrMode=ModIndex; AdrPart=0; + END + else + BEGIN + AdrVals[0]=EvalIntExpression(Asc,UInt8,&OK); + if (OK) + if (AdrVals[0]==0) + BEGIN + AdrMode=ModIReg; AdrPart=1; + END + else + BEGIN + AdrMode=ModDisp; AdrCnt=1; + END; + END + END + + ChkAdr(Mask); return; + END + + /* erzwungen lang ? */ + + if (*Asc=='!') + BEGIN + LongFlag=True; strcpy(Asc,Asc+1); + END + else LongFlag=False; + + /* -->absolut */ + + FirstPassUnknown=True; + AdrWord=EvalIntExpression(Asc,UInt16,&OK); + if (FirstPassUnknown) + BEGIN + AdrWord&=0xffffe; + if ((Mask & MModAbs)==0) + AdrWord=(AdrWord | 0xff00) & 0xff1f; + END + if (OK) + if ((NOT LongFlag) AND ((Mask & MModShort)!=0) AND (AdrWord>=0xfe20) AND (AdrWord<=0xff1f)) + BEGIN + AdrMode=ModShort; AdrCnt=1; AdrVals[0]=Lo(AdrWord); + END + else if ((NOT LongFlag) AND ((Mask & MModSFR)!=0) AND (((AdrWord>=0xff00) AND (AdrWord<=0xffcf)) OR (AdrWord>=0xffe0))) + BEGIN + AdrMode=ModSFR; AdrCnt=1; AdrVals[0]=Lo(AdrWord); + END + else + BEGIN + AdrMode=ModAbs; AdrCnt=2; AdrVals[0]=Lo(AdrWord); AdrVals[1]=Hi(AdrWord); + END + + ChkAdr(Mask); +END + + static void ChkEven(void) +BEGIN + if ((AdrMode==ModAbs) OR (AdrMode==ModShort) OR (AdrMode==ModSFR)) + if ((AdrVals[0]&1)==1) WrError(180); +END + + static Boolean DecodeBitAdr(char *Asc, Byte *Erg) +BEGIN + char *p; + Boolean OK; + + p=RQuotPos(Asc,'.'); + if (p==Nil) + BEGIN + WrError(1510); return False; + END + + *p='\0'; + *Erg=EvalIntExpression(p+1,UInt3,&OK) << 4; + if (NOT OK) return False; + + DecodeAdr(Asc,MModShort+MModSFR+MModIReg+MModReg8); + switch (AdrMode) + BEGIN + case ModReg8: + if (AdrPart!=AccReg) + BEGIN + WrError(1350); return False; + END + else + BEGIN + *Erg+=0x88; return True; + END + case ModShort: + return True; + case ModSFR: + *Erg+=0x08; return True; + case ModIReg: + if (AdrPart==0) + BEGIN + WrError(1350); return False; + END + else + BEGIN + *Erg+=0x80; return True; + END + default: + return False; + END +END + +/*-------------------------------------------------------------------------*/ + + static Boolean DecodePseudo(void) +BEGIN + return False; +END + + static void MakeCode_78K0(void) +BEGIN + int z; + Byte HReg; + Word AdrWord; + Integer AdrInt; + Boolean OK; + + CodeLen=0; DontPrint=False; OpSize=0; + + /* zu ignorierendes */ + + if (Memo("")) return; + + /* Pseudoanweisungen */ + + if (DecodePseudo()) return; + + if (DecodeIntelPseudo(False)) return; + + /* ohne Argument */ + + for (z=0; z=-128) AND (AdrInt<127)) ? 2 : 1; + END + switch (HReg) + BEGIN + case 1: + BAsmCode[0]=0x9b; BAsmCode[1]=Lo(AdrWord); BAsmCode[2]=Hi(AdrWord); + CodeLen=3; + break; + case 2: + AdrInt=AdrWord-(EProgCounter()+2); + if (((AdrInt<-128) OR (AdrInt>127)) AND (NOT SymbolQuestionable)) WrError(1370); + else + BEGIN + BAsmCode[0]=0xfa; BAsmCode[1]=AdrInt & 0xff; CodeLen=2; + END + break; + END + END + END + return; + END + + for (z=0; z127)) AND (NOT SymbolQuestionable)) WrError(1370); + else + BEGIN + BAsmCode[0]=0x8b+(z << 4); BAsmCode[1]=AdrInt & 0xff; + CodeLen=2; + END + END + return; + END + + for (z=0; z127)) AND (NOT SymbolQuestionable)) WrError(1370); + else + BEGIN + BAsmCode[HReg]=AdrInt & 0xff; + CodeLen=HReg+1; + END + END + return; + END + + if (Memo("DBNZ")) + BEGIN + if (ArgCnt!=2) WrError(1110); + else + BEGIN + DecodeAdr(ArgStr[1],MModReg8+MModShort); + if ((AdrMode==ModReg8) AND ((AdrPart & 6)!=2)) WrError(1350); + else if (AdrMode!=ModNone) + BEGIN + BAsmCode[0]=(AdrMode==ModReg8) ? 0x88+AdrPart : 0x04; + BAsmCode[1]=AdrVals[0]; + if (*ArgStr[2]=='$') strcpy(ArgStr[2],ArgStr[2]+1); + AdrInt=EvalIntExpression(ArgStr[2],UInt16,&OK)-(EProgCounter()+AdrCnt+2); + if (OK) + if (((AdrInt<-128) OR (AdrInt>127)) AND (NOT SymbolQuestionable)) WrError(1370); + else + BEGIN + BAsmCode[AdrCnt+1]=AdrInt & 0xff; + CodeLen=AdrCnt+2; + END + END + END + return; + END + + /* Steueranweisungen */ + + if (Memo("SEL")) + BEGIN + if (ArgCnt!=1) WrError(1350); + else if ((strlen(ArgStr[1])!=3) OR (strncasecmp(ArgStr[1],"RB",2)!=0)) WrError(1350); + else + BEGIN + HReg=ArgStr[1][2]-'0'; + if (ChkRange(HReg,0,3)) + BEGIN + BAsmCode[0]=0x61; + BAsmCode[1]=0xd0+((HReg & 1) << 3)+((HReg & 2) << 4); + CodeLen=2; + END + END + return; + END + + WrXError(1200,OpPart); +END + + static Boolean IsDef_78K0(void) +BEGIN + return False; +END + + static void SwitchFrom_78K0(void) +BEGIN + DeinitFields(); +END + + static void SwitchTo_78K0(void) +BEGIN + TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False; + + PCSymbol="PC"; HeaderID=0x7c; NOPCode=0x00; + DivideChars=","; HasAttrs=False; + + ValidSegs=1<