aboutsummaryrefslogtreecommitdiffstats
path: root/codefmc8.c
diff options
context:
space:
mode:
Diffstat (limited to 'codefmc8.c')
-rw-r--r--codefmc8.c1017
1 files changed, 1017 insertions, 0 deletions
diff --git a/codefmc8.c b/codefmc8.c
new file mode 100644
index 0000000..0cd1b1c
--- /dev/null
+++ b/codefmc8.c
@@ -0,0 +1,1017 @@
+/* codefmc8.c */
+/****************************************************************************/
+/* AS, C-Version */
+/* */
+/* Codegenerator fuer Fujitsu-F2MC8L-Prozessoren */
+/* */
+/* Historie: 4. 7.1999 Grundsteinlegung */
+/* 29. 7.1999 doppelte Variable entfernt */
+/* */
+/****************************************************************************/
+
+#include "stdinc.h"
+#include <string.h>
+#include <ctype.h>
+
+#include "bpemu.h"
+#include "strutil.h"
+#include "asmdef.h"
+#include "asmpars.h"
+#include "asmsub.h"
+#include "codepseudo.h"
+#include "codevars.h"
+#include "asmitree.h"
+#include "headids.h"
+
+/*--------------------------------------------------------------------------*/
+/* Definitionen */
+
+#define FixedOrderCnt 10
+#define ALUOrderCnt 5
+#define AccOrderCnt 10
+#define RelOrderCnt 12
+
+#define ModNone (-1)
+enum {ModAcc, ModDir, ModExt, ModIIX, ModIEP, ModIA, ModReg, ModReg16, ModT,
+ ModPC, ModPS, ModImm};
+#define MModAcc (1 << ModAcc)
+#define MModDir (1 << ModDir)
+#define MModExt (1 << ModExt)
+#define MModIIX (1 << ModIIX)
+#define MModIEP (1 << ModIEP)
+#define MModIA (1 << ModIA)
+#define MModReg (1 << ModReg)
+#define MModReg16 (1 << ModReg16)
+#define MModT (1 << ModT)
+#define MModPC (1 << ModPC)
+#define MModPS (1 << ModPS)
+#define MModImm (1 << ModImm)
+
+typedef struct
+ {
+ Byte Code;
+ } FixedOrder;
+
+static CPUVar CPU89190;
+
+static PInstTable InstTable;
+static FixedOrder *FixedOrders, *ALUOrders, *AccOrders, *RelOrders;
+
+static int AdrMode;
+static Byte AdrPart, AdrVals[2];
+static int OpSize;
+
+/*--------------------------------------------------------------------------*/
+/* Adressdekoder */
+
+ static void DecodeAdr(char *Asc, unsigned Mask)
+BEGIN
+ Boolean OK;
+ Word Address;
+
+ AdrMode = ModNone; AdrCnt = 0;
+
+ /* Register ? */
+
+ if (strcasecmp(Asc, "A") == 0)
+ AdrMode = ModAcc;
+
+ else if (strcasecmp(Asc, "SP") == 0)
+ BEGIN
+ AdrMode = ModReg16;
+ AdrPart = 1;
+ END
+
+ else if (strcasecmp(Asc, "IX") == 0)
+ BEGIN
+ AdrMode = ModReg16;
+ AdrPart = 2;
+ END
+
+ else if (strcasecmp(Asc, "EP") == 0)
+ BEGIN
+ AdrMode = ModReg16;
+ AdrPart = 3;
+ END
+
+ else if (strcasecmp(Asc, "T") == 0)
+ AdrMode = ModT;
+
+ else if (strcasecmp(Asc, "PC") == 0)
+ AdrMode = ModPC;
+
+ else if (strcasecmp(Asc, "PS") == 0)
+ AdrMode = ModPS;
+
+ else if ((strlen(Asc) == 2) AND (toupper(*Asc) == 'R') AND (Asc[1]>= '0') AND (Asc[1] <= '7'))
+ BEGIN
+ AdrMode = ModReg;
+ AdrPart = Asc[1] - '0' + 8;
+ END
+
+ /* immediate ? */
+
+ else if (*Asc == '#')
+ BEGIN
+ if (OpSize)
+ BEGIN
+ Address = EvalIntExpression(Asc + 1, Int16, &OK);
+ if (OK)
+ BEGIN
+ /***Problem: Byte order? */
+ AdrVals[0] = Lo(Address);
+ AdrVals[1] = Hi(Address);
+ AdrMode = ModImm;
+ AdrCnt = 2;
+ AdrPart = 4;
+ END
+ END
+ else
+ BEGIN
+ AdrVals[0] = EvalIntExpression(Asc + 1, Int8, &OK);
+ if (OK)
+ BEGIN
+ AdrMode = ModImm;
+ AdrCnt = 1;
+ AdrPart = 4;
+ END
+ END
+ END
+
+ /* indirekt ? */
+
+ else if (strcasecmp(Asc, "@EP") == 0)
+ BEGIN
+ AdrMode = ModIEP;
+ AdrPart = 7;
+ END
+
+ else if (strcasecmp(Asc, "@A") == 0)
+ BEGIN
+ AdrMode = ModIA;
+ AdrPart = 7;
+ END
+
+ else if (strncasecmp(Asc, "@IX", 3) == 0)
+ BEGIN
+ /***Problem: Offset signed oder unsigned? */
+ AdrVals[0] = EvalIntExpression(Asc + 3, SInt8, &OK);
+ if (OK)
+ BEGIN
+ AdrMode = ModIIX;
+ AdrCnt = 1;
+ AdrPart = 6;
+ END
+ END
+
+ /* direkt ? */
+
+ else
+ BEGIN
+ Address = EvalIntExpression(Asc, (Mask & MModExt) ? UInt16 : UInt8, &OK);
+ if (OK)
+ if ((Mask & MModDir) AND (Hi(Address) == 0))
+ BEGIN
+ AdrVals[0] = Lo(Address);
+ AdrMode = ModDir;
+ AdrCnt = 1;
+ AdrPart = 5;
+ END
+ else
+ BEGIN
+ AdrMode = ModExt;
+ AdrCnt = 2;
+ /***Problem: Byte order? */
+ AdrVals[0] = Lo(Address);
+ AdrVals[1] = Hi(Address);
+ END
+ END
+
+ /* erlaubt ? */
+
+ if ((AdrMode != ModNone) && ((Mask & (1 << AdrMode)) == 0))
+ BEGIN
+ WrError(1350);
+ AdrMode = ModNone;
+ AdrCnt = 0;
+ END
+END
+
+ static Boolean DecodeBitAdr(char *Asc, Byte *Adr, Byte *Bit)
+BEGIN
+ char *sep;
+ Boolean OK;
+
+ sep = strchr(Asc, ':');
+ if (sep == NULL) return FALSE;
+ *sep = '\0';
+
+ *Adr = EvalIntExpression(Asc, UInt8, &OK);
+ if (NOT OK) return FALSE;
+
+ *Bit = EvalIntExpression(sep + 1, UInt3, &OK);
+ if (NOT OK) return FALSE;
+
+ return TRUE;
+END
+
+/*--------------------------------------------------------------------------*/
+/* ind. Decoder */
+
+ static void DecodeFixed(Word Index)
+BEGIN
+ FixedOrder *porder = FixedOrders + Index;
+
+ if (ArgCnt != 0) WrError(1110);
+ else
+ BEGIN
+ BAsmCode[0] = porder->Code;
+ CodeLen = 1;
+ END
+END
+
+ static void DecodeAcc(Word Index)
+BEGIN
+ FixedOrder *porder = AccOrders + Index;
+
+ if (ArgCnt != 1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1], MModAcc);
+ if (AdrMode != ModNone)
+ BEGIN
+ BAsmCode[0] = porder->Code;
+ CodeLen = 1;
+ END
+ END
+END
+
+ static void DecodeALU(Word Index)
+BEGIN
+ FixedOrder *porder = ALUOrders + Index;
+
+ if ((ArgCnt != 1) AND (ArgCnt != 2)) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1], MModAcc);
+ if (AdrMode != ModNone)
+ if (ArgCnt == 1)
+ BEGIN
+ BAsmCode[0] = porder->Code + 2;
+ CodeLen = 1;
+ END
+ else
+ BEGIN
+ OpSize = 0;
+ DecodeAdr(ArgStr[2], MModDir | MModIIX | MModIEP | MModReg | MModImm);
+ if (AdrMode != ModNone)
+ BEGIN
+ BAsmCode[0] = porder->Code + AdrPart;
+ memcpy(BAsmCode + 1, AdrVals, AdrCnt);
+ CodeLen = 1 + AdrCnt;
+ END
+ END
+ END
+END
+
+ static void DecodeRel(Word Index)
+BEGIN
+ Integer Adr;
+ Boolean OK;
+ FixedOrder *porder = RelOrders + Index;
+
+ if (ArgCnt != 1) WrError(1110);
+ else
+ BEGIN
+ Adr = EvalIntExpression(ArgStr[1], UInt16, &OK) - (EProgCounter() + 2);
+ if (OK)
+ if (((Adr < -128) OR (Adr > 127)) AND (NOT SymbolQuestionable)) WrError(1370);
+ else
+ BEGIN
+ BAsmCode[0] = porder->Code;
+ BAsmCode[1] = Adr & 0xff;
+ CodeLen = 2;
+ END
+ END
+END
+
+ static void DecodeMOV(Word Index)
+BEGIN
+ Byte HReg;
+
+ if (ArgCnt != 2) WrError(1110);
+ else
+ BEGIN
+ OpSize = 0;
+ DecodeAdr(ArgStr[1], MModAcc | MModDir | MModIIX | MModIEP | MModExt | MModReg | MModIA);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ DecodeAdr(ArgStr[2], MModDir | MModIIX | MModIEP | MModIA | MModReg | MModImm| MModExt);
+ switch (AdrMode)
+ BEGIN
+ case ModDir:
+ case ModIIX:
+ case ModIEP:
+ case ModReg:
+ case ModImm:
+ BAsmCode[0] = 0x00 + AdrPart;
+ memcpy(BAsmCode + 1, AdrVals, AdrCnt);
+ CodeLen = 1 + AdrCnt;
+ break;
+ case ModExt:
+ BAsmCode[0] = 0x60;
+ memcpy(BAsmCode + 1, AdrVals, AdrCnt);
+ CodeLen = 1 + AdrCnt;
+ break;
+ case ModIA:
+ BAsmCode[0] = 0x92;
+ CodeLen = 1 + AdrCnt;
+ break;
+ END
+ break;
+
+ case ModDir:
+ BAsmCode[1] = AdrVals[0];
+ DecodeAdr(ArgStr[2], MModAcc | MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ BAsmCode[0] = 0x45;
+ CodeLen = 2;
+ break;
+ case ModImm:
+ BAsmCode[0] = 0x85; /***turn Byte 1+2 for F2MC ? */
+ BAsmCode[2] = AdrVals[0];
+ CodeLen = 3;
+ break;
+ END
+ break;
+
+ case ModIIX:
+ BAsmCode[1] = AdrVals[0];
+ DecodeAdr(ArgStr[2], MModAcc | MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ BAsmCode[0] = 0x46;
+ CodeLen = 2;
+ break;
+ case ModImm:
+ BAsmCode[0] = 0x86; /***turn Byte 1+2 for F2MC ? */
+ BAsmCode[2] = AdrVals[0];
+ CodeLen = 3;
+ break;
+ END
+ break;
+
+ case ModIEP:
+ DecodeAdr(ArgStr[2], MModAcc | MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ BAsmCode[0] = 0x47;
+ CodeLen = 1;
+ break;
+ case ModImm:
+ BAsmCode[0] = 0x87;
+ BAsmCode[1] = AdrVals[0];
+ CodeLen = 2;
+ break;
+ END
+ break;
+
+ case ModExt:
+ BAsmCode[1] = AdrVals[0]; BAsmCode[2] = AdrVals[1];
+ DecodeAdr(ArgStr[2], MModAcc);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ BAsmCode[0] = 0x61;
+ CodeLen = 3;
+ break;
+ END
+ break;
+
+ case ModReg:
+ HReg = AdrPart;
+ DecodeAdr(ArgStr[2], MModAcc | MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ BAsmCode[0] = 0x40 + HReg;
+ CodeLen = 1;
+ break;
+ case ModImm:
+ BAsmCode[0] = 0x80 + HReg;
+ BAsmCode[1] = AdrVals[0];
+ CodeLen = 2;
+ break;
+ END
+ break;
+
+ case ModIA:
+ DecodeAdr(ArgStr[2], MModT);
+ switch (AdrMode)
+ BEGIN
+ case ModT:
+ BAsmCode[0] = 0x82;
+ CodeLen = 1;
+ break;
+ END
+ break;
+ END
+ END
+END
+
+ static void DecodeMOVW(Word Index)
+BEGIN
+ Byte HReg;
+
+ OpSize = 1;
+ if (ArgCnt != 2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1], MModAcc | MModDir | MModIIX | MModExt | MModIEP | MModReg16 | MModIA | MModPS);
+ switch(AdrMode)
+ BEGIN
+ case ModAcc:
+ DecodeAdr(ArgStr[2], MModImm | MModDir | MModIEP | MModIIX | MModExt | MModIA | MModReg16 | MModPS | MModPC);
+ switch (AdrMode)
+ BEGIN
+ case ModImm:
+ BAsmCode[0] = 0xe4;
+ memcpy(BAsmCode + 1, AdrVals, AdrCnt);
+ CodeLen = 1 + AdrCnt;
+ break;
+ case ModExt:
+ BAsmCode[0] = 0xc4;
+ memcpy(BAsmCode + 1, AdrVals, AdrCnt);
+ CodeLen = 1 + AdrCnt;
+ break;
+ case ModDir:
+ case ModIEP:
+ case ModIIX:
+ BAsmCode[0] = 0xc0 | AdrPart;
+ memcpy(BAsmCode + 1, AdrVals, AdrCnt);
+ CodeLen = 1 + AdrCnt;
+ break;
+ case ModIA:
+ BAsmCode[0] = 0x93;
+ CodeLen = 1;
+ break;
+ case ModReg16:
+ BAsmCode[0] = 0xf0 + AdrPart;
+ CodeLen = 1;
+ break;
+ case ModPS:
+ BAsmCode[0] = 0x70;
+ CodeLen = 1;
+ break;
+ case ModPC:
+ BAsmCode[0] = 0xf0;
+ CodeLen = 1;
+ break;
+ END
+ break;
+
+ case ModDir:
+ BAsmCode[1] = AdrVals[0];
+ DecodeAdr(ArgStr[2], MModAcc);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ BAsmCode[0] = 0xd5;
+ CodeLen = 2;
+ break;
+ END
+ break;
+
+ case ModIIX:
+ BAsmCode[1] = AdrVals[0];
+ DecodeAdr(ArgStr[2], MModAcc);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ BAsmCode[0] = 0xd6;
+ CodeLen = 2;
+ break;
+ END
+ break;
+
+ case ModExt:
+ BAsmCode[1] = AdrVals[0]; BAsmCode[2] = AdrVals[1];
+ DecodeAdr(ArgStr[2], MModAcc);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ BAsmCode[0] = 0xd4;
+ CodeLen = 3;
+ break;
+ END
+ break;
+
+ case ModIEP:
+ DecodeAdr(ArgStr[2], MModAcc);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ BAsmCode[0] = 0xd7;
+ CodeLen = 1;
+ break;
+ END
+ break;
+
+ case ModReg16:
+ HReg = AdrPart;
+ DecodeAdr(ArgStr[2], MModAcc | MModImm);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ BAsmCode[0] = 0xe0 + HReg;
+ CodeLen = 1;
+ break;
+ case ModImm:
+ BAsmCode[0] = 0xe4 + HReg;
+ memcpy(BAsmCode + 1, AdrVals, AdrCnt);
+ CodeLen = 1 + AdrCnt;
+ break;
+ END
+ break;
+
+ case ModIA:
+ DecodeAdr(ArgStr[2], MModT);
+ switch (AdrMode)
+ BEGIN
+ case ModT:
+ BAsmCode[0] = 0x83;
+ CodeLen = 1;
+ break;
+ END
+ break;
+
+ case ModPS:
+ DecodeAdr(ArgStr[2], MModAcc);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ BAsmCode[0] = 0x71;
+ CodeLen = 1;
+ break;
+ END
+ break;
+ END
+ END
+END
+
+ static void DecodeBit(Word Index)
+BEGIN
+ Byte Adr, Bit;
+
+ if (ArgCnt != 1) WrError(1110);
+ else if (NOT DecodeBitAdr(ArgStr[1], &Adr, &Bit)) WrError(1350);
+ else
+ BEGIN
+ BAsmCode[0] = 0xa0 + (Index << 3) + Bit;
+ BAsmCode[1] = Adr;
+ CodeLen = 2;
+ END;
+END
+
+ static void DecodeXCH(Word Index)
+BEGIN
+ if (ArgCnt != 2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1], MModAcc | MModT);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ DecodeAdr(ArgStr[2], MModT);
+ if (AdrMode != ModNone)
+ BEGIN
+ BAsmCode[0] = 0x42;
+ CodeLen = 1;
+ END
+ break;
+ case ModT:
+ DecodeAdr(ArgStr[2], MModAcc);
+ if (AdrMode != ModNone)
+ BEGIN
+ BAsmCode[0] = 0x42;
+ CodeLen = 1;
+ END
+ break;
+ END
+ END
+END
+
+ static void DecodeXCHW(Word Index)
+BEGIN
+ Byte HReg;
+
+ if (ArgCnt != 2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1], MModAcc | MModT | MModReg16 | MModPC);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ DecodeAdr(ArgStr[2], MModT | MModReg16 | MModPC);
+ switch (AdrMode)
+ BEGIN
+ case ModT:
+ BAsmCode[0] = 0x43;
+ CodeLen = 1;
+ break;
+ case ModReg16:
+ BAsmCode[0] = 0xf4 + AdrPart;
+ CodeLen = 1;
+ break;
+ case ModPC:
+ BAsmCode[0] = 0xf4;
+ CodeLen = 1;
+ break;
+ END
+ break;
+ case ModT:
+ DecodeAdr(ArgStr[2], MModAcc);
+ if (AdrMode != ModNone)
+ BEGIN
+ BAsmCode[0] = 0x43;
+ CodeLen = 1;
+ END
+ break;
+ case ModReg16:
+ HReg = AdrPart;
+ DecodeAdr(ArgStr[2], MModAcc);
+ if (AdrMode != ModNone)
+ BEGIN
+ BAsmCode[0] = 0xf4 | HReg;
+ CodeLen = 1;
+ END
+ break;
+ case ModPC:
+ DecodeAdr(ArgStr[2], MModAcc);
+ if (AdrMode != ModNone)
+ BEGIN
+ BAsmCode[0] = 0xf4;
+ CodeLen = 1;
+ END
+ END
+ END
+END
+
+ static void DecodeINCDEC(Word Index)
+BEGIN
+ if (ArgCnt != 1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1], MModReg);
+ if (AdrMode != ModNone)
+ BEGIN
+ BAsmCode[0] = 0xc0 + (Index << 4) + AdrPart;
+ CodeLen = 1;
+ END
+ END
+END
+
+ static void DecodeINCDECW(Word Index)
+BEGIN
+ if (ArgCnt != 1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1], MModAcc | MModReg16);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ BAsmCode[0] = 0xc0 + (Index << 4);
+ CodeLen = 1;
+ break;
+ case ModReg16:
+ BAsmCode[0] = 0xc0 + (Index << 4) + AdrPart;
+ CodeLen = 1;
+ break;
+ END
+ END
+END
+
+ static void DecodeCMP(Word Index)
+BEGIN
+ Byte HReg;
+
+ if ((ArgCnt != 1) AND (ArgCnt != 2)) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1], MModAcc | MModDir | MModIIX | MModIEP | MModReg);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ if (ArgCnt == 1)
+ BEGIN
+ BAsmCode[0] = 0x12;
+ CodeLen = 1;
+ END
+ else
+ BEGIN
+ DecodeAdr(ArgStr[2], MModDir | MModIEP | MModIIX | MModReg | MModImm);
+ if (AdrMode != ModNone)
+ BEGIN
+ BAsmCode[0] = 0x10 + AdrPart;
+ memcpy(BAsmCode + 1, AdrVals, AdrCnt);
+ CodeLen = 1 + AdrCnt;
+ END
+ END
+ break;
+ case ModDir:
+ if (ArgCnt != 2) WrError(1110);
+ else
+ BEGIN
+ BAsmCode[1] = AdrVals[0];
+ DecodeAdr(ArgStr[2], MModImm);
+ if (AdrMode != ModNone)
+ BEGIN
+ BAsmCode[0] = 0x95;
+ BAsmCode[2] = AdrVals[0]; /* reverse for F2MC8 */
+ CodeLen = 3;
+ END
+ END
+ break;
+ case ModIIX:
+ if (ArgCnt != 2) WrError(1110);
+ else
+ BEGIN
+ BAsmCode[1] = AdrVals[0];
+ DecodeAdr(ArgStr[2], MModImm);
+ if (AdrMode != ModNone)
+ BEGIN
+ BAsmCode[0] = 0x96;
+ BAsmCode[2] = AdrVals[0]; /* reverse for F2MC8 */
+ CodeLen = 3;
+ END
+ END
+ break;
+ case ModIEP:
+ if (ArgCnt != 2) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[2], MModImm);
+ if (AdrMode != ModNone)
+ BEGIN
+ BAsmCode[0] = 0x97;
+ BAsmCode[1] = AdrVals[0];
+ CodeLen = 2;
+ END
+ END
+ break;
+ case ModReg:
+ if (ArgCnt != 2) WrError(1110);
+ else
+ BEGIN
+ HReg = AdrPart;
+ DecodeAdr(ArgStr[2], MModImm);
+ if (AdrMode != ModNone)
+ BEGIN
+ BAsmCode[0] = 0x90 + HReg;
+ BAsmCode[1] = AdrVals[0];
+ CodeLen = 2;
+ END
+ END
+ break;
+ END
+ END
+END
+
+ static void DecodeBitBr(Word Index)
+BEGIN
+ Byte Bit, BAdr;
+ Boolean OK;
+ Integer Adr;
+
+ if (ArgCnt != 2) WrError(1110);
+ else if (NOT DecodeBitAdr(ArgStr[1], &BAdr, &Bit)) WrError(1350);
+ else
+ BEGIN
+ Adr = EvalIntExpression(ArgStr[2], UInt16, &OK) - (EProgCounter() + 3);
+ if (OK)
+ if (((Adr < -128) OR (Adr > 127)) AND (NOT SymbolQuestionable)) WrError(1370);
+ else
+ BEGIN
+ BAsmCode[0] = 0xb0 + (Index << 3) + Bit;
+ BAsmCode[1] = BAdr; /* reverse for F2MC8? */
+ BAsmCode[2] = Adr & 0xff;
+ CodeLen = 3;
+ END
+ END
+END
+
+ static void DecodeJmp(Word Index)
+BEGIN
+ if (ArgCnt != 1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1], MModExt | ((Index) ? 0 : MModIA));
+ switch (AdrMode)
+ BEGIN
+ case ModIA:
+ BAsmCode[0] = 0xe0;
+ CodeLen = 1;
+ break;
+ case ModExt:
+ BAsmCode[0] = 0x21 | (Index << 4);
+ memcpy(BAsmCode + 1, AdrVals, AdrCnt);
+ CodeLen = 1 + AdrCnt;
+ break;
+ END
+ END
+END
+
+ static void DecodeCALLV(Word Index)
+BEGIN
+ Boolean OK;
+
+ if (ArgCnt != 1) WrError(1110);
+ else if (*ArgStr[1] != '#') WrError(1120);
+ else
+ BEGIN
+ BAsmCode[0] = 0xb8 + EvalIntExpression(ArgStr[1] + 1, UInt3, &OK);
+ if (OK) CodeLen = 1;
+ END
+END
+
+ static void DecodeStack(Word Index)
+BEGIN
+ if (ArgCnt != 1) WrError(1110);
+ else
+ BEGIN
+ DecodeAdr(ArgStr[1], MModAcc | MModReg16);
+ switch (AdrMode)
+ BEGIN
+ case ModAcc:
+ BAsmCode[0] = 0x40 + (Index << 4);
+ CodeLen = 1;
+ break;
+ case ModReg16:
+ if (AdrPart != 2) WrXError(1445, ArgStr[1]);
+ else
+ BEGIN
+ BAsmCode[0] = 0x41 + (Index << 4);
+ CodeLen = 1;
+ END
+ break;
+ END
+ END
+END
+
+/*--------------------------------------------------------------------------*/
+/* Codetabellen */
+
+ 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 AddALU(char *NName, Byte NCode)
+BEGIN
+ if (InstrZ > ALUOrderCnt) exit(255);
+
+ ALUOrders[InstrZ].Code = NCode;
+ AddInstTable(InstTable, NName, InstrZ++, DecodeALU);
+END
+
+ static void AddAcc(char *NName, Byte NCode)
+BEGIN
+ if (InstrZ > AccOrderCnt) exit(255);
+
+ AccOrders[InstrZ].Code = NCode;
+ AddInstTable(InstTable, NName, InstrZ++, DecodeAcc);
+END
+
+ static void AddRel(char *NName, Byte NCode)
+BEGIN
+ if (InstrZ > RelOrderCnt) exit(255);
+
+ RelOrders[InstrZ].Code = NCode;
+ AddInstTable(InstTable, NName, InstrZ++, DecodeRel);
+END
+
+ static void InitFields(void)
+BEGIN
+ InstTable = CreateInstTable(201);
+
+ FixedOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * FixedOrderCnt);
+ InstrZ = 0;
+ AddFixed("SWAP" , 0x10); AddFixed("DAA" , 0x84);
+ AddFixed("DAS" , 0x94); AddFixed("RET" , 0x20);
+ AddFixed("RETI" , 0x30); AddFixed("NOP" , 0x00);
+ AddFixed("CLRC" , 0x81); AddFixed("SETC" , 0x91);
+ AddFixed("CLRI" , 0x80); AddFixed("SETI" , 0x90);
+
+ ALUOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * ALUOrderCnt);
+ InstrZ = 0;
+ AddALU("ADDC" , 0x20); AddALU("SUBC" , 0x30);
+ AddALU("XOR" , 0x50); AddALU("AND" , 0x60);
+ AddALU("OR" , 0x70);
+
+ AccOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * AccOrderCnt);
+ InstrZ = 0;
+ AddAcc("ADDCW" , 0x23); AddAcc("SUBCW" , 0x33);
+ AddAcc("MULU" , 0x01); AddAcc("DIVU" , 0x11);
+ AddAcc("ANDW" , 0x63); AddAcc("ORW" , 0x73);
+ AddAcc("XORW" , 0x53); AddAcc("CMPW" , 0x13);
+ AddAcc("RORC" , 0x03); AddAcc("ROLC" , 0x02);
+
+ RelOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * RelOrderCnt);
+ InstrZ = 0;
+ AddRel("BEQ", 0xfd); AddRel("BZ" , 0xfd);
+ AddRel("BNZ", 0xfc); AddRel("BNE", 0xfc);
+ AddRel("BC" , 0xf9); AddRel("BLO", 0xf9);
+ AddRel("BNC", 0xf8); AddRel("BHS", 0xf8);
+ AddRel("BN" , 0xfb); AddRel("BP" , 0xfa);
+ AddRel("BLT", 0xff); AddRel("BGE", 0xfe);
+
+ AddInstTable(InstTable, "MOV", 0, DecodeMOV);
+ AddInstTable(InstTable, "MOVW", 0, DecodeMOVW);
+ AddInstTable(InstTable, "XCH", 0, DecodeXCH);
+ AddInstTable(InstTable, "XCHW", 0, DecodeXCHW);
+ AddInstTable(InstTable, "SETB", 1, DecodeBit);
+ AddInstTable(InstTable, "CLRB", 0, DecodeBit);
+ AddInstTable(InstTable, "INC", 0, DecodeINCDEC);
+ AddInstTable(InstTable, "DEC", 1, DecodeINCDEC);
+ AddInstTable(InstTable, "INCW", 0, DecodeINCDECW);
+ AddInstTable(InstTable, "DECW", 1, DecodeINCDECW);
+ AddInstTable(InstTable, "CMP", 0, DecodeCMP);
+ AddInstTable(InstTable, "BBC", 0, DecodeBitBr);
+ AddInstTable(InstTable, "BBS", 1, DecodeBitBr);
+ AddInstTable(InstTable, "JMP", 0, DecodeJmp);
+ AddInstTable(InstTable, "CALL", 1, DecodeJmp);
+ AddInstTable(InstTable, "CALLV", 0, DecodeCALLV);
+ AddInstTable(InstTable, "PUSHW", 0, DecodeStack);
+ AddInstTable(InstTable, "POPW", 1, DecodeStack);
+END
+
+ static void DeinitFields(void)
+BEGIN
+ free(FixedOrders);
+ free(ALUOrders);
+ free(AccOrders);
+ free(RelOrders);
+ DestroyInstTable(InstTable);
+END
+
+/*--------------------------------------------------------------------------*/
+/* Interface zu AS */
+
+ static void MakeCode_F2MC8(void)
+BEGIN
+ /* Leeranweisung ignorieren */
+
+ if (Memo("")) return;
+
+ /* Pseudoanweisungen */
+
+ if (DecodeIntelPseudo(False)) return;
+
+ if (NOT LookupInstTable(InstTable, OpPart))
+ WrXError(1200, OpPart);
+END
+
+ static Boolean IsDef_F2MC8(void)
+BEGIN
+ return FALSE;
+END
+
+ static void SwitchFrom_F2MC8(void)
+BEGIN
+ DeinitFields();
+END
+
+ static void SwitchTo_F2MC8(void)
+BEGIN
+ PFamilyDescr FoundDescr;
+
+ FoundDescr = FindFamilyByName("F2MC8");
+
+ TurnWords = False; ConstMode = ConstModeIntel; SetIsOccupied = False;
+
+ PCSymbol = "$"; HeaderID = FoundDescr->Id; NOPCode=0x00;
+ DivideChars = ","; HasAttrs = False;
+
+ ValidSegs = 1 << SegCode;
+ Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
+ SegLimits[SegCode] = 0xffff;
+
+ MakeCode = MakeCode_F2MC8; IsDef = IsDef_F2MC8;
+ SwitchFrom = SwitchFrom_F2MC8; InitFields();
+END
+
+/*--------------------------------------------------------------------------*/
+/* Initialisierung */
+
+ void codef2mc8_init(void)
+BEGIN
+ CPU89190 = AddCPU("MB89190", SwitchTo_F2MC8);
+END