Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. /* code53c8xx.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* Makroassembler AS                                                         */
  6. /*                                                                           */
  7. /* Codegenerator SYM53C8xx                                                   */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "asmdef.h"
  16. #include "asmsub.h"
  17. #include "asmpars.h"
  18. #include "asmitree.h"
  19. #include "headids.h"
  20. #include "strutil.h"
  21. #include "codevars.h"
  22. #include "intpseudo.h"
  23. #include "errmsg.h"
  24.  
  25. #include "code53c8xx.h"
  26.  
  27. /*---------------------------------------------------------------------------*/
  28.  
  29. typedef struct
  30. {
  31.   const char *Name;
  32.   LongWord Code;
  33.   Word Mask;
  34. } TReg, *PReg;
  35.  
  36. static CPUVar CPU53C810, CPU53C860, CPU53C815, CPU53C825, CPU53C875,
  37.               CPU53C895;
  38.  
  39. #define M_53C810 0x0001
  40. #define M_53C860 0x0002
  41. #define M_53C815 0x0004
  42. #define M_53C825 0x0008
  43. #define M_53C875 0x0010
  44. #define M_53C895 0x0020
  45.  
  46. static PReg Regs;
  47.  
  48. /*---------------------------------------------------------------------------*/
  49.  
  50. static Boolean IsInToken(char Inp)
  51. {
  52.   return ((Inp == '_') || (isalnum(((usint) Inp) & 0xff)));
  53. }
  54.  
  55. static void GetToken(tStrComp *pSrc, tStrComp *pDest)
  56. {
  57.   char *p;
  58.  
  59.   /* search token start, by skipping spaces */
  60.  
  61.   for (p = pSrc->str.p_str; as_isspace(*p); p++)
  62.     if (*p == '\0') break;
  63.   StrCompCutLeft(pSrc, p - pSrc->str.p_str);
  64.   if (*p == '\0')
  65.   {
  66.     StrCompReset(pDest);
  67.     return;
  68.   }
  69.   pDest->Pos.StartCol = pSrc->Pos.StartCol;
  70.  
  71.   /* geklammerter Ausdruck ? */
  72.  
  73.   if (*pSrc->str.p_str == '(')
  74.   {
  75.     p = QuotPos(pSrc->str.p_str, ')');
  76.  
  77.     /* no closing ) -> copy all up to end */
  78.  
  79.     if (!p)
  80.     {
  81.       StrCompCopy(pDest, pSrc);
  82.       StrCompCutLeft(pSrc, strlen(pSrc->str.p_str));
  83.     }
  84.  
  85.     /* otherwise, copy (...) */
  86.  
  87.     else
  88.     {
  89.       pDest->Pos.Len = strmemcpy(pDest->str.p_str, STRINGSIZE, pSrc->str.p_str, p + 1 - pSrc->str.p_str);
  90.       StrCompCutLeft(pSrc, p + 1 - pSrc->str.p_str);
  91.     }
  92.   }
  93.  
  94.   /* Spezialtoken ? */
  95.  
  96.   else if (!IsInToken(*pSrc->str.p_str))
  97.   {
  98.     pDest->str.p_str[0] = *pSrc->str.p_str;
  99.     pDest->str.p_str[1] = '\0';
  100.     pDest->Pos.Len = 1;
  101.     StrCompCutLeft(pSrc, 1);
  102.   }
  103.  
  104.   /* Wort ? */
  105.  
  106.   else
  107.   {
  108.     for (; IsInToken(*p); p++)
  109.       if (*p == '\0')
  110.         break;
  111.     pDest->Pos.Len = strmemcpy(pDest->str.p_str, STRINGSIZE, pSrc->str.p_str, p - pSrc->str.p_str);
  112.     StrCompCutLeft(pSrc, p - pSrc->str.p_str);
  113.   }
  114. }
  115.  
  116.  
  117. static Boolean DecodePhase(char *Name, LongWord *Result)
  118. {
  119.   *Result = 8;
  120.   if (!as_strcasecmp(Name, "DATA_OUT")) *Result = 0;
  121.   else if (!as_strcasecmp(Name, "DATA_IN")) *Result = 1;
  122.   else if (!as_strcasecmp(Name, "CMD")) *Result = 2;
  123.   else if (!as_strcasecmp(Name, "COMMAND")) *Result = 2;
  124.   else if (!as_strcasecmp(Name, "STATUS")) *Result = 3;
  125.   else if (!as_strcasecmp(Name, "RES4")) *Result = 4;
  126.   else if (!as_strcasecmp(Name, "RES5")) *Result = 5;
  127.   else if (!as_strcasecmp(Name, "MSG_OUT")) *Result = 6;
  128.   else if (!as_strcasecmp(Name, "MSG_IN")) *Result = 7;
  129.   else if (!as_strcasecmp(Name, "MESSAGE_OUT")) *Result = 6;
  130.   else if (!as_strcasecmp(Name, "MESSAGE_IN")) *Result = 7;
  131.   return (*Result < 8);
  132. }
  133.  
  134. static Boolean DecodeReg(char *Name, LongWord *Result)
  135. {
  136.   Integer Mask = 1 << (MomCPU - CPU53C810);
  137.   PReg Reg;
  138.  
  139.   for (Reg = Regs; Reg->Name; Reg++)
  140.     if (!(as_strcasecmp(Reg->Name, Name)) && (Mask & Reg->Mask))
  141.     {
  142.       *Result = Reg->Code;
  143.       return True;
  144.     }
  145.  
  146.   return False;
  147. }
  148.  
  149. static Boolean Err(tErrorNum Num, const char *Msg)
  150. {
  151.   WrXError(Num, Msg);
  152.   return False;
  153. }
  154.  
  155. static Boolean DecodeCond(tStrComp *pSrc, LongWord *Dest)
  156. {
  157.   String TokStr;
  158.   tStrComp Tok;
  159.   Boolean PhaseATNUsed, DataUsed, CarryUsed, MaskUsed;
  160.   LongWord Tmp;
  161.   Boolean OK;
  162.  
  163.   /* IF/WHEN/Nix-Unterscheidung - TRUE fuer Nix setzen */
  164.  
  165.   StrCompMkTemp(&Tok, TokStr, sizeof(TokStr));
  166.   GetToken(pSrc, &Tok);
  167.   if (*Tok.str.p_str == '\0')
  168.   {
  169.     *Dest |= 0x00080000;
  170.     return True;
  171.   }
  172.  
  173.   if (as_strcasecmp(Tok.str.p_str, "WHEN") == 0)
  174.     *Dest |= 0x00010000;
  175.   else if (as_strcasecmp(Tok.str.p_str, "IF") != 0)
  176.     return Err(ErrNum_OpTypeMismatch, Tok.str.p_str);
  177.  
  178.   /* Negierung? */
  179.  
  180.   GetToken(pSrc, &Tok);
  181.   if (as_strcasecmp(Tok.str.p_str, "NOT") == 0)
  182.     GetToken(pSrc, &Tok);
  183.   else
  184.     *Dest |= 0x00080000;
  185.  
  186.   /* Bedingungen durchgehen */
  187.  
  188.   PhaseATNUsed = DataUsed = MaskUsed = CarryUsed = False;
  189.   do
  190.   {
  191.     if (!as_strcasecmp(Tok.str.p_str, "ATN"))
  192.     {
  193.       if (PhaseATNUsed)
  194.         return Err(ErrNum_InvAddrMode, "2 x ATN/Phase");
  195.       if (CarryUsed)
  196.         return Err(ErrNum_InvAddrMode, "Carry + ATN/Phase");
  197.       if ((*Dest & 0x00010000) != 0)
  198.         return Err(ErrNum_InvAddrMode, "WHEN + ATN");
  199.       PhaseATNUsed = True;
  200.       *Dest |= 0x00020000;
  201.     }
  202.     else if (DecodePhase(Tok.str.p_str, &Tmp))
  203.     {
  204.       if (PhaseATNUsed)
  205.         return Err(ErrNum_InvAddrMode, "2 x ATN/Phase");
  206.       if (CarryUsed)
  207.         return Err(ErrNum_InvAddrMode, "Carry + ATN/Phase");
  208.       PhaseATNUsed = True;
  209.       *Dest |= 0x00020000 + (Tmp << 24);
  210.     }
  211.     else if (!as_strcasecmp(Tok.str.p_str, "CARRY"))
  212.     {
  213.       if (CarryUsed)
  214.         return Err(ErrNum_InvAddrMode, "2 x Carry");
  215.       if ((PhaseATNUsed) || (DataUsed))
  216.         return Err(ErrNum_InvAddrMode, "Carry + ...");
  217.       CarryUsed = True;
  218.       *Dest |= 0x00200000;
  219.     }
  220.     else if (!as_strcasecmp(Tok.str.p_str, "MASK"))
  221.     {
  222.       if (CarryUsed)
  223.         return Err(ErrNum_InvAddrMode, "Carry + Data");
  224.       if (MaskUsed)
  225.         return Err(ErrNum_InvAddrMode, "2 x Mask");
  226.       if (!DataUsed)
  227.         return Err(ErrNum_InvAddrMode, "Mask + !Data");
  228.       GetToken(pSrc, &Tok);
  229.       Tmp = EvalStrIntExpression(&Tok, UInt8, &OK);
  230.       if (!OK)
  231.         return False;
  232.       MaskUsed = True;
  233.       *Dest |= (Tmp << 8);
  234.     }
  235.     else
  236.     {
  237.       if (CarryUsed)
  238.         return Err(ErrNum_InvAddrMode, "Carry + Data");
  239.       if (DataUsed)
  240.         return Err(ErrNum_InvAddrMode, "2 x Data");
  241.       Tmp = EvalStrIntExpression(&Tok, UInt8, &OK);
  242.       if (!OK)
  243.         return False;
  244.       DataUsed = True;
  245.       *Dest |= 0x00040000 + Tmp;
  246.     }
  247.     GetToken(pSrc, &Tok);
  248.     if (*Tok.str.p_str != '\0')
  249.     {
  250.       if (as_strcasecmp(Tok.str.p_str, "AND"))
  251.         return Err(ErrNum_InvAddrMode, Tok.str.p_str);
  252.       GetToken(pSrc, &Tok);
  253.     }
  254.   }
  255.   while (*Tok.str.p_str != '\0');
  256.  
  257.   return True;
  258. }
  259.  
  260. typedef enum
  261. {
  262.   NONE, SFBR, REGISTER, IMM8
  263. } CompType;
  264.  
  265. static CompType DecodeComp(const tStrComp *pInp, LongWord *Outp)
  266. {
  267.   Boolean OK;
  268.  
  269.   if (!as_strcasecmp(pInp->str.p_str, "SFBR"))
  270.     return SFBR;
  271.   else if (DecodeReg(pInp->str.p_str, Outp))
  272.     return REGISTER;
  273.   else
  274.   {
  275.     *Outp = EvalStrIntExpression(pInp, Int8, &OK) & 0xff;
  276.     return (OK) ?  IMM8 : NONE;
  277.   }
  278. }
  279.  
  280. /*---------------------------------------------------------------------------*/
  281.  
  282. static void DecodeFixed(Word Index)
  283. {
  284.   if (ChkArgCnt(0, 0))
  285.   {
  286.     DAsmCode[0] = ((LongWord) Index) << 24;
  287.     DAsmCode[1] = 0x00000000;
  288.     CodeLen = 8;
  289.   }
  290. }
  291.  
  292. static void DecodeJmps(Word Index)
  293. {
  294.   LongWord Buf;
  295.   LongInt Adr;
  296.   int l;
  297.   Boolean OK;
  298.   tSymbolFlags Flags;
  299.  
  300.   if (ArgCnt == 0)
  301.   {
  302.     if (Memo("INTFLY"))
  303.     {
  304.       ArgCnt = 1;
  305.       strcpy(ArgStr[1].str.p_str, "0");
  306.     }
  307.     else if (Memo("RETURN"))
  308.     {
  309.       ArgCnt = 1;
  310.       *ArgStr[1].str.p_str = '\0';
  311.     }
  312.   }
  313.   if (ChkArgCnt(1, 2))
  314.   {
  315.     if (ArgCnt == 1)
  316.     {
  317.       if (Memo("RETURN"))
  318.         StrCompCopy(&ArgStr[2], &ArgStr[1]);
  319.       else
  320.         StrCompReset(&ArgStr[2]);
  321.     }
  322.     Buf = 0;
  323.     if (Memo("RETURN"))
  324.     {
  325.       Adr = 0;
  326.       OK = True;
  327.     }
  328.     else
  329.     {
  330.       l = strlen(ArgStr[1].str.p_str);
  331.       if ((!as_strncasecmp(ArgStr[1].str.p_str, "REL(", 4)) && (ArgStr[1].str.p_str[l - 1] == ')'))
  332.       {
  333.         if (*OpPart.str.p_str == 'I')
  334.         {
  335.           WrError(ErrNum_InvAddrMode);
  336.           OK = False;
  337.         }
  338.         Buf |= 0x00800000;
  339.         strmov(ArgStr[1].str.p_str, ArgStr[1].str.p_str + 4);
  340.         ArgStr[1].str.p_str[l - 5] = '\0';
  341.       }
  342.       Adr = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt32, &OK, &Flags);
  343.       if ((OK) && (Buf != 0))
  344.       {
  345.         Adr -= EProgCounter() + 8;
  346.         if (!mSymbolQuestionable(Flags) && ((Adr > 0x7fffff) || (Adr < -0x800000)))
  347.         {
  348.           WrError(ErrNum_JmpDistTooBig);
  349.           OK = False;
  350.         }
  351.       }
  352.     }
  353.     if ((OK) && (DecodeCond(&ArgStr[2], &Buf)))
  354.     {
  355.       DAsmCode[0] = 0x80000000 + (((LongWord) Index) << 27) + Buf;
  356.       if (Memo("INTFLY")) DAsmCode[0] |= 0x00100000;
  357.       DAsmCode[1] = Adr;
  358.       CodeLen = 8;
  359.     }
  360.   }
  361. }
  362.  
  363. static void DecodeCHMOV(Word Index)
  364. {
  365.   String TokenStr;
  366.   tStrComp Token, *pAdrArg = NULL;
  367.   LongWord Phase;
  368.   Boolean OK;
  369.  
  370.   UNUSED(Index);
  371.   StrCompMkTemp(&Token, TokenStr, sizeof(TokenStr));
  372.  
  373.   if ((ChkExactCPUList(ErrNum_InstructionNotSupported, CPU53C825, CPU53C875, CPU53C895, CPUNone) >= 0)
  374.    && ChkArgCnt(2, 3))
  375.   {
  376.     GetToken(&ArgStr[ArgCnt], &Token);
  377.     if (!as_strcasecmp(Token.str.p_str, "WITH"))
  378.       DAsmCode[0] = 0x08000000;
  379.     else if (!as_strcasecmp(Token.str.p_str, "WHEN"))
  380.       DAsmCode[0] = 0x00000000;
  381.     else
  382.     {
  383.       WrStrErrorPos(ErrNum_InvAddrMode, &Token);
  384.       return;
  385.     }
  386.     KillPrefBlanksStrComp(&ArgStr[ArgCnt]);
  387.     KillPostBlanksStrComp(&ArgStr[ArgCnt]);
  388.     if (!DecodePhase(ArgStr[ArgCnt].str.p_str, &Phase)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[ArgCnt]);
  389.     else
  390.     {
  391.       DAsmCode[0] |= Phase << 24;
  392.       OK = False;
  393.       if (ArgCnt == 2)
  394.       {
  395.         GetToken(&ArgStr[1], &Token);
  396.         if (as_strcasecmp(Token.str.p_str, "FROM")) WrError(ErrNum_InvAddrMode);
  397.         else
  398.         {
  399.           pAdrArg = &ArgStr[1];
  400.           DAsmCode[0] |= 0x10000000;
  401.           OK = True;
  402.         }
  403.       }
  404.       else
  405.       {
  406.         Phase = EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
  407.         if (OK)
  408.         {
  409.           DAsmCode[0] |= Phase;
  410.           if (!as_strncasecmp(ArgStr[2].str.p_str,"PTR", 3))
  411.           {
  412.             StrCompCutLeft(&ArgStr[2], 4);
  413.             DAsmCode[0] |= 0x20000000;
  414.           }
  415.           pAdrArg = &ArgStr[2];
  416.         }
  417.       }
  418.       if (OK)
  419.       {
  420.         KillPrefBlanksStrComp(pAdrArg);
  421.         DAsmCode[1] = EvalStrIntExpression(pAdrArg, UInt32, &OK);
  422.         if (OK)
  423.           CodeLen = 8;
  424.       }
  425.     }
  426.   }
  427. }
  428.  
  429. static Boolean TrueFnc(void)
  430. {
  431.   return True;
  432. }
  433.  
  434. static void DecodeFlags(Word Index)
  435. {
  436.   Boolean OK;
  437.   String TokenStr;
  438.   tStrComp Token;
  439.  
  440.   StrCompMkTemp(&Token, TokenStr, sizeof(TokenStr));
  441.   if (ChkArgCnt(1, 1))
  442.   {
  443.     OK = True;
  444.     DAsmCode[0] = ((LongWord) Index) << 24;
  445.     DAsmCode[1] = 0;
  446.     while ((OK) && (*ArgStr[1].str.p_str != '\0'))
  447.     {
  448.       GetToken(&ArgStr[1], &Token);
  449.       if (!as_strcasecmp(Token.str.p_str, "ACK"))
  450.         DAsmCode[0] |= 0x00000040;
  451.       else if (!as_strcasecmp(Token.str.p_str, "ATN"))
  452.         DAsmCode[0] |= 0x00000008;
  453.       else if (!as_strcasecmp(Token.str.p_str, "TARGET"))
  454.         DAsmCode[0] |= 0x00000200;
  455.       else if (!as_strcasecmp(Token.str.p_str, "CARRY"))
  456.         DAsmCode[0] |= 0x00000400;
  457.       else
  458.       {
  459.         OK = False;
  460.         WrStrErrorPos(ErrNum_InvAddrMode, &Token);
  461.       }
  462.       if (OK && (*ArgStr[1].str.p_str != '\0'))
  463.       {
  464.         GetToken(&ArgStr[1], &Token);
  465.         if (as_strcasecmp(Token.str.p_str, "AND"))
  466.         {
  467.           OK = False;
  468.           WrStrErrorPos(ErrNum_InvAddrMode, &Token);
  469.         }
  470.       }
  471.     }
  472.     if (OK)
  473.       CodeLen = 8;
  474.   }
  475. }
  476.  
  477. static void DecodeRegTrans(Word Index)
  478. {
  479.   LongWord Reg, Cnt;
  480.   Boolean OK;
  481.  
  482.   if (!ChkArgCnt(3, 3));
  483.   else if (!ChkExcludeCPU(CPU53C815));
  484.   else if (!DecodeReg(ArgStr[1].str.p_str, &Reg)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  485.   else
  486.   {
  487.     tSymbolFlags Flags;
  488.  
  489.     Cnt = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt3, &OK, &Flags);
  490.     if (mFirstPassUnknown(Flags))
  491.       Cnt = 1;
  492.     if ((OK) && (ChkRange(Cnt, 1, 4)))
  493.     {
  494.       int l = strlen(ArgStr[3].str.p_str);
  495.       DAsmCode[0] = 0xe0000000 + (((LongInt) Index) << 24) + (Reg << 16) + Cnt;
  496.       if ((!as_strncasecmp(ArgStr[3].str.p_str, "DSAREL(", 7))
  497.        && (ArgStr[3].str.p_str[l - 1] == ')'))
  498.       {
  499.         ArgStr[3].str.p_str[--l] = '\0';
  500.         DAsmCode[0] |= 0x10000000;
  501.         DAsmCode[1] = EvalStrIntExpressionOffs(&ArgStr[3], 6, SInt24, &OK) & 0xffffff;
  502.       }
  503.       else
  504.         DAsmCode[1] = EvalStrIntExpression(&ArgStr[3], UInt32, &OK);
  505.       if (OK)
  506.         CodeLen = 8;
  507.     }
  508.   }
  509. }
  510.  
  511. static void DecodeMOVE(Word Index)
  512. {
  513. #define MAXPARTS 8
  514.   Boolean WithCarry;
  515.   String TokenStr;
  516.   tStrComp Token;
  517.   LongWord Tmp, DReg , AriOp = 0xff, ImmVal = 0x100;
  518.   Boolean OK;
  519.   int z;
  520.   Word BigCPUMask = (1 << (CPU53C825 - CPU53C810))
  521.                   | (1 << (CPU53C875 - CPU53C810))
  522.                   | (1 << (CPU53C895 - CPU53C810));
  523.  
  524.   UNUSED(Index);
  525.   StrCompMkTemp(&Token, TokenStr, sizeof(TokenStr));
  526.  
  527.   if (!ChkArgCnt(1, 3));
  528.   else if (ArgCnt == 1) /* MOVE Register */
  529.   {
  530.     String PartStr[MAXPARTS];
  531.     tStrComp Parts[MAXPARTS];
  532.     int PartCnt = 0;
  533.  
  534.     for (z = 0; z < MAXPARTS; z++)
  535.       StrCompMkTemp(&Parts[z], PartStr[z], sizeof(PartStr[z]));
  536.     do
  537.     {
  538.       GetToken(&ArgStr[1], &Parts[PartCnt++]);
  539.     }
  540.     while ((*ArgStr[1].str.p_str != '\0') && (PartCnt < MAXPARTS));
  541.     if ((PartCnt > 1) && (!as_strcasecmp(Parts[PartCnt - 1].str.p_str, "CARRY")) && (!as_strcasecmp(Parts[PartCnt - 1].str.p_str, "TO")))
  542.     {
  543.       WithCarry = True;
  544.       PartCnt -= 2;
  545.     }
  546.     else
  547.       WithCarry = False;
  548.     DAsmCode[0] = 0x40000000;
  549.     DAsmCode[1] = 0;
  550.     if (PartCnt == 3)
  551.     {
  552.       if (WithCarry) WrError(ErrNum_InvAddrMode);
  553.       else if (!as_strcasecmp(Parts[1].str.p_str, "TO")) /* MOVE */
  554.       {
  555.         switch (DecodeComp(&Parts[0], &ImmVal))
  556.         {
  557.           case SFBR:
  558.             switch (DecodeComp(&Parts[2], &ImmVal))
  559.             {
  560.               case SFBR:
  561.                 ImmVal = 8;
  562.                 /* fall-through */
  563.               case REGISTER: /* --> 0x00 OR SFBR to reg */
  564.                 DAsmCode[0] += 0x2a000000 + (ImmVal << 16);
  565.                 CodeLen = 8;
  566.                 break;
  567.               default:
  568.                 WrError(ErrNum_InvAddrMode);
  569.             }
  570.             break;
  571.           case REGISTER:
  572.             DReg = ImmVal;
  573.             switch (DecodeComp(&Parts[2], &ImmVal))
  574.             {
  575.               case SFBR: /* --> 0x00 OR reg to SFBR */
  576.                 DAsmCode[0] += 0x32000000 + (DReg << 16);
  577.                 CodeLen = 8;
  578.                 break;
  579.               case REGISTER:
  580.                 if (ImmVal != DReg) WrError(ErrNum_InvAddrMode);
  581.                 else
  582.                 {
  583.                   DAsmCode[0] += 0x3a000000 + (DReg << 16);
  584.                   CodeLen = 8;
  585.                 }
  586.                 break;
  587.               default:
  588.                 WrError(ErrNum_InvAddrMode);
  589.             }
  590.             break;
  591.           case IMM8:
  592.             switch (DecodeComp(&Parts[2], &DReg))
  593.             {
  594.               case SFBR:
  595.                 DReg = 8;
  596.                 /* fall-through */
  597.               case REGISTER: /* --> imm to reg */
  598.                 DAsmCode[0] += 0x38000000 + (DReg << 16) + (ImmVal << 8);
  599.                 CodeLen = 8;
  600.                 break;
  601.               default:
  602.                 WrError(ErrNum_InvAddrMode);
  603.             }
  604.             break;
  605.           default:
  606.             WrError(ErrNum_InvAddrMode);
  607.             break;
  608.         }
  609.       } /* ... TO ... */
  610.       else if ((!as_strcasecmp(Parts[1].str.p_str, "SHL")) || (!as_strcasecmp(Parts[1].str.p_str, "SHR")))
  611.       {
  612.         AriOp = 1 + (Ord(as_toupper(Parts[1].str.p_str[2]) == 'R') << 2);
  613.         switch (DecodeComp(&Parts[0], &DReg))
  614.         {
  615.            case SFBR:
  616.              switch (DecodeComp(&Parts[2], &DReg))
  617.              {
  618.                case SFBR:
  619.                  DReg = 8;
  620.                  /* fall-through */
  621.                case REGISTER:
  622.                  DAsmCode[0] += 0x28000000 + (AriOp << 24) + (DReg << 16);
  623.                  CodeLen = 8;
  624.                  break;
  625.                default:
  626.                  WrError(ErrNum_InvAddrMode);
  627.              }
  628.              break;
  629.            case REGISTER:
  630.              ImmVal = DReg;
  631.              switch (DecodeComp(&Parts[2], &DReg))
  632.              {
  633.                case SFBR:
  634.                  DAsmCode[0] += 0x30000000 + (AriOp << 24) + (ImmVal << 16);
  635.                  CodeLen = 8;
  636.                  break;
  637.                case REGISTER:
  638.                  if (DReg != ImmVal) WrError(ErrNum_InvAddrMode);
  639.                  else
  640.                  {
  641.                    DAsmCode[0] += 0x38000000 + (AriOp << 24) + (ImmVal << 16);
  642.                    CodeLen = 8;
  643.                  }
  644.                  break;
  645.                default:
  646.                  WrError(ErrNum_InvAddrMode);
  647.              }
  648.              break;
  649.           default:
  650.             WrError(ErrNum_InvAddrMode);
  651.         }
  652.       } /* ... SHx ... */
  653.     } /* PartCnt == 3 */
  654.     else if (PartCnt == 5)
  655.     {
  656.       if (as_strcasecmp(Parts[3].str.p_str, "TO")) WrError(ErrNum_InvAddrMode);
  657.       else
  658.       {
  659.         if ((!as_strcasecmp(Parts[1].str.p_str, "XOR"))
  660.          || (!as_strcasecmp(Parts[1].str.p_str, "^")))
  661.           AriOp = 3;
  662.         else if ((!as_strcasecmp(Parts[1].str.p_str, "OR"))
  663.               || (!as_strcasecmp(Parts[1].str.p_str, "|")))
  664.           AriOp = 2;
  665.         else if ((!as_strcasecmp(Parts[1].str.p_str, "AND"))
  666.               || (!as_strcasecmp(Parts[1].str.p_str, "&")))
  667.           AriOp = 4;
  668.         else if (!strcmp(Parts[1].str.p_str, "+"))
  669.           AriOp = 6;
  670.         if (WithCarry)
  671.           AriOp = (AriOp == 6) ? 7 : 0xff;
  672.         if (AriOp == 0xff) WrError(ErrNum_InvAddrMode);
  673.         else
  674.         {
  675.           DAsmCode[0] |= (AriOp << 24);
  676.           switch (DecodeComp(&Parts[0], &ImmVal))
  677.           {
  678.             case SFBR:
  679.               switch (DecodeComp(&Parts[2], &ImmVal))
  680.               {
  681.                 case SFBR:
  682.                   switch (DecodeComp(&Parts[4], &ImmVal))
  683.                   {
  684.                     case SFBR:
  685.                       ImmVal = 8;
  686.                       /* fall-through */
  687.                     case REGISTER:
  688.                       if (ChkExactCPUMask(BigCPUMask, CPU53C810) >= 0)
  689.                       {
  690.                         DAsmCode[0] |= 0x28800000 + (ImmVal << 16);
  691.                         CodeLen = 8;
  692.                       }
  693.                       break;
  694.                     default:
  695.                       WrError(ErrNum_InvAddrMode);
  696.                   }
  697.                   break;
  698.                 case IMM8:
  699.                   switch (DecodeComp(&Parts[4], &DReg))
  700.                   {
  701.                     case SFBR:
  702.                       DReg = 8;
  703.                       /* fall-through */
  704.                     case REGISTER:
  705.                       DAsmCode[0] |= 0x28000000 + (DReg << 16) + (ImmVal << 8);
  706.                       CodeLen = 8;
  707.                       break;
  708.                     default:
  709.                       WrError(ErrNum_InvAddrMode);
  710.                   }
  711.                   break;
  712.                 default:
  713.                   WrError(ErrNum_InvAddrMode);
  714.               }
  715.               break;
  716.             case REGISTER:
  717.               DAsmCode[0] |= ImmVal << 16;
  718.               DReg = ImmVal;
  719.               switch (DecodeComp(&Parts[2], &ImmVal))
  720.               {
  721.                 case SFBR:
  722.                   switch (DecodeComp(&Parts[4], &ImmVal))
  723.                   {
  724.                     case SFBR:
  725.                       if (ChkExactCPUMask(BigCPUMask, CPU53C810) >= 0)
  726.                       {
  727.                         DAsmCode[0] |= 0x30800000;
  728.                         CodeLen = 8;
  729.                       }
  730.                       break;
  731.                     case REGISTER:
  732.                       if (DReg != ImmVal) WrError(ErrNum_InvAddrMode);
  733.                       else if (ChkExactCPUMask(BigCPUMask, CPU53C810) >= 0)
  734.                       {
  735.                         DAsmCode[0] |= 0x38800000;
  736.                         CodeLen = 8;
  737.                       }
  738.                       break;
  739.                     default:
  740.                       WrError(ErrNum_InvAddrMode);
  741.                   }
  742.                   break;
  743.                 case IMM8:
  744.                   DAsmCode[0] |= (ImmVal << 8);
  745.                   switch (DecodeComp(&Parts[4], &Tmp))
  746.                   {
  747.                     case SFBR:
  748.                       DAsmCode[0] |= 0x30000000;
  749.                       CodeLen = 8;
  750.                       break;
  751.                     case REGISTER:
  752.                       if (DReg != Tmp) WrError(ErrNum_InvAddrMode);
  753.                       else
  754.                       {
  755.                         DAsmCode[0] |= 0x38000000;
  756.                         CodeLen = 8;
  757.                       }
  758.                       break;
  759.                     default:
  760.                       WrError(ErrNum_InvAddrMode);
  761.                   }
  762.                   break;
  763.                 default:
  764.                   WrError(ErrNum_InvAddrMode);
  765.               }
  766.               break;
  767.             default:
  768.               WrError(ErrNum_InvAddrMode);
  769.           }
  770.         }
  771.       }
  772.     }  /* PartCnt == 5 */
  773.     else
  774.       WrError(ErrNum_InvAddrMode);
  775.   }
  776.   else if (ArgCnt == 2)
  777.   {
  778.     GetToken(&ArgStr[1], &Token);
  779.     if (as_strcasecmp(Token.str.p_str, "FROM")) WrError(ErrNum_InvAddrMode);
  780.     else
  781.     {
  782.       DAsmCode[0] = 0x00000000;
  783.       DAsmCode[1] = EvalStrIntExpression(&ArgStr[1], Int32, &OK);
  784.       if (OK)
  785.       {
  786.         GetToken(&ArgStr[2], &Token);
  787.         OK = True;
  788.         if (!as_strcasecmp(Token.str.p_str, "WHEN"))
  789.           DAsmCode[0] |= 0x08000000;
  790.         else if (as_strcasecmp(Token.str.p_str, "WITH"))
  791.           OK = False;
  792.         if (!OK) WrError(ErrNum_InvAddrMode);
  793.         else
  794.         {
  795.           KillPrefBlanksStrComp(&ArgStr[2]);
  796.           KillPostBlanksStrComp(&ArgStr[2]);
  797.           if (!DecodePhase(ArgStr[2].str.p_str, &ImmVal)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  798.           else
  799.           {
  800.             DAsmCode[0] |= ImmVal << 24;
  801.             CodeLen = 8;
  802.           }
  803.         }
  804.       }
  805.     }
  806.   }
  807.   else if (ArgCnt == 3)
  808.   {
  809.     if (!as_strncasecmp(ArgStr[1].str.p_str, "MEMORY", 6))
  810.     {
  811.       StrCompCutLeft(&ArgStr[1], 7);
  812.       if (!as_strncasecmp(ArgStr[1].str.p_str, "NO FLUSH", 8))
  813.       {
  814.         DAsmCode[0] = 0xc1000000;
  815.         StrCompCutLeft(&ArgStr[1], 9);
  816.       }
  817.       else DAsmCode[0] = 0xc0000000;
  818.       DAsmCode[0] |= EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
  819.       if (OK)
  820.       {
  821.         DAsmCode[1] = EvalStrIntExpression(&ArgStr[2], Int32, &OK);
  822.         if (OK)
  823.         {
  824.           DAsmCode[2] = EvalStrIntExpression(&ArgStr[3], Int32, &OK);
  825.           if (OK) CodeLen = 12;
  826.         }
  827.       }
  828.     }
  829.     else
  830.     {
  831.       DAsmCode[0] = EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
  832.       if (OK)
  833.       {
  834.         GetToken(&ArgStr[3], &Token);
  835.         OK = True;
  836.         if (!as_strcasecmp(Token.str.p_str, "WHEN")) DAsmCode[0] |= 0x08000000;
  837.         else if (as_strcasecmp(Token.str.p_str, "WITH")) OK = False;
  838.         if (!OK) WrError(ErrNum_InvAddrMode);
  839.         else
  840.         {
  841.           KillPrefBlanksStrComp(&ArgStr[3]);
  842.           KillPostBlanksStrComp(&ArgStr[3]);
  843.           if (!DecodePhase(ArgStr[3].str.p_str, &ImmVal)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[3]);
  844.           else
  845.           {
  846.             DAsmCode[0] |= ImmVal << 24;
  847.             if (!as_strncasecmp(ArgStr[2].str.p_str, "PTR", 3))
  848.             {
  849.               StrCompCutLeft(&ArgStr[2], 4);
  850.               DAsmCode[0] |= 0x20000000;
  851.             }
  852.             DAsmCode[1] = EvalStrIntExpression(&ArgStr[2], UInt32, &OK);
  853.             if (OK) CodeLen = 8;
  854.           }
  855.         }
  856.       }
  857.     }
  858.   }
  859. }
  860.  
  861. static void DecodeSELECT(Word MayATN)
  862. {
  863.   Boolean OK;
  864.   LongInt Dist;
  865.   tSymbolFlags Flags;
  866.   int l;
  867.  
  868.   if (ChkArgCnt(2, 2))
  869.   {
  870.     DAsmCode[0] = 0x40000000;
  871.     OK = True;
  872.     if (!as_strncasecmp(ArgStr[1].str.p_str, "ATN ", 4))
  873.     {
  874.       strmov(ArgStr[1].str.p_str, ArgStr[1].str.p_str + 4);
  875.       ArgStr[1].Pos.StartCol += 4;
  876.       ArgStr[1].Pos.Len -= 4;
  877.       KillPrefBlanksStrComp(&ArgStr[1]);
  878.       if (!MayATN)
  879.         OK = False;
  880.       else
  881.         DAsmCode[0] |= 0x01000000;
  882.     }
  883.     if (!OK) WrError(ErrNum_InvAddrMode);
  884.     else
  885.     {
  886.       if (!as_strncasecmp(ArgStr[1].str.p_str, "FROM ", 5))
  887.       {
  888.         strmov(ArgStr[1].str.p_str, ArgStr[1].str.p_str + 5);
  889.         ArgStr[1].Pos.StartCol += 5;
  890.         ArgStr[1].Pos.Len -= 5;
  891.         KillPrefBlanksStrComp(&ArgStr[1]);
  892.         DAsmCode[0] |= 0x02000000 + EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
  893.       }
  894.       else
  895.         DAsmCode[0] |= EvalStrIntExpression(&ArgStr[1], UInt4, &OK) << 16;
  896.       if (OK)
  897.       {
  898.         l = strlen(ArgStr[2].str.p_str);
  899.         if ((!as_strncasecmp(ArgStr[2].str.p_str, "REL(", 4)) && (ArgStr[2].str.p_str[l - 1] == ')'))
  900.         {
  901.           DAsmCode[0] |= 0x04000000;
  902.           ArgStr[2].str.p_str[l - 1] = '\0';
  903.           Dist = EvalStrIntExpressionOffsWithFlags(&ArgStr[2], 4, UInt32, &OK, &Flags) - (EProgCounter() + 8);
  904.           if (OK)
  905.           {
  906.             if (!mSymbolQuestionable(Flags) && ((Dist > 0x7fffff) || (Dist < -0x800000))) WrError(ErrNum_JmpDistTooBig);
  907.             else DAsmCode[1] = Dist & 0xffffff;
  908.           }
  909.         }
  910.         else DAsmCode[1] = EvalStrIntExpression(&ArgStr[2], UInt32, &OK);
  911.         if (OK) CodeLen = 8;
  912.       }
  913.     }
  914.   }
  915. }
  916.  
  917. static void DecodeWAIT(Word Index)
  918. {
  919.   String TokenStr;
  920.   tStrComp Token;
  921.   Boolean OK;
  922.   LongInt Dist;
  923.   tSymbolFlags Flags;
  924.  
  925.   UNUSED(Index);
  926.   StrCompMkTemp(&Token, TokenStr, sizeof(TokenStr));
  927.  
  928.   if (ChkArgCnt(1, 1))
  929.   {
  930.     GetToken(&ArgStr[1], &Token);
  931.     KillPrefBlanksStrComp(&ArgStr[1]);
  932.     if (!as_strcasecmp(Token.str.p_str, "DISCONNECT"))
  933.     {
  934.       if (*ArgStr[1].str.p_str != '\0') WrError(ErrNum_InvAddrMode);
  935.       else
  936.       {
  937.         DAsmCode[0] = 0x48000000;
  938.         DAsmCode[1] = 0;
  939.         CodeLen = 8;
  940.       }
  941.     }
  942.     else if ((!as_strcasecmp(Token.str.p_str, "RESELECT")) || (!as_strcasecmp(Token.str.p_str, "SELECT")))
  943.     {
  944.       if ((!as_strncasecmp(ArgStr[1].str.p_str, "REL(", 4)) && (ArgStr[1].str.p_str[strlen(ArgStr[1].str.p_str) - 1] == ')'))
  945.       {
  946.         StrCompShorten(&ArgStr[1], 1);
  947.         DAsmCode[0] = 0x54000000;
  948.         Dist = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], 4, UInt32, &OK, &Flags) - (EProgCounter() + 8);
  949.         if (OK)
  950.         {
  951.           if (mSymbolQuestionable(Flags) && ((Dist > 0x7fffff) || (Dist < -0x800000))) WrError(ErrNum_JmpDistTooBig);
  952.           else
  953.             DAsmCode[1] = Dist & 0xffffff;
  954.         }
  955.       }
  956.       else
  957.       {
  958.         DAsmCode[0] = 0x50000000;
  959.         DAsmCode[1] = EvalStrIntExpression(&ArgStr[1], UInt32, &OK);
  960.       }
  961.       if (OK)
  962.       {
  963.         if (as_toupper(*Token.str.p_str) == 'S')
  964.           DAsmCode[0] |= 0x00000200;
  965.         CodeLen = 8;
  966.       }
  967.     }
  968.   }
  969. }
  970.  
  971. /*---------------------------------------------------------------------------*/
  972.  
  973. static void AddReg(const char *NName, LargeWord Adr, Word Mask)
  974. {
  975.   order_array_rsv_end(Regs, TReg);
  976.   Regs[InstrZ].Name = NName;
  977.   Regs[InstrZ].Code = Adr;
  978.   Regs[InstrZ++].Mask = Mask;
  979. }
  980.  
  981. static void InitFields(void)
  982. {
  983.   InstTable = CreateInstTable(51);
  984.   AddInstTable(InstTable, "NOP"     , 0x80, DecodeFixed);
  985.   AddInstTable(InstTable, "DISCONNECT" , 0x48, DecodeFixed);
  986.   AddInstTable(InstTable, "JUMP"    , 0,    DecodeJmps);
  987.   AddInstTable(InstTable, "CALL"    , 1,    DecodeJmps);
  988.   AddInstTable(InstTable, "RETURN"  , 2,    DecodeJmps);
  989.   AddInstTable(InstTable, "INT"     , 3,    DecodeJmps);
  990.   AddInstTable(InstTable, "INTFLY"  , 3,    DecodeJmps);
  991.   AddInstTable(InstTable, "CHMOV"   , 0,    DecodeCHMOV);
  992.   AddInstTable(InstTable, "CLEAR"   , 0x60, DecodeFlags);
  993.   AddInstTable(InstTable, "SET"     , 0x58, DecodeFlags);
  994.   AddInstTable(InstTable, "LOAD"    , 1,    DecodeRegTrans);
  995.   AddInstTable(InstTable, "STORE"   , 0,    DecodeRegTrans);
  996.   AddInstTable(InstTable, "MOVE"    , 0,    DecodeMOVE);
  997.   AddInstTable(InstTable, "RESELECT", 0,    DecodeSELECT);
  998.   AddInstTable(InstTable, "SELECT"  , 1,    DecodeSELECT);
  999.   AddInstTable(InstTable, "WAIT"    , 0,    DecodeWAIT);
  1000.  
  1001.   InstrZ = 0;
  1002.   AddReg("SCNTL0"   , 0x00, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1003.   AddReg("SCNTL1"   , 0x01, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1004.   AddReg("SCNTL2"   , 0x02, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1005.   AddReg("SCNTL3"   , 0x03, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1006.   AddReg("SCID"     , 0x04, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1007.   AddReg("SXFER"    , 0x05, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1008.   AddReg("SDID"     , 0x06, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1009.   AddReg("GPREG"    , 0x07, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1010.   AddReg("SFBR"     , 0x08, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1011.   AddReg("SOCL"     , 0x09, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1012.   AddReg("SSID"     , 0x0a, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1013.   AddReg("SBCL"     , 0x0b, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1014.   AddReg("DSTAT"    , 0x0c, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1015.   AddReg("SSTAT0"   , 0x0d, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1016.   AddReg("SSTAT1"   , 0x0e, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1017.   AddReg("SSTAT2"   , 0x0f, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1018.   AddReg("DSA"      , 0x10, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1019.   AddReg("ISTAT"    , 0x14, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1020.   AddReg("CTEST0"   , 0x18, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1021.   AddReg("CTEST1"   , 0x19, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1022.   AddReg("CTEST2"   , 0x1a, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1023.   AddReg("CTEST3"   , 0x1b, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1024.   AddReg("TEMP"     , 0x1c, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1025.   AddReg("DFIFO"    , 0x20, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1026.   AddReg("CTEST4"   , 0x21, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1027.   AddReg("CTEST5"   , 0x22, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1028.   AddReg("CTEST6"   , 0x23, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1029.   AddReg("DBC"      , 0x24, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1030.   AddReg("DCMD"     , 0x27, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1031.   AddReg("DNAD"     , 0x28, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1032.   AddReg("DSP"      , 0x2c, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1033.   AddReg("DSPS"     , 0x30, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1034.   AddReg("SCRATCHA" , 0x34, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1035.   AddReg("DMODE"    , 0x38, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1036.   AddReg("DIEN"     , 0x39, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1037.   AddReg("SBR"      , 0x3a, M_53C810                       + M_53C860 + M_53C875 + M_53C895);
  1038.   AddReg("DWT"      , 0x3a,            M_53C815                                            );
  1039.   AddReg("DCNTL"    , 0x3b, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1040.   AddReg("ADDER"    , 0x3c, M_53C810            + M_53C825 + M_53C860            + M_53C895);
  1041.   AddReg("SIEN0"    , 0x40, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1042.   AddReg("SIEN1"    , 0x41, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1043.   AddReg("SIST0"    , 0x42, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1044.   AddReg("SIST1"    , 0x43, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1045.   AddReg("SLPAR"    , 0x44, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1046.   AddReg("SWIDE"    , 0x45,                       M_53C825            + M_53C875 + M_53C895);
  1047.   AddReg("MACNTL"   , 0x46, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1048.   AddReg("GPCNTL"   , 0x47, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1049.   AddReg("STIME0"   , 0x48, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1050.   AddReg("STIME1"   , 0x49, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1051.   AddReg("RESPID"   , 0x4a, M_53C810 + M_53C815 + M_53C825 + M_53C860                      );
  1052.   AddReg("RESPID0"  , 0x4a,                                             M_53C875 + M_53C895);
  1053.   AddReg("RESPID1"  , 0x4b,                                             M_53C875 + M_53C895);
  1054.   AddReg("STEST0"   , 0x4c, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1055.   AddReg("STEST1"   , 0x4d, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1056.   AddReg("STEST2"   , 0x4e, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1057.   AddReg("STEST3"   , 0x4f, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1058.   AddReg("SIDL"     , 0x50, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1059.   AddReg("STEST4"   , 0x52,                                                      + M_53C895);
  1060.   AddReg("SODL"     , 0x54, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1061.   AddReg("SBDL"     , 0x58, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1062.   AddReg("SCRATCHB" , 0x5c, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
  1063.   AddReg("SCRATCHC" , 0x60,                                             M_53C875 + M_53C895);
  1064.   AddReg("SCRATCHD" , 0x64,                                             M_53C875 + M_53C895);
  1065.   AddReg("SCRATCHE" , 0x68,                                             M_53C875 + M_53C895);
  1066.   AddReg("SCRATCHF" , 0x6c,                                             M_53C875 + M_53C895);
  1067.   AddReg("SCRATCHG" , 0x70,                                             M_53C875 + M_53C895);
  1068.   AddReg("SCRATCHH" , 0x74,                                             M_53C875 + M_53C895);
  1069.   AddReg("SCRATCHI" , 0x78,                                             M_53C875 + M_53C895);
  1070.   AddReg("SCRATCHJ" , 0x7c,                                             M_53C875 + M_53C895);
  1071.   AddReg(NULL       , 0x00, 0);
  1072. }
  1073.  
  1074. static void DeinitFields(void)
  1075. {
  1076.   DestroyInstTable(InstTable);
  1077.   order_array_free(Regs);
  1078. }
  1079.  
  1080. /*---------------------------------------------------------------------------*/
  1081.  
  1082. static void MakeCode_53c8xx(void)
  1083. {
  1084.   CodeLen = 0;
  1085.   DontPrint = False;
  1086.  
  1087.   /* zu ignorierendes */
  1088.  
  1089.   if (Memo(""))
  1090.     return;
  1091.  
  1092.   if (DecodeIntelPseudo(False))
  1093.     return;
  1094.  
  1095.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1096.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1097. }
  1098.  
  1099. static Boolean IsDef_53c8xx(void)
  1100. {
  1101.   return False;
  1102. }
  1103.  
  1104. static void SwitchFrom_53c8xx(void)
  1105. {
  1106.   DeinitFields();
  1107. }
  1108.  
  1109. static void SwitchTo_53c8xx(void)
  1110. {
  1111.   const TFamilyDescr *FoundDescr;
  1112.  
  1113.   FoundDescr = FindFamilyByName("SYM53C8xx");
  1114.  
  1115.   TurnWords = False;
  1116.   SetIntConstMode(eIntConstModeC);
  1117.   SetIsOccupiedFnc = TrueFnc;
  1118.   PCSymbol="$";
  1119.   HeaderID = FoundDescr->Id;
  1120.   NOPCode = 0;
  1121.   DivideChars = ",";
  1122.   HasAttrs = False;
  1123.  
  1124.   ValidSegs = (1 << SegCode);
  1125.   Grans[SegCode ] = 1; ListGrans[SegCode ] = 4; SegInits[SegCode ] = 0;
  1126.   SegLimits[SegCode] = (LargeWord)IntTypeDefs[UInt32].Max;
  1127.  
  1128.   MakeCode = MakeCode_53c8xx;
  1129.   IsDef = IsDef_53c8xx;
  1130.   SwitchFrom = SwitchFrom_53c8xx;
  1131.  
  1132.   InitFields();
  1133. }
  1134.  
  1135. /*---------------------------------------------------------------------------*/
  1136.  
  1137. void code53c8xx_init(void)
  1138. {
  1139.   CPU53C810 = AddCPU("SYM53C810", SwitchTo_53c8xx);
  1140.   CPU53C860 = AddCPU("SYM53C860", SwitchTo_53c8xx);
  1141.   CPU53C815 = AddCPU("SYM53C815", SwitchTo_53c8xx);
  1142.   CPU53C825 = AddCPU("SYM53C825", SwitchTo_53c8xx);
  1143.   CPU53C875 = AddCPU("SYM53C875", SwitchTo_53c8xx);
  1144.   CPU53C895 = AddCPU("SYM53C895", SwitchTo_53c8xx);
  1145. }
  1146.