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 --- code4004.c | 503 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 503 insertions(+) create mode 100644 code4004.c (limited to 'code4004.c') diff --git a/code4004.c b/code4004.c new file mode 100644 index 0000000..d3f799c --- /dev/null +++ b/code4004.c @@ -0,0 +1,503 @@ +/* code4004.c */ +/*****************************************************************************/ +/* AS-Portierung */ +/* */ +/* Codegenerator Intel 4004 */ +/* */ +/* Historie: 1. 2.1998 Grundsteinlegung */ +/* 3. 3.1998 weitere Fixed-Befehle hinzugefuegt */ +/* 28.11.1998 LookupInstTable ;-) */ +/* JCN FIM... */ +/* 29.11.1998 HeaderId symbolisch holen */ +/* 3.12.1998 DATA schrieb 16-Bit-Ints statt 8 Bit */ +/* 3. 1.1999 ChkPC-Anpassung */ +/* 23. 1.1999 / / entfernt */ +/* 2. 7.1999 Zus. Befehlsvarianten, andere Registersyntax */ +/* 8. 9.1999 REG fehlte */ +/* */ +/*****************************************************************************/ + +#include "stdinc.h" +#include +#include + +#include "bpemu.h" +#include "strutil.h" +#include "asmdef.h" +#include "asmsub.h" +#include "asmpars.h" +#include "asmitree.h" +#include "headids.h" + +/*---------------------------------------------------------------------------*/ +/* Variablen */ + +#define FixedOrderCnt 35 +#define OneRegOrderCnt 1 +#define OneRRegOrderCnt 3 +#define AccRegOrderCnt 4 +#define Imm4OrderCnt 2 + +typedef struct + { + Byte Code; + } FixedOrder; + +static CPUVar CPU4004/*,CPU4040*/; + +static FixedOrder *FixedOrders; +static FixedOrder *OneRegOrders; +static FixedOrder *OneRRegOrders; +static FixedOrder *AccRegOrders; +static FixedOrder *Imm4Orders; +static PInstTable InstTable; + +/*---------------------------------------------------------------------------*/ +/* Parser */ + + static Byte RegVal(char Inp) +BEGIN + if ((Inp >='0') AND (Inp <= '9')) return Inp - '0'; + else if ((Inp >='A') AND (Inp <= 'F')) return Inp - 'A' + 10; + else return 0xff; +END + + static Boolean DecodeReg(char *Asc, Byte *Erg) +BEGIN + char *s; + + if (FindRegDef(Asc,&s)) Asc=s; + + if ((strlen(Asc) != 2) OR (toupper(*Asc)!='R')) return False; + else + BEGIN + *Erg = RegVal(toupper(Asc[1])); + return (*Erg != 0xff); + END +END + + static Boolean DecodeRReg(char *Asc, Byte *Erg) +BEGIN + Byte h; + char *s; + + if (FindRegDef(Asc,&s)) Asc = s; + + if ((strlen(Asc) != 4) OR (toupper(*Asc) != 'R') OR (toupper(Asc[2]) != 'R')) return False; + else + BEGIN + *Erg = RegVal(toupper(Asc[1])); + h = RegVal(toupper(Asc[3])); + return ((*Erg != 0xff) AND (h != 0xff) AND (h == (*Erg) + 1) AND (Odd(h))); + END +END + +/*---------------------------------------------------------------------------*/ +/* Hilfsdekoder */ + + static void DecodeFixed(Word Index) +BEGIN + FixedOrder *Instr=FixedOrders+Index; + + if (ArgCnt!=0) WrError(1110); + else + BEGIN + BAsmCode[0]=Instr->Code; CodeLen=1; + END +END + + static void DecodeOneReg(Word Index) +BEGIN + FixedOrder *Instr=OneRegOrders+Index; + Byte Erg; + + if (ArgCnt!=1) WrError(1110); + else if (NOT DecodeReg(ArgStr[1],&Erg)) WrXError(1445,ArgStr[1]); + else + BEGIN + BAsmCode[0]=Instr->Code+Erg; CodeLen=1; + END +END + + static void DecodeOneRReg(Word Index) +BEGIN + FixedOrder *Instr=OneRRegOrders+Index; + Byte Erg; + + if (ArgCnt!=1) WrError(1110); + else if (NOT DecodeRReg(ArgStr[1],&Erg)) WrXError(1445,ArgStr[1]); + else + BEGIN + BAsmCode[0]=Instr->Code+Erg; CodeLen=1; + END +END + + static void DecodeAccReg(Word Index) +BEGIN + FixedOrder *Instr=AccRegOrders+Index; + Byte Erg; + + if ((ArgCnt != 2) AND (ArgCnt != 1)) WrError(1110); + else if ((ArgCnt == 2) AND (strcasecmp(ArgStr[1], "A") != 0)) WrError(1350); + else if (NOT DecodeReg(ArgStr[ArgCnt], &Erg)) WrXError(1445, ArgStr[ArgCnt]); + else + BEGIN + BAsmCode[0] = Instr->Code + Erg; CodeLen = 1; + END +END + + static void DecodeImm4(Word Index) +BEGIN + FixedOrder *Instr=Imm4Orders+Index; + Boolean OK; + + if (ArgCnt!=1) WrError(1110); + else + BEGIN + BAsmCode[0]=EvalIntExpression(ArgStr[1],UInt4,&OK); + if (OK) + BEGIN + BAsmCode[0]+=Instr->Code; CodeLen=1; + END + END +END + + static void DecodeFullJmp(Word Index) +BEGIN + Word Adr; + Boolean OK; + + if (ArgCnt!=1) WrError(1110); + else + BEGIN + Adr=EvalIntExpression(ArgStr[1],UInt12,&OK); + if (OK) + BEGIN + BAsmCode[0]=0x40+(Index << 4)+Hi(Adr); + BAsmCode[1]=Lo(Adr); + CodeLen=2; + END + END +END + + static void DecodeISZ(Word Index) +BEGIN + Word Adr; + Boolean OK; + Byte Erg; + + if (ArgCnt!=2) WrError(1110); + else if (NOT DecodeReg(ArgStr[1],&Erg)) WrXError(1445,ArgStr[1]); + else + BEGIN + Adr=EvalIntExpression(ArgStr[2],UInt12,&OK); + if (OK) + if ((NOT SymbolQuestionable) AND (Hi(EProgCounter()+1)!=Hi(Adr))) WrError(1910); + else + BEGIN + BAsmCode[0]=0x70+Erg; BAsmCode[1]=Lo(Adr); CodeLen=2; + END + END +END + + static void DecodeJCN(Word Index) +BEGIN + Word AdrInt; + Boolean OK; + + if (ArgCnt != 2) WrError(1110); + else + BEGIN + BAsmCode[0] = 0x10; + if (strcasecmp(ArgStr[1], "Z") == 0) BAsmCode[0] += 4; + else if (strcasecmp(ArgStr[1], "NZ") == 0) BAsmCode[0] += 12; + else if (strcasecmp(ArgStr[1], "C") == 0) BAsmCode[0] += 2; + else if (strcasecmp(ArgStr[1], "NC") == 0) BAsmCode[0] += 10; + else if (strcasecmp(ArgStr[1], "T") == 0) BAsmCode[0] += 1; + else if (strcasecmp(ArgStr[1], "NT") == 0) BAsmCode[0] += 9; + if (BAsmCode[0] == 0x10) WrXError(1360, ArgStr[1]); + else + BEGIN + AdrInt = EvalIntExpression(ArgStr[2], UInt12, &OK); + if (OK) + if ((NOT SymbolQuestionable) AND (Hi(EProgCounter() + 2) != Hi(AdrInt))) WrError(1370); + else + BEGIN + BAsmCode[1] = Lo(AdrInt); + CodeLen = 2; + END + END + END +END + + static void DecodeFIM(Word Index) +BEGIN + Boolean OK; + + if (ArgCnt != 2) WrError(1110); + else if (NOT DecodeRReg(ArgStr[1], BAsmCode)) WrXError(1445, ArgStr[1]); + else + BEGIN + BAsmCode[1] = EvalIntExpression(ArgStr[2], Int8, &OK); + if (OK) + BEGIN + BAsmCode[0] |= 0x20; + CodeLen = 2; + END + END +END + + static Boolean DecodePseudo(void) +BEGIN + Boolean ValOK; + Word Size; + int z, z2; + TempResult t; + char Ch; + + if (Memo("DS")) + BEGIN + if (ArgCnt!=1) WrError(1110); + else + BEGIN + FirstPassUnknown=False; + Size=EvalIntExpression(ArgStr[1],Int16,&ValOK); + if (FirstPassUnknown) WrError(1820); + if ((ValOK) AND (NOT FirstPassUnknown)) + BEGIN + DontPrint=True; + CodeLen=Size; + BookKeeping(); + END + END + return True; + END + + if (Memo("DATA")) + BEGIN + if (ArgCnt==0) WrError(1110); + else + BEGIN + ValOK=True; + for (z=1; z<=ArgCnt; z++) + if (ValOK) + BEGIN + FirstPassUnknown=False; + EvalExpression(ArgStr[z],&t); + if ((t.Typ==TempInt) AND (FirstPassUnknown)) + if (ActPC==SegData) t.Contents.Int&=7; else t.Contents.Int&=127; + switch (t.Typ) + BEGIN + case TempInt: + if (ActPC==SegCode) + BEGIN + if (NOT RangeCheck(t.Contents.Int,Int8)) + BEGIN + WrError(1320); ValOK=False; + END + else BAsmCode[CodeLen++]=t.Contents.Int & 0xff; + END + else + BEGIN + if (NOT RangeCheck(t.Contents.Int,Int4)) + BEGIN + WrError(1320); ValOK=False; + END + else BAsmCode[CodeLen++]=t.Contents.Int & 0x0f; + END + break; + case TempFloat: + WrError(1135); ValOK=False; + break; + case TempString: + for (z2=0; z2> 4; + BAsmCode[CodeLen++]=Ch & 15; + END + END + break; + default: + ValOK=False; + END + END + if (NOT ValOK) CodeLen=0; + END + return True; + END + + if (Memo("REG")) + BEGIN + if (ArgCnt!=1) WrError(1110); + else AddRegDef(LabPart,ArgStr[1]); + return True; + END + + return False; +END + +/*---------------------------------------------------------------------------*/ +/* Codetabellenverwaltung */ + +static int InstrZ; + + static void AddFixed(char *NName, Byte NCode) +BEGIN + if (InstrZ>=FixedOrderCnt) exit(255); + FixedOrders[InstrZ].Code=NCode; + AddInstTable(InstTable,NName,InstrZ++,DecodeFixed); +END + + static void AddOneReg(char *NName, Byte NCode) +BEGIN + if (InstrZ>=OneRegOrderCnt) exit(255); + OneRegOrders[InstrZ].Code=NCode; + AddInstTable(InstTable,NName,InstrZ++,DecodeOneReg); +END + + static void AddOneRReg(char *NName, Byte NCode) +BEGIN + if (InstrZ>=OneRRegOrderCnt) exit(255); + OneRRegOrders[InstrZ].Code=NCode; + AddInstTable(InstTable,NName,InstrZ++,DecodeOneRReg); +END + + static void AddAccReg(char *NName, Byte NCode) +BEGIN + if (InstrZ>=AccRegOrderCnt) exit(255); + AccRegOrders[InstrZ].Code=NCode; + AddInstTable(InstTable,NName,InstrZ++,DecodeAccReg); +END + + static void AddImm4(char *NName, Byte NCode) +BEGIN + if (InstrZ>=Imm4OrderCnt) exit(255); + Imm4Orders[InstrZ].Code=NCode; + AddInstTable(InstTable,NName,InstrZ++,DecodeImm4); +END + + static void InitFields(void) +BEGIN + InstTable=CreateInstTable(101); + + InstrZ=0; FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); + AddFixed("NOP" ,0x00); AddFixed("WRM" ,0xe0); + AddFixed("WMP" ,0xe1); AddFixed("WRR" ,0xe2); + AddFixed("WPM" ,0xe3); AddFixed("WR0" ,0xe4); + AddFixed("WR1" ,0xe5); AddFixed("WR2" ,0xe6); + AddFixed("WR3" ,0xe7); AddFixed("SBM" ,0xe8); + AddFixed("RDM" ,0xe9); AddFixed("RDR" ,0xea); + AddFixed("ADM" ,0xeb); AddFixed("RD0" ,0xec); + AddFixed("RD1" ,0xed); AddFixed("RD2" ,0xee); + AddFixed("RD3" ,0xef); AddFixed("CLB" ,0xf0); + AddFixed("CLC" ,0xf1); AddFixed("IAC" ,0xf2); + AddFixed("CMC" ,0xf3); AddFixed("CMA" ,0xf4); + AddFixed("RAL" ,0xf5); AddFixed("RAR" ,0xf6); + AddFixed("TCC" ,0xf7); AddFixed("DAC" ,0xf8); + AddFixed("TCS" ,0xf9); AddFixed("STC" ,0xfa); + AddFixed("DAA" ,0xfb); AddFixed("KBP" ,0xfc); + AddFixed("DCL" ,0xfd); AddFixed("AD0" ,0xec); + AddFixed("AD1" ,0xed); AddFixed("AD2" ,0xee); + AddFixed("AD3" ,0xef); + + InstrZ=0; OneRegOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*OneRegOrderCnt); + AddOneReg("INC" ,0x60); + + InstrZ=0; OneRRegOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*OneRRegOrderCnt); + AddOneRReg("SRC" ,0x21); + AddOneRReg("FIN" ,0x30); + AddOneRReg("JIN" ,0x31); + + InstrZ=0; AccRegOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*AccRegOrderCnt); + AddAccReg("ADD" ,0x80); AddAccReg("SUB" ,0x90); + AddAccReg("LD" ,0xa0); AddAccReg("XCH" ,0xb0); + + InstrZ=0; Imm4Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*Imm4OrderCnt); + AddImm4("BBL" ,0xc0); AddImm4("LDM" ,0xd0); + + AddInstTable(InstTable,"JCN", 0, DecodeJCN); + AddInstTable(InstTable,"JCM", 0, DecodeJCN); + AddInstTable(InstTable,"JUN", 0, DecodeFullJmp); + AddInstTable(InstTable,"JMS", 1, DecodeFullJmp); + AddInstTable(InstTable,"ISZ", 0, DecodeISZ); + AddInstTable(InstTable,"FIM", 0, DecodeFIM); +END + + static void DeinitFields(void) +BEGIN + DestroyInstTable(InstTable); + free(FixedOrders); + free(OneRegOrders); + free(OneRRegOrders); + free(AccRegOrders); + free(Imm4Orders); +END + +/*---------------------------------------------------------------------------*/ +/* Callbacks */ + + static void MakeCode_4004(void) +BEGIN + CodeLen=0; DontPrint=False; + + /* zu ignorierendes */ + + if (Memo("")) return; + + /* Pseudoanweisungen */ + + if (DecodePseudo()) return; + + /* der Rest */ + + if (NOT LookupInstTable(InstTable, OpPart)) WrXError(1200, OpPart); +END + + static Boolean IsDef_4004(void) +BEGIN + return Memo("REG"); +END + + static void SwitchFrom_4004(void) +BEGIN + DeinitFields(); +END + + static void SwitchTo_4004(void) +BEGIN + PFamilyDescr FoundDescr; + + FoundDescr=FindFamilyByName("4004/4040"); + + TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False; + + PCSymbol="$"; HeaderID=FoundDescr->Id; NOPCode=0x00; + DivideChars=","; HasAttrs=False; + + ValidSegs=(1<