aboutsummaryrefslogtreecommitdiffstats
path: root/code8008.c
diff options
context:
space:
mode:
Diffstat (limited to 'code8008.c')
-rw-r--r--code8008.c356
1 files changed, 356 insertions, 0 deletions
diff --git a/code8008.c b/code8008.c
new file mode 100644
index 0000000..77c4399
--- /dev/null
+++ b/code8008.c
@@ -0,0 +1,356 @@
+/* code8008.c */
+/*****************************************************************************/
+/* AS-Portierung */
+/* */
+/* Codegenerator Intel 8008 */
+/* */
+/* Historie: 3.12.1998 Grundsteinlegung */
+/* 4.12.1998 FixedOrders begonnen */
+/* 3. 1.1999 ChkPC-Anpassung */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+#include <ctype.h>
+#include <string.h>
+
+#include "bpemu.h"
+#include "strutil.h"
+#include "asmdef.h"
+#include "asmsub.h"
+#include "asmpars.h"
+#include "asmitree.h"
+#include "headids.h"
+
+/*---------------------------------------------------------------------------*/
+/* Variablen */
+
+typedef struct
+ {
+ Byte Code;
+ } FixedOrder;
+
+#define FixedOrderCnt 10
+#define ImmOrderCnt 10
+#define JmpOrderCnt 10
+
+static CPUVar CPU8008;
+static PInstTable InstTable;
+
+static FixedOrder *FixedOrders, *ImmOrders, *JmpOrders;
+
+static char *RegNames = "ABCDEHLM";
+
+/*---------------------------------------------------------------------------*/
+/* Parser */
+
+ static Boolean DecodeReg(char *Asc, Byte *Erg)
+BEGIN
+ char *p;
+
+ if (strlen(Asc) != 2) return False;
+
+ p = strchr(RegNames, toupper(*Asc));
+ if (p != NULL) *Erg = p - RegNames;
+ return (p!= NULL);
+END
+
+/*---------------------------------------------------------------------------*/
+/* Hilfsdekoder */
+
+ static void DecodeFixed(Word Index)
+BEGIN
+ if (ArgCnt != 0) WrError(1110);
+ else
+ BEGIN
+ BAsmCode[0] = FixedOrders[Index].Code;
+ CodeLen = 1;
+ END
+END
+
+ static void DecodeImm(Word Index)
+BEGIN
+ Boolean OK;
+
+ if (ArgCnt != 1) WrError(1110);
+ else
+ BEGIN
+ BAsmCode[1] = EvalIntExpression(ArgStr[1], Int8, &OK);
+ if (OK)
+ BEGIN
+ BAsmCode[0] = ImmOrders[Index].Code;
+ CodeLen = 2;
+ END
+ END
+END
+
+ static void DecodeJmp(Word Index)
+BEGIN
+ Boolean OK;
+ Word AdrWord;
+
+ if (ArgCnt != 1) WrError(1110);
+ else
+ BEGIN
+ AdrWord = EvalIntExpression(ArgStr[1], UInt14, &OK);
+ if (OK)
+ BEGIN
+ BAsmCode[0] = JmpOrders[Index].Code;
+ BAsmCode[1] = Lo(AdrWord);
+ BAsmCode[2] = Hi(AdrWord) & 0x3f;
+ CodeLen = 3;
+ ChkSpace(SegCode);
+ END
+ END
+END
+
+ static void DecodeRST(Word Index)
+BEGIN
+ Boolean OK;
+ Word AdrWord;
+
+ if (ArgCnt != 1) WrError(1110);
+ else
+ BEGIN
+ FirstPassUnknown = False;
+ AdrWord = EvalIntExpression(ArgStr[1], UInt14, &OK);
+ if (FirstPassUnknown) AdrWord &= 0x38;
+ if (OK)
+ if (ChkRange(AdrWord, 0, 0x38))
+ if ((AdrWord & 7) != 0) WrError(1325);
+ else
+ BEGIN
+ BAsmCode[0] = AdrWord + 0x05;
+ CodeLen = 1;
+ ChkSpace(SegCode);
+ END
+ END
+END
+
+ static void DecodeINP(Word Index)
+BEGIN
+ Boolean OK;
+
+ if (ArgCnt != 1) WrError(1110);
+ else
+ BEGIN
+ BAsmCode[0] = 0x41 + (EvalIntExpression(ArgStr[1], UInt3, &OK) << 1);
+ if (OK)
+ BEGIN
+ CodeLen = 1;
+ ChkSpace(SegIO);
+ END
+ END
+END
+
+ static void DecodeOUT(Word Index)
+BEGIN
+ Boolean OK;
+
+ if (ArgCnt != 1) WrError(1110);
+ else
+ BEGIN
+ BAsmCode[0] = 0x41 + (EvalIntExpression(ArgStr[1], UInt3, &OK) << 1);
+ if (OK)
+ BEGIN
+ CodeLen = 1;
+ ChkSpace(SegIO);
+ END
+ END
+END
+
+ static Boolean DecodePseudo(void)
+BEGIN
+ return False;
+END
+
+/*---------------------------------------------------------------------------*/
+/* Codetabellenverwaltung */
+
+static int InstrZ;
+static char *FlagNames = "CZSP";
+
+ 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 AddFixeds(char *NName, Byte NCode, int Pos)
+BEGIN
+ char Memo[10], *p;
+ int z;
+
+ strcpy(Memo, NName); p = strchr(Memo, '*');
+ for (z = 0; z < 8; z++)
+ BEGIN
+ *p = RegNames[z];
+ AddFixed(Memo, NCode + (z << Pos));
+ END
+END
+
+ static void AddImm(char *NName, Byte NCode)
+BEGIN
+ if (InstrZ >= ImmOrderCnt) exit(255);
+ ImmOrders[InstrZ].Code = NCode;
+ AddInstTable(InstTable, NName, InstrZ++, DecodeImm);
+END
+
+ static void AddImms(char *NName, Byte NCode, int Pos)
+BEGIN
+ char Memo[10], *p;
+ int z;
+
+ strcpy(Memo, NName); p = strchr(Memo, '*');
+ for (z = 0; z < 8; z++)
+ BEGIN
+ *p = RegNames[z];
+ AddImm(Memo, NCode + (z << Pos));
+ END
+END
+
+ static void AddJmp(char *NName, Byte NCode)
+BEGIN
+ if (InstrZ >= JmpOrderCnt) exit(255);
+ JmpOrders[InstrZ].Code = NCode;
+ AddInstTable(InstTable, NName, InstrZ++, DecodeJmp);
+END
+
+ static void AddJmps(char *NName, Byte NCode, int Pos)
+BEGIN
+ char Memo[10], *p;
+ int z;
+
+ strcpy(Memo, NName); p = strchr(Memo, '*');
+ for (z = 0; z < 4; z++)
+ BEGIN
+ *p = FlagNames[z];
+ AddJmp(Memo, NCode + (z << Pos));
+ END
+END
+
+ static void InitFields(void)
+BEGIN
+ SetDynamicInstTable(InstTable=CreateInstTable(401));
+
+ FixedOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * FixedOrderCnt); InstrZ = 0;
+ AddFixeds("L*A", 0xc0, 3); AddFixeds("L*B", 0xc1, 3);
+ AddFixeds("L*C", 0xc2, 3); AddFixeds("L*D", 0xc3, 3);
+ AddFixeds("L*E", 0xc4, 3); AddFixeds("L*H", 0xc5, 3);
+ AddFixeds("L*L", 0xc6, 3); AddFixeds("L*M", 0xc7, 3);
+
+ AddFixeds("IN*", 0x00, 3);
+ AddFixeds("DC*", 0x01, 3);
+ AddFixeds("AD*", 0x80, 0);
+ AddFixeds("AC*", 0x88, 0);
+ AddFixeds("SU*", 0x90, 0);
+ AddFixeds("SB*", 0x98, 0);
+ AddFixeds("NR*", 0xa0, 0);
+ AddFixeds("XR*", 0xa8, 0);
+ AddFixeds("OR*", 0xb0, 0);
+ AddFixeds("CP*", 0xb8, 0);
+ AddFixed ("RLC", 0x02);
+ AddFixed ("RRC", 0x0a);
+ AddFixed ("RAL", 0x12);
+ AddFixed ("RAR", 0x1a);
+
+ AddFixed("RET", 0x07);
+ AddFixed("RFC", 0x03); AddFixed("RFZ", 0x0b);
+ AddFixed("RFS", 0x13); AddFixed("RFP", 0x1b);
+ AddFixed("RTC", 0x23); AddFixed("RTZ", 0x2b);
+ AddFixed("RTS", 0x33); AddFixed("RTP", 0x3b);
+ AddFixed("HLT", 0x00);
+
+ ImmOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * ImmOrderCnt); InstrZ = 0;
+ AddImms("L*I", 0x06, 3);
+ AddImm ("ADI", 0x04);
+ AddImm ("ACI", 0x0c);
+ AddImm ("SUI", 0x14);
+ AddImm ("SBI", 0x1c);
+ AddImm ("NDI", 0x24);
+ AddImm ("XRI", 0x2c);
+ AddImm ("ORI", 0x34);
+ AddImm ("CPI", 0x3c);
+
+ JmpOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * JmpOrderCnt); InstrZ = 0;
+ AddJmp ("JMP", 0x44);
+ AddJmps("JF*", 0x40, 3);
+ AddJmps("JT*", 0x60, 3);
+ AddJmp ("CAL", 0x46);
+ AddJmps("CF*", 0x42, 3);
+ AddJmps("CT*", 0x62, 3);
+
+ AddInstTable(InstTable, "RST", 0, DecodeRST);
+ AddInstTable(InstTable, "INP", 0, DecodeINP);
+ AddInstTable(InstTable, "OUT", 0, DecodeOUT);
+END
+
+ static void DeinitFields(void)
+BEGIN
+ DestroyInstTable(InstTable);
+ free(FixedOrders);
+ free(ImmOrders);
+ free(JmpOrders);
+END
+
+/*---------------------------------------------------------------------------*/
+/* Callbacks */
+
+ static void MakeCode_8008(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_8008(void)
+BEGIN
+ return False;
+END
+
+ static void SwitchFrom_8008(void)
+BEGIN
+ DeinitFields();
+END
+
+ static void SwitchTo_8008(void)
+BEGIN
+ PFamilyDescr FoundDescr;
+
+ FoundDescr=FindFamilyByName("8008");
+
+ TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False;
+
+ PCSymbol="$"; HeaderID=FoundDescr->Id; NOPCode=0x00;
+ DivideChars=","; HasAttrs=False;
+
+ ValidSegs=(1<<SegCode)|(1<<SegIO);
+ Grans[SegCode ]=1; ListGrans[SegCode ]=1; SegInits[SegCode ]=0;
+ SegLimits[SegCode] = 0x3fff;
+ Grans[SegIO ]=1; ListGrans[SegIO ]=1; SegInits[SegIO ]=0;
+ SegLimits[SegIO] = 7;
+
+ MakeCode=MakeCode_8008; IsDef=IsDef_8008;
+ SwitchFrom=SwitchFrom_8008;
+
+ InitFields();
+END
+
+/*---------------------------------------------------------------------------*/
+/* Initialisierung */
+
+ void code8008_init(void)
+BEGIN
+ CPU8008=AddCPU("8008",SwitchTo_8008);
+END