aboutsummaryrefslogtreecommitdiffstats
path: root/code53c8xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'code53c8xx.c')
-rw-r--r--code53c8xx.c1055
1 files changed, 1055 insertions, 0 deletions
diff --git a/code53c8xx.c b/code53c8xx.c
new file mode 100644
index 0000000..e5808e6
--- /dev/null
+++ b/code53c8xx.c
@@ -0,0 +1,1055 @@
+/* code53c8xx.c */
+/*****************************************************************************/
+/* Makroassembler AS */
+/* */
+/* Codegenerator SYM53C8xx */
+/* */
+/* Historie: 30. 9.1998 angelegt */
+/* 3.10.1998 erste Befehle (NOP JUMP CALL RETURN INT INTFLY) */
+/* 4.10.1998 CHMOV CLEAR SET DISCONNECT LOAD STORE */
+/* 7.10.1998 MOVE begonnen */
+/* 15.11.1998 SELECT/RESELECT, WAIT */
+/* 3. 1.1999 ChkPC-Anpassung */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+#include <string.h>
+#include <ctype.h>
+
+#include "asmdef.h"
+#include "asmsub.h"
+#include "asmpars.h"
+#include "asmitree.h"
+#include "headids.h"
+#include "strutil.h"
+
+/*---------------------------------------------------------------------------*/
+
+#define RegCnt 69
+
+typedef struct
+ {
+ char *Name;
+ LongWord Code;
+ Word Mask;
+ } TReg, *PReg;
+
+static CPUVar CPU53C810, CPU53C860, CPU53C815, CPU53C825, CPU53C875,
+ CPU53C895;
+
+#define M_53C810 0x0001
+#define M_53C860 0x0002
+#define M_53C815 0x0004
+#define M_53C825 0x0008
+#define M_53C875 0x0010
+#define M_53C895 0x0020
+
+static PInstTable InstTable;
+static PReg Regs;
+
+/*---------------------------------------------------------------------------*/
+
+ static Boolean IsInToken(char Inp)
+BEGIN
+ return ((Inp == '_') OR (isalnum(((usint) Inp) & 0xff)));
+END
+
+ static void GetToken(char *Src, char *Dest)
+BEGIN
+ char *p, *start, Save;
+
+ /* Anfang suchen */
+
+ for (p = Src; isspace(*p); p++)
+ if (*p == '\0') break;
+ if (*p == '\0')
+ BEGIN
+ *Dest = *Src = '\0'; return;
+ END
+ start = p;
+
+ /* geklammerter Ausdruck ? */
+
+ if (*p == '(')
+ BEGIN
+ p = QuotPos(p, ')');
+ if (p == Nil)
+ BEGIN
+ strcpy(Dest, start); *Src = '\0';
+ END
+ else
+ BEGIN
+ Save = p[1]; p[1] = '\0';
+ strcpy(Dest, start);
+ p[1] = Save; strcpy(Src, p + 1);
+ END
+ END
+
+ /* Spezialtoken ? */
+
+ else if (NOT IsInToken(*p))
+ BEGIN
+ *Dest = *p; Dest[1] = '\0';
+ strcpy(Src, p + 1);
+ END
+
+ /* Wort ? */
+
+ else
+ BEGIN
+ for (; IsInToken(*p); p++)
+ if (*p == '\0') break;
+ Save = *p; *p = '\0';
+ strcpy(Dest, start);
+ *p = Save; strcpy(Src, p);
+ END
+END
+
+#if 0
+ static void GetRToken(char *Src, char *Dest)
+BEGIN
+ char *p;
+
+ KillPostBlanks(Src);
+
+ p = Src + strlen(Src) - 1;
+
+ /* geklammerter Ausdruck ? */
+
+ if (*p == ')')
+ BEGIN
+ p = RQuotPos(p, ')');
+ if (p == Nil)
+ BEGIN
+ strcpy(Dest, Src); *Src = '\0';
+ END
+ else
+ BEGIN
+ strcpy(Dest, p); *p = '\0';
+ END
+ END
+
+ /* Spezieltoken ? */
+
+ else if (NOT IsInToken(*p))
+ BEGIN
+ *Dest = *p; Dest[1] = '\0';
+ *p = '\0';
+ END
+
+ else
+ BEGIN
+ for (; IsInToken(*p); p--)
+ if (p <= Src) break;
+ if (NOT IsInToken(*p)) p++;
+ strcpy(Dest, p); *p = '\0';
+ END
+END
+#endif
+
+ static Boolean DecodePhase(char *Name, LongWord *Result)
+BEGIN
+ *Result = 8;
+ if (strcasecmp(Name, "DATA_OUT") == 0) *Result = 0;
+ else if (strcasecmp(Name, "DATA_IN") == 0) *Result = 1;
+ else if (strcasecmp(Name, "COMMAND") == 0) *Result = 2;
+ else if (strcasecmp(Name, "STATUS") == 0) *Result = 3;
+ else if (strcasecmp(Name, "RES4") == 0) *Result = 4;
+ else if (strcasecmp(Name, "RES5") == 0) *Result = 5;
+ else if (strcasecmp(Name, "MESSAGE_OUT") == 0) *Result = 6;
+ else if (strcasecmp(Name, "MESSAGE_IN") == 0) *Result = 7;
+ return (*Result < 8);
+END
+
+ static Boolean DecodeReg(char *Name, LongWord *Result)
+BEGIN
+ int z;
+ Integer Mask = 1 << (MomCPU - CPU53C810);
+ PReg Reg;
+
+ for (z = 0, Reg = Regs; z < RegCnt; z++, Reg++)
+ if ((strcasecmp(Reg->Name, Name) == 0) AND (Mask & Reg->Mask))
+ BEGIN
+ *Result = Reg->Code; return True;
+ END
+
+ return False;
+END
+
+ static Boolean Err(int Num, char *Msg)
+BEGIN
+ WrXError(Num, Msg);
+ return False;
+END
+
+ static Boolean DecodeCond(char *Src, LongWord *Dest)
+BEGIN
+ String Tok;
+ Boolean PhaseATNUsed, DataUsed, CarryUsed, MaskUsed;
+ LongWord Tmp;
+ Boolean OK;
+
+ /* IF/WHEN/Nix-Unterscheidung - TRUE fuer Nix setzen */
+
+ GetToken(Src, Tok);
+ if (*Tok == '\0')
+ BEGIN
+ *Dest |= 0x00080000;
+ return True;
+ END
+
+ if (strcasecmp(Tok, "WHEN") == 0)
+ *Dest |= 0x00010000;
+ else if (strcasecmp(Tok, "IF") != 0)
+ return Err(1135, Tok);
+
+ /* Negierung? */
+
+ GetToken(Src, Tok);
+ if (strcasecmp(Tok, "NOT") == 0) GetToken(Src, Tok);
+ else *Dest |= 0x00080000;
+
+ /* Bedingungen durchgehen */
+
+ PhaseATNUsed = DataUsed = MaskUsed = CarryUsed = False;
+ do
+ BEGIN
+ if (strcasecmp(Tok, "ATN") == 0)
+ BEGIN
+ if (PhaseATNUsed) return Err(1350, "2 x ATN/Phase");
+ if (CarryUsed) return Err(1350, "Carry + ATN/Phase");
+ if ((*Dest & 0x00010000) != 0) return Err(1350, "WHEN + ATN");
+ PhaseATNUsed = True; *Dest |= 0x00020000;
+ END
+ else if (DecodePhase(Tok, &Tmp))
+ BEGIN
+ if (PhaseATNUsed) return Err(1350, "2 x ATN/Phase");
+ if (CarryUsed) return Err(1350, "Carry + ATN/Phase");
+ PhaseATNUsed = True; *Dest |= 0x00020000 + (Tmp << 24);
+ END
+ else if (strcasecmp(Tok, "CARRY") == 0)
+ BEGIN
+ if (CarryUsed) return Err(1350, "2 x Carry");
+ if ((PhaseATNUsed) OR (DataUsed)) return Err(1350, "Carry + ...");
+ CarryUsed = True; *Dest |= 0x00200000;
+ END
+ else if (strcasecmp(Tok, "MASK") == 0)
+ BEGIN
+ if (CarryUsed) return Err(1350, "Carry + Data");
+ if (MaskUsed) return Err(1350, "2 x Mask");
+ if (NOT DataUsed) return Err(1350, "Mask + !Data");
+ GetToken(Src, Tok);
+ Tmp = EvalIntExpression(Tok, UInt8, &OK);
+ if (!OK) return False;
+ MaskUsed = True; *Dest |= (Tmp << 8);
+ END
+ else
+ BEGIN
+ if (CarryUsed) return Err(1350, "Carry + Data");
+ if (DataUsed) return Err(1350, "2 x Data");
+ Tmp = EvalIntExpression(Tok, UInt8, &OK);
+ if (!OK) return False;
+ DataUsed = True; *Dest |= 0x00040000 + Tmp;
+ END
+ GetToken(Src, Tok);
+ if (*Tok != '\0')
+ BEGIN
+ if (strcasecmp(Tok, "AND") != 0) return Err(1350, Tok);
+ GetToken(Src, Tok);
+ END
+ END
+ while (*Tok != '\0');
+
+ return True;
+END
+
+typedef enum {NONE, SFBR, REGISTER, IMM8} CompType;
+
+ CompType DecodeComp(char *Inp, LongWord *Outp)
+BEGIN
+ Boolean OK;
+
+ if (strcasecmp(Inp, "SFBR") == 0) return SFBR;
+ else if (DecodeReg(Inp, Outp)) return REGISTER;
+ else
+ BEGIN
+ *Outp = EvalIntExpression(Inp, Int8, &OK) & 0xff;
+ return (OK) ? IMM8 : NONE;
+ END
+END
+
+/*---------------------------------------------------------------------------*/
+
+static int InstrZ;
+
+ static void DecodeFixed(Word Index)
+BEGIN
+ if (ArgCnt != 0) WrError(1110);
+ else
+ BEGIN
+ DAsmCode[0] = ((LongWord) Index) << 24;
+ DAsmCode[1] = 0x00000000;
+ CodeLen = 8;
+ END
+END
+
+ static void DecodeJmps(Word Index)
+BEGIN
+ LongWord Buf;
+ LongInt Adr;
+ int l;
+ Boolean OK;
+
+ if (ArgCnt == 0)
+ if (Memo("INTFLY"))
+ BEGIN
+ ArgCnt = 1; strcpy(ArgStr[1], "0");
+ END
+ else if (Memo("RETURN"))
+ BEGIN
+ ArgCnt = 1; *ArgStr[1] = '\0';
+ END
+ if ((ArgCnt != 2) AND (ArgCnt!= 1)) WrError(1110);
+ else
+ BEGIN
+ if (ArgCnt == 1)
+ if (Memo("RETURN")) strcpy(ArgStr[2], ArgStr[1]);
+ else *ArgStr[2] = '\0';
+ Buf = 0;
+ if (Memo("RETURN")) Adr = 0;
+ else
+ BEGIN
+ l = strlen(ArgStr[1]);
+ if ((strncasecmp(ArgStr[1], "REL(", 4) == 0) AND (ArgStr[1][l - 1] == ')'))
+ BEGIN
+ if (*OpPart == 'I')
+ BEGIN
+ WrError(1350); OK = False;
+ END
+ Buf |= 0x00800000;
+ strcpy(ArgStr[1], ArgStr[1] + 4); ArgStr[1][l - 5] = '\0';
+ END
+ Adr = EvalIntExpression(ArgStr[1], UInt32, &OK);
+ if ((OK) AND (Buf != 0))
+ BEGIN
+ Adr -= EProgCounter() + 8;
+ if ((NOT SymbolQuestionable) AND ((Adr > 0x7fffff) OR (Adr < -0x800000)))
+ BEGIN
+ WrError(1370); OK = False;
+ END
+ END
+ END
+ if ((OK) AND (DecodeCond(ArgStr[2], &Buf)))
+ BEGIN
+ DAsmCode[0] = 0x80000000 + (((LongWord) Index) << 27) + Buf;
+ if (Memo("INTFLY")) DAsmCode[0] |= 0x00100000;
+ DAsmCode[1] = Adr;
+ CodeLen = 8;
+ END
+ END
+END
+
+ static void DecodeCHMOV(Word Index)
+BEGIN
+ String Token;
+ char *Adr = Nil;
+ LongWord Phase;
+ Boolean OK;
+
+ if ((MomCPU != CPU53C825) AND (MomCPU != CPU53C875) AND (MomCPU != CPU53C895)) WrError(1500);
+ else if ((ArgCnt<2) OR (ArgCnt>3)) WrError(1110);
+ else
+ BEGIN
+ GetToken(ArgStr[ArgCnt], Token);
+ if (strcasecmp(Token, "WITH") == 0) DAsmCode[0] = 0x08000000;
+ else if (strcasecmp(Token, "WHEN") == 0) DAsmCode[0] = 0x00000000;
+ else
+ BEGIN
+ WrXError(1350, Token); return;
+ END
+ KillBlanks(ArgStr[ArgCnt]);
+ if (NOT DecodePhase(ArgStr[ArgCnt], &Phase)) WrXError(1350, ArgStr[ArgCnt]);
+ else
+ BEGIN
+ DAsmCode[0] |= Phase << 24;
+ OK = False;
+ if (ArgCnt == 2)
+ BEGIN
+ GetToken(ArgStr[1], Token);
+ if (strcasecmp(Token, "FROM") != 0) WrError(1350);
+ else
+ BEGIN
+ Adr = ArgStr[1];
+ DAsmCode[0] |= 0x10000000;
+ OK = True;
+ END
+ END
+ else
+ BEGIN
+ Phase = EvalIntExpression(ArgStr[1], UInt24, &OK);
+ if (OK)
+ BEGIN
+ DAsmCode[0] |= Phase;
+ if (strncasecmp(ArgStr[2],"PTR", 3) == 0)
+ BEGIN
+ strcpy(ArgStr[2], ArgStr[2] + 4);
+ DAsmCode[0] |= 0x20000000;
+ END
+ Adr = ArgStr[2];
+ END
+ END
+ if (OK)
+ BEGIN
+ KillPrefBlanks(Adr);
+ DAsmCode[1] = EvalIntExpression(Adr, UInt32, &OK);
+ if (OK) CodeLen = 8;
+ END
+ END
+ END
+END
+
+ static void DecodeFlags(Word Index)
+BEGIN
+ Boolean OK;
+ String Token;
+
+ if (ArgCnt != 1) WrError(1110);
+ else
+ BEGIN
+ OK = True;
+ DAsmCode[0] = ((LongWord) Index) << 24;
+ DAsmCode[1] = 0;
+ while ((OK) AND (*ArgStr[1] != '\0'))
+ BEGIN
+ GetToken(ArgStr[1], Token);
+ if (strcasecmp(Token, "ACK") == 0) DAsmCode[0] |= 0x00000040;
+ else if (strcasecmp(Token, "ATN") == 0) DAsmCode[0] |= 0x00000008;
+ else if (strcasecmp(Token, "TARGET") == 0) DAsmCode[0] |= 0x00000200;
+ else if (strcasecmp(Token, "CARRY") == 0) DAsmCode[0] |= 0x00000400;
+ else
+ BEGIN
+ OK = False; WrXError(1350, Token);
+ END
+ if ((OK) AND (*ArgStr[1] != '\0'))
+ BEGIN
+ GetToken(ArgStr[1], Token);
+ if (strcasecmp(Token, "AND") != 0)
+ BEGIN
+ OK = False; WrXError(1350, Token);
+ END
+ END
+ END
+ if (OK) CodeLen = 8;
+ END
+END
+
+ static void DecodeRegTrans(Word Index)
+BEGIN
+ LongWord Reg, Cnt;
+ Boolean OK;
+
+ if (ArgCnt != 3) WrError(1110);
+ else if (MomCPU == CPU53C815) WrError(1500);
+ else if (NOT DecodeReg(ArgStr[1], &Reg)) WrXError(1445, ArgStr[1]);
+ else
+ BEGIN
+ FirstPassUnknown = False;
+ Cnt = EvalIntExpression(ArgStr[2], UInt3, &OK);
+ if (FirstPassUnknown) Cnt = 1;
+ if ((OK) AND (ChkRange(Cnt, 1, 4)))
+ BEGIN
+ DAsmCode[0] = 0xe0000000 + (((LongInt) Index) << 24) + (Reg << 16) + Cnt;
+ if ((strncasecmp(ArgStr[3], "DSAREL(", 7) == 0)
+ AND (ArgStr[3][strlen(ArgStr[3]) - 1] == ')'))
+ BEGIN
+ DAsmCode[0] |= 0x10000000;
+ DAsmCode[1] = EvalIntExpression(ArgStr[3] + 6, SInt24, &OK) & 0xffffff;
+ END
+ else DAsmCode[1] = EvalIntExpression(ArgStr[3], UInt32, &OK);
+ if (OK) CodeLen = 8;
+ END
+ END
+END
+
+ static void DecodeMOVE(Word Index)
+BEGIN
+ Boolean WithCarry, BigCPU;
+ String Token;
+ LongWord Tmp, DReg , AriOp = 0xff, ImmVal = 0x100;
+ String Parts[8];
+ Boolean OK;
+
+ BigCPU = (MomCPU == CPU53C825) OR (MomCPU == CPU53C875) OR (MomCPU == CPU53C895);
+
+ if ((ArgCnt > 3) OR (ArgCnt < 1)) WrError(1110);
+ else if (ArgCnt == 1) /* MOVE Register */
+ BEGIN
+ ArgCnt = 0;
+ do
+ BEGIN
+ GetToken(ArgStr[1], Parts[ArgCnt++]);
+ END
+ while ((*ArgStr[1] != '\0') AND (ArgCnt < 8));
+ if ((ArgCnt > 1) AND (strcasecmp(Parts[ArgCnt - 1], "CARRY") == 0) AND (strcasecmp(Parts[ArgCnt - 1], "TO") == 0))
+ BEGIN
+ WithCarry = True; ArgCnt -= 2;
+ END
+ else WithCarry = False;
+ DAsmCode[0] = 0x40000000;
+ DAsmCode[1] = 0;
+ if (ArgCnt == 3)
+ BEGIN
+ if (WithCarry) WrError(1350);
+ else if (strcasecmp(Parts[1], "TO") == 0) /* MOVE */
+ BEGIN
+ switch (DecodeComp(Parts[0], &ImmVal))
+ BEGIN
+ case SFBR:
+ switch (DecodeComp(Parts[2], &ImmVal))
+ BEGIN
+ case SFBR:
+ ImmVal = 8;
+ case REGISTER: /* --> 0x00 OR SFBR to reg */
+ DAsmCode[0] += 0x2a000000 + (ImmVal << 16);
+ CodeLen = 8;
+ break;
+ default:
+ WrError(1350);
+ END
+ break;
+ case REGISTER:
+ DReg = ImmVal;
+ switch (DecodeComp(Parts[2], &ImmVal))
+ BEGIN
+ case SFBR: /* --> 0x00 OR reg to SFBR */
+ DAsmCode[0] += 0x32000000 + (DReg << 16);
+ CodeLen = 8;
+ break;
+ case REGISTER:
+ if (ImmVal != DReg) WrError(1350);
+ else
+ BEGIN
+ DAsmCode[0] += 0x3a000000 + (DReg << 16);
+ CodeLen = 8;
+ END
+ break;
+ default:
+ WrError(1350);
+ END
+ break;
+ case IMM8:
+ switch (DecodeComp(Parts[2], &DReg))
+ BEGIN
+ case SFBR:
+ DReg = 8;
+ case REGISTER: /* --> imm to reg */
+ DAsmCode[0] += 0x38000000 + (DReg << 16) + (ImmVal << 8);
+ CodeLen = 8;
+ break;
+ default:
+ WrError(1350);
+ END
+ break;
+ default:
+ WrError(1350);
+ break;
+ END
+ END /* ... TO ... */
+ else if ((strcasecmp(Parts[1], "SHL") == 0) OR (strcasecmp(Parts[1], "SHR") == 0))
+ BEGIN
+ AriOp = 1 + (Ord(toupper(Parts[1][2]) == 'R') << 2);
+ switch (DecodeComp(Parts[0], &DReg))
+ BEGIN
+ case SFBR:
+ switch (DecodeComp(Parts[2], &DReg))
+ BEGIN
+ case SFBR:
+ DReg = 8;
+ case REGISTER:
+ DAsmCode[0] += 0x28000000 + (AriOp << 24) + (DReg << 16);
+ CodeLen = 8;
+ break;
+ default:
+ WrError(1350);
+ END
+ break;
+ case REGISTER:
+ ImmVal = DReg;
+ switch (DecodeComp(Parts[2], &DReg))
+ BEGIN
+ case SFBR:
+ DAsmCode[0] += 0x30000000 + (AriOp << 24) + (ImmVal << 16);
+ CodeLen = 8;
+ break;
+ case REGISTER:
+ if (DReg != ImmVal) WrError(1350);
+ else
+ BEGIN
+ DAsmCode[0] += 0x38000000 + (AriOp << 24) + (ImmVal << 16);
+ CodeLen = 8;
+ END
+ break;
+ default:
+ WrError(1350);
+ END
+ break;
+ default:
+ WrError(1350);
+ END
+ END /* ... SHx ... */
+ END /* ArgCnt == 3 */
+ else if (ArgCnt == 5)
+ BEGIN
+ if (strcasecmp(Parts[3], "TO") != 0) WrError(1350);
+ else
+ BEGIN
+ if (strcasecmp(Parts[1], "XOR") == 0) AriOp = 3;
+ else if (strcasecmp(Parts[1], "OR") == 0) AriOp = 2;
+ else if (strcasecmp(Parts[1], "AND") == 0) AriOp = 4;
+ else if (strcmp(Parts[1], "+") == 0) AriOp = 6;
+ if (WithCarry) AriOp = (AriOp == 6) ? 7 : 0xff;
+ if (AriOp == 0xff) WrError(1350);
+ else
+ BEGIN
+ DAsmCode[0] |= (AriOp << 24);
+ switch (DecodeComp(Parts[0], &ImmVal))
+ BEGIN
+ case SFBR:
+ switch (DecodeComp(Parts[2], &ImmVal))
+ BEGIN
+ case SFBR:
+ switch (DecodeComp(Parts[4], &ImmVal))
+ BEGIN
+ case SFBR:
+ ImmVal = 8;
+ case REGISTER:
+ if (NOT BigCPU) WrError(1500);
+ else
+ BEGIN
+ DAsmCode[0] |= 0x28800000 + (ImmVal << 16);
+ CodeLen = 8;
+ END
+ break;
+ default:
+ WrError(1350);
+ END
+ break;
+ case IMM8:
+ switch (DecodeComp(Parts[4], &DReg))
+ BEGIN
+ case SFBR:
+ DReg = 8;
+ case REGISTER:
+ DAsmCode[0] |= 0x28000000 + (DReg << 16) + (ImmVal << 8);
+ CodeLen = 8;
+ break;
+ default:
+ WrError(1350);
+ END
+ break;
+ default:
+ WrError(1350);
+ END
+ break;
+ case REGISTER:
+ DAsmCode[0] |= ImmVal << 16;
+ DReg = ImmVal;
+ switch (DecodeComp(Parts[2], &ImmVal))
+ BEGIN
+ case SFBR:
+ switch (DecodeComp(Parts[4], &ImmVal))
+ BEGIN
+ case SFBR:
+ if (NOT BigCPU) WrError(1500);
+ else
+ BEGIN
+ DAsmCode[0] |= 0x30800000;
+ CodeLen = 8;
+ END
+ break;
+ case REGISTER:
+ if (DReg != ImmVal) WrError(1350);
+ else if (NOT BigCPU) WrError(1500);
+ else
+ BEGIN
+ DAsmCode[0] |= 0x38800000;
+ CodeLen = 8;
+ END
+ break;
+ default:
+ WrError(1350);
+ END
+ break;
+ case IMM8:
+ DAsmCode[0] |= (ImmVal << 8);
+ switch (DecodeComp(Parts[4], &Tmp))
+ BEGIN
+ case SFBR:
+ DAsmCode[0] |= 0x30000000;
+ CodeLen = 8;
+ break;
+ case REGISTER:
+ if (DReg != Tmp) WrError(1350);
+ else
+ BEGIN
+ DAsmCode[0] |= 0x38000000;
+ CodeLen = 8;
+ END
+ break;
+ default:
+ WrError(1350);
+ END
+ break;
+ default:
+ WrError(1350);
+ END
+ break;
+ default:
+ WrError(1350);
+ END
+ END
+ END
+ END /* ArgCnt == 5 */
+ else WrError(1350);
+ END
+ else if (ArgCnt == 2)
+ BEGIN
+ GetToken(ArgStr[1], Token);
+ if (strcasecmp(Token, "FROM") != 0) WrError(1350);
+ else
+ BEGIN
+ DAsmCode[0] = 0x00000000;
+ DAsmCode[1] = EvalIntExpression(ArgStr[1], Int32, &OK);
+ if (OK)
+ BEGIN
+ GetToken(ArgStr[2], Token);
+ OK = True;
+ if (strcasecmp(Token, "WHEN") == 0) DAsmCode[0] |= 0x08000000;
+ else if (strcasecmp(Token, "WITH") != 0) OK = False;
+ if (NOT OK) WrError(1350);
+ else
+ BEGIN
+ KillBlanks(ArgStr[2]);
+ if (NOT DecodePhase(ArgStr[2], &ImmVal)) WrXError(1350, ArgStr[2]);
+ else
+ BEGIN
+ DAsmCode[0] |= ImmVal << 24;
+ CodeLen = 8;
+ END
+ END
+ END
+ END
+ END
+ else if (ArgCnt == 3)
+ BEGIN
+ if (strncasecmp(ArgStr[1], "MEMORY", 6) == 0)
+ BEGIN
+ strcpy(ArgStr[1], ArgStr[1] + 7);
+ if (strncasecmp(ArgStr[1], "NO FLUSH", 8) == 0)
+ BEGIN
+ DAsmCode[0] = 0xc1000000;
+ strcpy(ArgStr[1], ArgStr[1] + 9);
+ END
+ else DAsmCode[0] = 0xc0000000;
+ DAsmCode[0] |= EvalIntExpression(ArgStr[1], UInt24, &OK);
+ if (OK)
+ BEGIN
+ DAsmCode[1] = EvalIntExpression(ArgStr[2], Int32, &OK);
+ if (OK)
+ BEGIN
+ DAsmCode[2] = EvalIntExpression(ArgStr[3], Int32, &OK);
+ if (OK) CodeLen = 12;
+ END
+ END
+ END
+ else
+ BEGIN
+ DAsmCode[0] = EvalIntExpression(ArgStr[1], UInt24, &OK);
+ if (OK)
+ BEGIN
+ GetToken(ArgStr[3], Token);
+ OK = True;
+ if (strcasecmp(Token, "WHEN") == 0) DAsmCode[0] |= 0x08000000;
+ else if (strcasecmp(Token, "WITH") != 0) OK = False;
+ if (NOT OK) WrError(1350);
+ else
+ BEGIN
+ KillBlanks(ArgStr[3]);
+ if (NOT DecodePhase(ArgStr[3], &ImmVal)) WrXError(1350, ArgStr[2]);
+ else
+ BEGIN
+ DAsmCode[0] |= ImmVal << 24;
+ if (strncasecmp(ArgStr[2], "PTR", 3) == 0)
+ BEGIN
+ strcpy(ArgStr[2], ArgStr[2] + 4);
+ DAsmCode[0] |= 0x20000000;
+ END
+ DAsmCode[1] = EvalIntExpression(ArgStr[2], UInt32, &OK);
+ if (OK) CodeLen = 8;
+ END
+ END
+ END
+ END
+ END
+ else WrError(1110);
+END
+
+ static void DecodeSELECT(Word MayATN)
+BEGIN
+ Boolean OK;
+ LongInt Dist;
+ int l;
+
+ if (ArgCnt != 2) WrError(1110);
+ else
+ BEGIN
+ DAsmCode[0] = 0x40000000; OK = True;
+ if (strncasecmp(ArgStr[1], "ATN ", 4) == 0)
+ BEGIN
+ strcpy(ArgStr[1], ArgStr[1] + 4); KillPrefBlanks(ArgStr[1]);
+ if (NOT MayATN) OK = False;
+ else DAsmCode[0] |= 0x01000000;
+ END
+ if (NOT OK) WrError(1350);
+ else
+ BEGIN
+ if (strncasecmp(ArgStr[1], "FROM ", 5) == 0)
+ BEGIN
+ strcpy(ArgStr[1], ArgStr[1] + 5); KillPrefBlanks(ArgStr[1]);
+ DAsmCode[0] |= 0x02000000 + EvalIntExpression(ArgStr[1], UInt24, &OK);
+ END
+ else DAsmCode[0] |= EvalIntExpression(ArgStr[1], UInt4, &OK) << 16;
+ if (OK)
+ BEGIN
+ l = strlen(ArgStr[2]);
+ if ((strncasecmp(ArgStr[2], "REL(", 4) == 0) AND (ArgStr[2][l - 1] == ')'))
+ BEGIN
+ DAsmCode[0] |= 0x04000000; ArgStr[2][l - 1] = '\0';
+ Dist = EvalIntExpression(ArgStr[2] + 4, UInt32, &OK) - (EProgCounter() + 8);
+ if (OK)
+ if ((NOT SymbolQuestionable) AND ((Dist > 0x7fffff) OR (Dist < -0x800000))) WrError(1370);
+ else DAsmCode[1] = Dist & 0xffffff;
+ END
+ else DAsmCode[1] = EvalIntExpression(ArgStr[2], UInt32, &OK);
+ if (OK) CodeLen = 8;
+ END
+ END
+ END
+END
+
+ static void DecodeWAIT(Word Index)
+BEGIN
+ String Token;
+ int l;
+ Boolean OK;
+ LongInt Dist;
+
+ if (ArgCnt != 1) WrError(1110);
+ else
+ BEGIN
+ GetToken(ArgStr[1], Token); KillPrefBlanks(ArgStr[1]);
+ if (strcasecmp(Token, "DISCONNECT") == 0)
+ BEGIN
+ if (*ArgStr[1] != '\0') WrError(1350);
+ else
+ BEGIN
+ DAsmCode[0] = 0x48000000;
+ DAsmCode[1] = 0;
+ CodeLen = 8;
+ END
+ END
+ else if ((strcasecmp(Token, "RESELECT") == 0) OR (strcasecmp(Token, "SELECT") == 0))
+ BEGIN
+ l = strlen(ArgStr[1]);
+ if ((strncasecmp(ArgStr[1], "REL(", 4) == 0) AND (ArgStr[1][l - 1] == ')'))
+ BEGIN
+ ArgStr[1][l - 1] = '\0';
+ DAsmCode[0] = 0x54000000;
+ Dist = EvalIntExpression(ArgStr[1] + 4, UInt32, &OK) - (EProgCounter() + 8);
+ if (OK)
+ if ((NOT SymbolQuestionable) AND ((Dist > 0x7fffff) OR (Dist < -0x800000))) WrError(1370);
+ else DAsmCode[1] = Dist & 0xffffff;
+ END
+ else
+ BEGIN
+ DAsmCode[0] = 0x50000000;
+ DAsmCode[1] = EvalIntExpression(ArgStr[1], UInt32, &OK);
+ END
+ if (OK)
+ BEGIN
+ if (toupper(*Token) == 'S') DAsmCode[0] |= 0x00000200;
+ CodeLen = 8;
+ END
+ END
+ END
+END
+
+/*---------------------------------------------------------------------------*/
+
+static int InstrZ;
+
+ static void AddReg(char *NName, LargeWord Adr, Word Mask)
+BEGIN
+ if (InstrZ >= RegCnt) exit(255);
+ Regs[InstrZ].Name = NName;
+ Regs[InstrZ].Code = Adr;
+ Regs[InstrZ++].Mask = Mask;
+END
+
+ static void InitFields(void)
+BEGIN
+ InstTable = CreateInstTable(51);
+ AddInstTable(InstTable, "NOP" , 0x80, DecodeFixed);
+ AddInstTable(InstTable, "DISCONNECT" , 0x48, DecodeFixed);
+ AddInstTable(InstTable, "JUMP" , 0, DecodeJmps);
+ AddInstTable(InstTable, "CALL" , 1, DecodeJmps);
+ AddInstTable(InstTable, "RETURN" , 2, DecodeJmps);
+ AddInstTable(InstTable, "INT" , 3, DecodeJmps);
+ AddInstTable(InstTable, "INTFLY" , 3, DecodeJmps);
+ AddInstTable(InstTable, "CHMOV" , 0, DecodeCHMOV);
+ AddInstTable(InstTable, "CLEAR" , 0x60, DecodeFlags);
+ AddInstTable(InstTable, "SET" , 0x58, DecodeFlags);
+ AddInstTable(InstTable, "LOAD" , 1, DecodeRegTrans);
+ AddInstTable(InstTable, "STORE" , 0, DecodeRegTrans);
+ AddInstTable(InstTable, "MOVE" , 0, DecodeMOVE);
+ AddInstTable(InstTable, "RESELECT", 0, DecodeSELECT);
+ AddInstTable(InstTable, "SELECT" , 1, DecodeSELECT);
+ AddInstTable(InstTable, "WAIT" , 0, DecodeWAIT);
+
+ Regs = (PReg) malloc(sizeof(TReg) * RegCnt); InstrZ = 0;
+ AddReg("SCNTL0" , 0x00, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SCNTL1" , 0x01, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SCNTL2" , 0x02, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SCNTL3" , 0x03, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SCID" , 0x04, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SXFER" , 0x05, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SDID" , 0x06, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("GPREG" , 0x07, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SFBR" , 0x08, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SOCL" , 0x09, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SSID" , 0x0a, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SBCL" , 0x0b, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("DSTAT" , 0x0c, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SSTAT0" , 0x0d, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SSTAT1" , 0x0e, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SSTAT2" , 0x0f, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("DSA" , 0x10, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("ISTAT" , 0x14, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("CTEST0" , 0x18, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("CTEST1" , 0x19, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("CTEST2" , 0x1a, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("CTEST3" , 0x1b, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("TEMP" , 0x1c, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("DFIFO" , 0x20, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("CTEST4" , 0x21, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("CTEST5" , 0x22, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("CTEST6" , 0x23, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("DBC" , 0x24, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("DCMD" , 0x27, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("DNAD" , 0x28, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("DSP" , 0x2c, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("DSPS" , 0x30, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SCRATCHA" , 0x34, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("DMODE" , 0x38, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("DIEN" , 0x39, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SBR" , 0x3a, M_53C810 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("DWT" , 0x3a, M_53C815 );
+ AddReg("DCNTL" , 0x3b, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("ADDER" , 0x3c, M_53C810 + M_53C825 + M_53C860 + M_53C895);
+ AddReg("SIEN0" , 0x40, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SIEN1" , 0x41, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SIST0" , 0x42, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SIST1" , 0x43, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SLPAR" , 0x44, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SWIDE" , 0x45, M_53C825 + M_53C875 + M_53C895);
+ AddReg("MACNTL" , 0x46, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("GPCNTL" , 0x47, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("STIME0" , 0x48, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("STIME1" , 0x49, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("RESPID" , 0x4a, M_53C810 + M_53C815 + M_53C825 + M_53C860 );
+ AddReg("RESPID0" , 0x4a, M_53C875 + M_53C895);
+ AddReg("RESPID1" , 0x4b, M_53C875 + M_53C895);
+ AddReg("STEST0" , 0x4c, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("STEST1" , 0x4d, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("STEST2" , 0x4e, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("STEST3" , 0x4f, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SIDL" , 0x50, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("STEST4" , 0x52, + M_53C895);
+ AddReg("SODL" , 0x54, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SBDL" , 0x58, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SCRATCHB" , 0x5c, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
+ AddReg("SCRATCHC" , 0x60, M_53C875 + M_53C895);
+ AddReg("SCRATCHD" , 0x64, M_53C875 + M_53C895);
+ AddReg("SCRATCHE" , 0x68, M_53C875 + M_53C895);
+ AddReg("SCRATCHF" , 0x6c, M_53C875 + M_53C895);
+ AddReg("SCRATCHG" , 0x70, M_53C875 + M_53C895);
+ AddReg("SCRATCHH" , 0x74, M_53C875 + M_53C895);
+ AddReg("SCRATCHI" , 0x78, M_53C875 + M_53C895);
+ AddReg("SCRATCHJ" , 0x7c, M_53C875 + M_53C895);
+END
+
+ static void DeinitFields(void)
+BEGIN
+ DestroyInstTable(InstTable);
+ free(Regs);
+END
+
+/*---------------------------------------------------------------------------*/
+
+ static void MakeCode_53c8xx(void)
+BEGIN
+ CodeLen=0; DontPrint=False;
+
+ /* zu ignorierendes */
+
+ if (Memo("")) return;
+
+ if (NOT LookupInstTable(InstTable,OpPart)) WrXError(1200, OpPart);
+END
+
+ static Boolean IsDef_53c8xx(void)
+BEGIN
+ return False;
+END
+
+ static void SwitchFrom_53c8xx(void)
+BEGIN
+ DeinitFields();
+END
+
+ static void SwitchTo_53c8xx(void)
+BEGIN
+ PFamilyDescr FoundDescr;
+
+ FoundDescr=FindFamilyByName("SYM53C8xx");
+
+ TurnWords=False; ConstMode=ConstModeC; SetIsOccupied=True;
+ PCSymbol="$"; HeaderID=FoundDescr->Id; NOPCode=0;
+ DivideChars=","; HasAttrs=False;
+
+ ValidSegs=(1<<SegCode);
+ Grans[SegCode ]=1; ListGrans[SegCode ]=4; SegInits[SegCode ]=0;
+#ifdef __STDC__
+ SegLimits[SegCode] = 0xfffffffful;
+#else
+ SegLimits[SegCode] = 0xffffffffl;
+#endif
+
+ MakeCode=MakeCode_53c8xx; IsDef=IsDef_53c8xx;
+ SwitchFrom=SwitchFrom_53c8xx;
+
+ InitFields();
+END
+
+/*---------------------------------------------------------------------------*/
+
+ void code53c8xx_init(void)
+BEGIN
+ CPU53C810 = AddCPU("SYM53C810", SwitchTo_53c8xx);
+ CPU53C860 = AddCPU("SYM53C860", SwitchTo_53c8xx);
+ CPU53C815 = AddCPU("SYM53C815", SwitchTo_53c8xx);
+ CPU53C825 = AddCPU("SYM53C825", SwitchTo_53c8xx);
+ CPU53C875 = AddCPU("SYM53C875", SwitchTo_53c8xx);
+ CPU53C895 = AddCPU("SYM53C895", SwitchTo_53c8xx);
+END