diff options
author | fishsoupisgood <github@madingley.org> | 2019-05-27 02:41:51 +0100 |
---|---|---|
committer | fishsoupisgood <github@madingley.org> | 2019-05-27 02:41:51 +0100 |
commit | 333b605b2afd472b823aeda0adf0e8b1ea9843c0 (patch) | |
tree | bc8f581317897e2e53f278f1716b4471fcdccd4f /codescmp.c | |
download | asl-master.tar.gz asl-master.tar.bz2 asl-master.zip |
Diffstat (limited to 'codescmp.c')
-rw-r--r-- | codescmp.c | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/codescmp.c b/codescmp.c new file mode 100644 index 0000000..18af961 --- /dev/null +++ b/codescmp.c @@ -0,0 +1,326 @@ +/* codescmp.c */ +/*****************************************************************************/ +/* AS-Portierung */ +/* */ +/* Codegenerator National SC/MP */ +/* */ +/* Historie: 17. 2.1996 Grundsteinlegung */ +/* 2. 1.1998 ChkPC umgestellt */ +/* */ +/*****************************************************************************/ + +#include "stdinc.h" +#include <ctype.h> +#include <string.h> + +#include "nls.h" +#include "strutil.h" +#include "chunks.h" +#include "asmdef.h" +#include "asmsub.h" +#include "asmpars.h" +#include "codepseudo.h" +#include "codevars.h" + + +#define FixedOrderCnt 21 +#define ImmOrderCnt 8 +#define RegOrderCnt 3 +#define MemOrderCnt 8 +#define JmpOrderCnt 4 + +typedef struct + { + char *Name; + Byte Code; + } FixedOrder; + + +static CPUVar CPUSCMP; + +static FixedOrder *FixedOrders; +static FixedOrder *ImmOrders; +static FixedOrder *RegOrders; +static FixedOrder *MemOrders; +static FixedOrder *JmpOrders; + +/*---------------------------------------------------------------------------*/ + + static void AddFixed(char *NName, Byte NCode) +BEGIN + if (InstrZ>=FixedOrderCnt) exit(255); + FixedOrders[InstrZ].Name=NName; + FixedOrders[InstrZ++].Code=NCode; +END + + static void AddImm(char *NName, Byte NCode) +BEGIN + if (InstrZ>=ImmOrderCnt) exit(255); + ImmOrders[InstrZ].Name=NName; + ImmOrders[InstrZ++].Code=NCode; +END + + static void AddReg(char *NName, Byte NCode) +BEGIN + if (InstrZ>=RegOrderCnt) exit(255); + RegOrders[InstrZ].Name=NName; + RegOrders[InstrZ++].Code=NCode; +END + + static void AddMem(char *NName, Byte NCode) +BEGIN + if (InstrZ>=MemOrderCnt) exit(255); + MemOrders[InstrZ].Name=NName; + MemOrders[InstrZ++].Code=NCode; +END + + static void AddJmp(char *NName, Byte NCode) +BEGIN + if (InstrZ>=JmpOrderCnt) exit(255); + JmpOrders[InstrZ].Name=NName; + JmpOrders[InstrZ++].Code=NCode; +END + + static void InitFields(void) +BEGIN + FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); InstrZ=0; + AddFixed("LDE" ,0x40); AddFixed("XAE" ,0x01); AddFixed("ANE" ,0x50); + AddFixed("ORE" ,0x58); AddFixed("XRE" ,0x60); AddFixed("DAE" ,0x68); + AddFixed("ADE" ,0x70); AddFixed("CAE" ,0x78); AddFixed("SIO" ,0x19); + AddFixed("SR" ,0x1c); AddFixed("SRL" ,0x1d); AddFixed("RR" ,0x1e); + AddFixed("RRL" ,0x1f); AddFixed("HALT",0x00); AddFixed("CCL" ,0x02); + AddFixed("SCL" ,0x03); AddFixed("DINT",0x04); AddFixed("IEN" ,0x05); + AddFixed("CSA" ,0x06); AddFixed("CAS" ,0x07); AddFixed("NOP" ,0x08); + + ImmOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*ImmOrderCnt); InstrZ=0; + AddImm("LDI" ,0xc4); AddImm("ANI" ,0xd4); AddImm("ORI" ,0xdc); + AddImm("XRI" ,0xe4); AddImm("DAI" ,0xec); AddImm("ADI" ,0xf4); + AddImm("CAI" ,0xfc); AddImm("DLY" ,0x8f); + + RegOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*RegOrderCnt); InstrZ=0; + AddReg("XPAL",0x30); AddReg("XPAH",0x34); AddReg("XPPC",0x3c); + + MemOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*MemOrderCnt); InstrZ=0; + AddMem("LD" ,0xc0); AddMem("ST" ,0xc8); AddMem("AND" ,0xd0); + AddMem("OR" ,0xd8); AddMem("XOR" ,0xe0); AddMem("DAD" ,0xe8); + AddMem("ADD" ,0xf0); AddMem("CAD" ,0xf8); + + JmpOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*JmpOrderCnt); InstrZ=0; + AddJmp("JMP" ,0x90); AddJmp("JP" ,0x94); AddJmp("JZ" ,0x98); + AddJmp("JNZ" ,0x9c); +END + + static void DeinitFields(void) +BEGIN + free(FixedOrders); + free(ImmOrders); + free(RegOrders); + free(MemOrders); + free(JmpOrders); +END + +/*---------------------------------------------------------------------------*/ + + static Boolean DecodeReg(char *Asc, Byte *Erg) +BEGIN + if ((strlen(Asc)!=2) OR (toupper(*Asc)!='P')) return False; + + switch (toupper(Asc[1])) + BEGIN + case 'C': *Erg=0; break; + case '0': case '1': case '2': + case '3': *Erg=Asc[1]-'0'; break; + default: return False; + END + + return True; +END + + static Boolean DecodeAdr(char *Asc, Boolean MayInc, Byte PCDisp, Byte *Arg) +BEGIN + Integer Disp; + Word PCVal; + Boolean OK; + int l=strlen(Asc); + + if ((l>=4) AND (Asc[l-1]==')') AND (Asc[l-4]=='(')) + BEGIN + Asc[l-1]='\0'; + if (DecodeReg(Asc+l-3,Arg)) + BEGIN + Asc[l-4]='\0'; + if (*Asc=='@') + BEGIN + if (NOT MayInc) + BEGIN + WrError(1350); return False; + END + strcpy(Asc,Asc+1); *Arg+=4; + END + if (strcasecmp(Asc,"E")==0) BAsmCode[1]=0x80; + else if (*Arg==0) + BEGIN + WrXError(1445,Asc+l-3); return False; + END + else + BEGIN + BAsmCode[1]=EvalIntExpression(Asc,SInt8,&OK); + if (NOT OK) return False; + END + return True; + END + else Asc[l-1]=')'; + END + + PCVal=(EProgCounter() & 0xf000)+((EProgCounter()+1) & 0xfff); + Disp=EvalIntExpression(Asc,UInt16,&OK)-PCDisp-PCVal; + if (OK) + if ((NOT SymbolQuestionable) AND ((Disp<-128) OR (Disp>127))) WrError(1370); + else + BEGIN + BAsmCode[1]=Disp & 0xff; *Arg=0; return True; + END + return False; +END + +/*---------------------------------------------------------------------------*/ + + static Boolean DecodePseudo(void) +BEGIN + return False; +END + + static void ChkPage(void) +BEGIN + if (((EProgCounter()) & 0xf000)!=((EProgCounter()+CodeLen) & 0xf000)) WrError(250); +END + + static void MakeCode_SCMP(void) +BEGIN + int z; + Boolean OK; + + CodeLen=0; DontPrint=False; + + /* zu ignorierendes */ + + if (Memo("")) return; + + /* Pseudoanweisungen */ + + if (DecodePseudo()) return; + + if (DecodeIntelPseudo(False)) return; + + /* ohne Argument */ + + for (z=0; z<FixedOrderCnt; z++) + if (Memo(FixedOrders[z].Name)) + BEGIN + if (ArgCnt!=0) WrError(1110); + else + BEGIN + BAsmCode[0]=FixedOrders[z].Code; CodeLen=1; + END + return; + END + + /* immediate */ + + for (z=0; z<ImmOrderCnt; z++) + if (Memo(ImmOrders[z].Name)) + BEGIN + if (ArgCnt!=1) WrError(1110); + else + BEGIN + BAsmCode[1]=EvalIntExpression(ArgStr[1],Int8,&OK); + if (OK) + BEGIN + BAsmCode[0]=ImmOrders[z].Code; CodeLen=2; ChkPage(); + END + END + return; + END + + /* ein Register */ + + for (z=0; z<RegOrderCnt; z++) + if (Memo(RegOrders[z].Name)) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (NOT DecodeReg(ArgStr[1],BAsmCode+0)) WrXError(1445,ArgStr[1]); + else + BEGIN + BAsmCode[0]+=RegOrders[z].Code; CodeLen=1; + END + return; + END + + /* ein Speicheroperand */ + + for (z=0; z<MemOrderCnt; z++) + if (Memo(MemOrders[z].Name)) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (DecodeAdr(ArgStr[1],True,0,BAsmCode+0)) + BEGIN + BAsmCode[0]+=MemOrders[z].Code; CodeLen=2; ChkPage(); + END + return; + END + + for (z=0; z<JmpOrderCnt; z++) + if (Memo(JmpOrders[z].Name)) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (DecodeAdr(ArgStr[1],False,1,BAsmCode+0)) + BEGIN + BAsmCode[0]+=JmpOrders[z].Code; CodeLen=2; ChkPage(); + END + return; + END + + if ((Memo("ILD")) OR (Memo("DLD"))) + BEGIN + if (ArgCnt!=1) WrError(1110); + else if (DecodeAdr(ArgStr[1],False,0,BAsmCode+0)) + BEGIN + BAsmCode[0]+=0xa8+(Ord(Memo("DLD")) << 4); CodeLen=2; ChkPage(); + END + return; + END + + WrXError(1200,OpPart); +END + + static Boolean IsDef_SCMP(void) +BEGIN + return False; +END + + static void SwitchFrom_SCMP(void) +BEGIN + DeinitFields(); +END + + static void SwitchTo_SCMP(void) +BEGIN + TurnWords=False; ConstMode=ConstModeC; SetIsOccupied=False; + + PCSymbol="$"; HeaderID=0x6e; NOPCode=0x08; + DivideChars=","; HasAttrs=False; + + ValidSegs=1<<SegCode; + Grans[SegCode]=1; ListGrans[SegCode]=1; SegInits[SegCode]=0; + SegLimits[SegCode] = 0xffff; + + MakeCode=MakeCode_SCMP; IsDef=IsDef_SCMP; + SwitchFrom=SwitchFrom_SCMP; InitFields(); +END + + void codescmp_init(void) +BEGIN + CPUSCMP=AddCPU("SC/MP",SwitchTo_SCMP); +END + + |