Subversion Repositories pentevo

Rev

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

  1. /* code68s12z.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS                                                                        */
  6. /*                                                                           */
  7. /* Code Generator NXP S12Z                                                   */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12.  
  13. #include <ctype.h>
  14. #include <string.h>
  15.  
  16. #include "strutil.h"
  17. #include "bpemu.h"
  18. #include "asmdef.h"
  19. #include "asmpars.h"
  20. #include "asmsub.h"
  21. #include "asmallg.h"
  22. #include "asmitree.h"
  23. #include "asmstructs.h"
  24. #include "codepseudo.h"
  25. #include "motpseudo.h"
  26. #include "codevars.h"
  27. #include "errmsg.h"
  28. #include "headids.h"
  29.  
  30. #include "codes12z.h"
  31.  
  32. typedef enum
  33. {
  34.   AdrModeNone = -1,
  35.   AdrModeReg = 0,
  36.   AdrModeAReg = 1,
  37.   AdrModeImm = 2,
  38.   AdrModeMemReg = 3
  39. } tAdrMode;
  40.  
  41. typedef enum
  42. {
  43.   eIndirModeNone,
  44.   eIndirModePar,
  45.   eIndirModeSquare
  46. } tIndirMode;
  47.  
  48. typedef enum
  49. {
  50.   eIncModeNone,
  51.   eIncModePreInc,
  52.   eIncModePostInc,
  53.   eIncModePreDec,
  54.   eIncModePostDec
  55. } tIncMode;
  56.  
  57. #define MModeReg (1 << AdrModeReg)
  58. #define MModeAReg (1 << AdrModeAReg)
  59. #define MModeImm (1 << AdrModeImm)
  60. #define MModeMemReg (1 << AdrModeMemReg)
  61.  
  62. #define OpSizeBitPos8 ((tSymbolSize)16)
  63. #define OpSizeBitPos16 ((tSymbolSize)17)
  64. #define OpSizeBitPos32 ((tSymbolSize)18)
  65. #define OpSizeShiftCount ((tSymbolSize)19)
  66.  
  67. typedef struct
  68. {
  69.   tAdrMode Mode;
  70.   Byte Arg, Vals[4], ShiftLSB;
  71.   unsigned ValCnt;
  72. } tAdrVals;
  73.  
  74. static tSymbolSize OpSize, OpSize2;
  75.  
  76. static const tSymbolSize RegSizes[16] =
  77. {
  78.   eSymbolSize16Bit, eSymbolSize16Bit,   /* D2/D3 */
  79.   eSymbolSize16Bit, eSymbolSize16Bit,   /* D4/D5 */
  80.   eSymbolSize8Bit,  eSymbolSize8Bit,    /* D0/D1 */
  81.   eSymbolSize32Bit, eSymbolSize32Bit,   /* D6/D7 */
  82.   eSymbolSize24Bit, eSymbolSize24Bit,   /* X/Y */
  83.   eSymbolSize24Bit, eSymbolSizeUnknown, /* S/- */
  84.   eSymbolSize8Bit,  eSymbolSize8Bit,    /* CCH/CCL */
  85.   eSymbolSize16Bit, eSymbolSizeUnknown, /* CCR/- */
  86. };
  87.  
  88. /*--------------------------------------------------------------------------*/
  89. /* Helper Functions */
  90.  
  91. static void PutCode(Word Code)
  92. {
  93.   if (Hi(Code))
  94.     BAsmCode[CodeLen++] = Hi(Code);
  95.   BAsmCode[CodeLen++] = Lo(Code);
  96. }
  97.  
  98. static void AppendAdrVals(const tAdrVals *pVals)
  99. {
  100.   memcpy(BAsmCode + CodeLen, pVals->Vals, pVals->ValCnt);
  101.   CodeLen += pVals->ValCnt;
  102. }
  103.  
  104. static Boolean DecodeRegStr(const char *pArg, Byte *pRes)
  105. {
  106.   if ((strlen(pArg) == 2)
  107.    && (toupper(*pArg) == 'D')
  108.    && ((pArg[1] >= '0') && (pArg[1] <= '7')))
  109.   {
  110.     static const Byte RegCodes[8] = { 4, 5, 0, 1, 2, 3, 6, 7 };
  111.  
  112.     *pRes = RegCodes[pArg[1] - '0'];
  113.     return True;
  114.   }
  115.   else
  116.     return False;
  117. }
  118.  
  119. static Boolean DecodeAdrRegStr(const char *pArg, Byte *pRes)
  120. {
  121.   static const char Regs[4][3] = { "X", "Y", "S", "PC" };
  122.   unsigned z;
  123.  
  124.   for (z = 0; z < 4; z++)
  125.     if (!as_strcasecmp(pArg, Regs[z]))
  126.     {
  127.       *pRes = z;
  128.       return True;
  129.     }
  130.   return False;
  131. }
  132.  
  133. static Boolean DecodeRegArg(int ArgNum, Byte *pRes, Byte Mask)
  134. {
  135.   Boolean Result = DecodeRegStr(ArgStr[ArgNum].str.p_str, pRes);
  136.  
  137.   if (!Result || !((Mask >> *pRes) & 1))
  138.     WrStrErrorPos(ErrNum_InvReg, &ArgStr[ArgNum]);
  139.   return Result;
  140. }
  141.  
  142. static Boolean DecodeAdrRegArg(int ArgNum, Byte *pRes, Byte Mask)
  143. {
  144.   Boolean Result = DecodeAdrRegStr(ArgStr[ArgNum].str.p_str, pRes);
  145.  
  146.   if (!Result || !((Mask >> *pRes) & 1))
  147.     WrStrErrorPos(ErrNum_InvReg, &ArgStr[ArgNum]);
  148.   return Result;
  149. }
  150.  
  151. static Boolean DecodeGenRegArg(int ArgNum, Byte *pRes)
  152. {
  153.   if (DecodeRegStr(ArgStr[ArgNum].str.p_str, pRes))
  154.     return True;
  155.   else if (DecodeAdrRegStr(ArgStr[ArgNum].str.p_str, pRes) && (*pRes != 3))
  156.   {
  157.     *pRes += 8;
  158.     return True;
  159.   }
  160.   else if (!as_strcasecmp(ArgStr[ArgNum].str.p_str, "CCH"))
  161.   {
  162.     *pRes = 12;
  163.     return True;
  164.   }
  165.   else if (!as_strcasecmp(ArgStr[ArgNum].str.p_str, "CCL"))
  166.   {
  167.     *pRes = 13;
  168.     return True;
  169.   }
  170.   else if (!as_strcasecmp(ArgStr[ArgNum].str.p_str, "CCW"))
  171.   {
  172.     *pRes = 14;
  173.     return True;
  174.   }
  175.   else
  176.     return False;
  177. }
  178.  
  179. static Boolean ShortImm(LongInt Value, ShortInt OpSize, Byte *pShortValue, Byte *pShiftLSB)
  180. {
  181.   if (OpSize == OpSizeShiftCount)
  182.   {
  183.     if ((Value >= 0) && (Value <= 31))
  184.     {
  185.       *pShortValue = (Value >> 1 & 15);
  186.       *pShiftLSB = Value & 1;
  187.       return True;
  188.     }
  189.     else
  190.       return False;
  191.   }
  192.   else if (OpSize < OpSizeBitPos8)
  193.   {
  194.     if (Value == -1)
  195.     {
  196.       *pShortValue = 0;
  197.       return True;
  198.     }
  199.     else if ((Value >= 1) && (Value <= 15))
  200.     {
  201.       *pShortValue = Value;
  202.       return True;
  203.     }
  204.     else if (((Value == (LongInt)0xff) && (OpSize == 0))
  205.           || ((Value == (LongInt)0xffff) && (OpSize == 1))
  206.           || ((Value == (LongInt)0xffffff) && (OpSize == eSymbolSize24Bit))
  207.           || ((Value == (LongInt)0xffffffff) && (OpSize == 2)))
  208.     {
  209.       *pShortValue = 0;
  210.       return True;
  211.     }
  212.     else
  213.       return False;
  214.   }
  215.   else
  216.     return False;
  217. }
  218.  
  219. static unsigned OpSizeByteLen(ShortInt OpSize)
  220. {
  221.   switch (OpSize)
  222.   {
  223.     case -1: return 0;
  224.     case 1: return 2;
  225.     case 2: return 4;
  226.     case eSymbolSize24Bit: return 3;
  227.     default: return 1;
  228.   }
  229. }
  230.  
  231. static void ResetAdrVals(tAdrVals *pVals)
  232. {
  233.   pVals->Mode = AdrModeNone;
  234.   pVals->Arg = 0;
  235.   pVals->ValCnt = 0;
  236.   pVals->ShiftLSB = 0;
  237. }
  238.  
  239. static Boolean IsIncDec(char ch, char *pRes)
  240. {
  241.   *pRes = ((ch == '+') || (ch == '-')) ? ch : '\0';
  242.   return !!*pRes;
  243. }
  244.  
  245. static void CopyIndirect(tStrComp *pDest, const tStrComp *pSrc)
  246. {
  247.   pDest->Pos.Len = strmemcpy(pDest->str.p_str, STRINGSIZE, pSrc->str.p_str + 1, strlen(pSrc->str.p_str) - 2);
  248.   pDest->Pos.StartCol = pSrc->Pos.StartCol + 1;
  249. }
  250.  
  251. static Boolean DecodeAdr(int ArgIndex, unsigned ModeMask, tAdrVals *pVals)
  252. {
  253.   String CompStr;
  254.   tStrComp Comp;
  255.   int l;
  256.   tIndirMode IndirMode;
  257.   LargeWord Address;
  258.   Boolean OK;
  259.  
  260.   ResetAdrVals(pVals);
  261.   StrCompMkTemp(&Comp, CompStr, sizeof(CompStr));
  262.  
  263.   /* simple register: */
  264.  
  265.   if (DecodeRegStr(ArgStr[ArgIndex].str.p_str, &pVals->Arg))
  266.   {
  267.     if (ModeMask & MModeReg)
  268.       pVals->Mode = AdrModeReg;
  269.     else
  270.     {
  271.       pVals->Mode = AdrModeMemReg;
  272.       pVals->Arg |= 0xb8;
  273.     }
  274.     goto done;
  275.   }
  276.  
  277.   if (DecodeAdrRegStr(ArgStr[ArgIndex].str.p_str, &pVals->Arg))
  278.   {
  279.     pVals->Mode = AdrModeAReg;
  280.     goto done;
  281.   }
  282.  
  283.   /* immediate: */
  284.  
  285.   if (*ArgStr[ArgIndex].str.p_str == '#')
  286.   {
  287.     Boolean OK;
  288.     LongInt Value;
  289.  
  290.     /* avoid returning AdrModeMemReg if immediate is forbidden */
  291.  
  292.     if (!(ModeMask &MModeImm))
  293.       goto error;
  294.  
  295.     switch ((int)OpSize)
  296.     {
  297.       case eSymbolSize8Bit:
  298.         Value = EvalStrIntExpressionOffs(&ArgStr[ArgIndex], 1, Int8, &OK);
  299.         break;
  300.       case eSymbolSize16Bit:
  301.         Value = EvalStrIntExpressionOffs(&ArgStr[ArgIndex], 1, Int16, &OK);
  302.         break;
  303.       case eSymbolSize32Bit:
  304.         Value = EvalStrIntExpressionOffs(&ArgStr[ArgIndex], 1, Int32, &OK);
  305.         break;
  306.       case eSymbolSize24Bit:
  307.         Value = EvalStrIntExpressionOffs(&ArgStr[ArgIndex], 1, Int24, &OK);
  308.         break;
  309.       case OpSizeBitPos8:
  310.         Value = EvalStrIntExpressionOffs(&ArgStr[ArgIndex], 1, UInt3, &OK);
  311.         break;
  312.       case OpSizeBitPos16:
  313.         Value = EvalStrIntExpressionOffs(&ArgStr[ArgIndex], 1, UInt4, &OK);
  314.         break;
  315.       case OpSizeBitPos32:
  316.       case OpSizeShiftCount:
  317.         Value = EvalStrIntExpressionOffs(&ArgStr[ArgIndex], 1, UInt5, &OK);
  318.         break;
  319.       default:
  320.         WrStrErrorPos(ErrNum_UndefOpSizes, &ArgStr[ArgIndex]);
  321.         goto done;
  322.     }
  323.  
  324.     if ((ModeMask & MModeMemReg) && (ShortImm(Value, OpSize, &pVals->Arg, &pVals->ShiftLSB)))
  325.     {
  326.       pVals->Mode = AdrModeMemReg;
  327.       pVals->Arg |= 0x70;
  328.     }
  329.     else
  330.     {
  331.       pVals->Mode = AdrModeImm;
  332.       if (OpSize == eSymbolSize32Bit)
  333.         pVals->Vals[pVals->ValCnt++] = (Value >> 24) & 0xff;
  334.       if ((OpSize == eSymbolSize32Bit) || (OpSize == eSymbolSize24Bit))
  335.         pVals->Vals[pVals->ValCnt++] = (Value >> 16) & 0xff;
  336.       if ((OpSize != eSymbolSize8Bit) && (OpSize < OpSizeBitPos8))
  337.         pVals->Vals[pVals->ValCnt++] = (Value >> 8) & 0xff;
  338.       pVals->Vals[pVals->ValCnt++] = Value & 0xff;
  339.     }
  340.     goto done;
  341.   }
  342.  
  343.   /* indirect () []: */
  344.  
  345.   l = strlen(ArgStr[ArgIndex].str.p_str);
  346.   if (IsIndirect(ArgStr[ArgIndex].str.p_str))
  347.     IndirMode = eIndirModePar;
  348.   else if ((l >= 2) && (ArgStr[ArgIndex].str.p_str[0] == '[') && (ArgStr[ArgIndex].str.p_str[l - 1] == ']'))
  349.     IndirMode = eIndirModeSquare;
  350.   else
  351.     IndirMode = eIndirModeNone;
  352.  
  353.   if (IndirMode)
  354.   {
  355.     char *pSep, IncChar;
  356.     LongInt DispAcc = 0;
  357.     Byte DataReg = 0, AdrReg = 0, AdrIncReg = 0;
  358.     Boolean AdrRegPresent = False, DataRegPresent = False, HasDisp = False;
  359.     tIncMode IncMode = eIncModeNone;
  360.     tStrComp Right, RunComp;
  361.  
  362.     CopyIndirect(&Comp, &ArgStr[ArgIndex]);
  363.     StrCompRefRight(&RunComp, &Comp, 0);
  364.  
  365.     /* split into components */
  366.  
  367.     while (True)
  368.     {
  369.       pSep = QuotPos(RunComp.str.p_str, ',');
  370.       if (pSep)
  371.         StrCompSplitRef(&RunComp, &Right, &RunComp, pSep);
  372.  
  373.       /* remove leading/trailing spaces */
  374.  
  375.       KillPrefBlanksStrCompRef(&RunComp);
  376.       KillPostBlanksStrComp(&RunComp);
  377.       l = strlen(RunComp.str.p_str);
  378.  
  379.       if (DecodeRegStr(RunComp.str.p_str, &DataReg))
  380.       {
  381.         if (DataRegPresent)
  382.         {
  383.           WrStrErrorPos(ErrNum_InvAddrMode, &RunComp);
  384.           goto done;
  385.         }
  386.         DataRegPresent = True;
  387.       }
  388.       else if (DecodeAdrRegStr(RunComp.str.p_str, &AdrReg))
  389.       {
  390.         if (AdrRegPresent)
  391.         {
  392.           WrStrErrorPos(ErrNum_InvAddrMode, &RunComp);
  393.           goto done;
  394.         }
  395.         AdrRegPresent = True;
  396.       }
  397.       else if (IsIncDec(*RunComp.str.p_str, &IncChar) && DecodeAdrRegStr(RunComp.str.p_str + 1, &AdrIncReg))
  398.       {
  399.         if (IncMode)
  400.         {
  401.           WrStrErrorPos(ErrNum_InvAddrMode, &RunComp);
  402.           goto done;
  403.         }
  404.         IncMode = (IncChar == '+') ? eIncModePreInc : eIncModePreDec;
  405.       }
  406.       else if (IsIncDec(Comp.str.p_str[l - 1], &IncChar))
  407.       {
  408.         RunComp.str.p_str[l - 1] = '\0';
  409.         if (!DecodeAdrRegStr(RunComp.str.p_str, &AdrIncReg))
  410.         {
  411.           WrStrErrorPos(ErrNum_InvReg, &RunComp);
  412.           goto done;
  413.         }
  414.         if (IncMode)
  415.         {
  416.           WrStrErrorPos(ErrNum_InvAddrMode, &RunComp);
  417.           goto done;
  418.         }
  419.         IncMode = (IncChar == '+') ? eIncModePostInc : eIncModePostDec;
  420.       }
  421.       else
  422.       {
  423.         Boolean OK;
  424.         LongInt Val = EvalStrIntExpression(&RunComp, Int24, &OK);
  425.  
  426.         if (!OK)
  427.           goto done;
  428.         DispAcc += Val;
  429.         HasDisp = True;
  430.       }
  431.  
  432.       if (pSep)
  433.         RunComp = Right;
  434.       else
  435.         break;
  436.     }
  437.  
  438.     /* pre/pos in/decrement */
  439.  
  440.     if ((IndirMode == eIndirModePar) && IncMode && !DispAcc && !AdrRegPresent && !DataRegPresent)
  441.     {
  442.       switch (AdrIncReg)
  443.       {
  444.         case 0:
  445.         case 1:
  446.           pVals->Arg = 0xc3 | (AdrIncReg << 4);
  447.           if ((IncMode == eIncModePostInc) || (IncMode == eIncModePreInc))
  448.             pVals->Arg |= 0x20;
  449.           if ((IncMode == eIncModePostInc) || (IncMode == eIncModePostDec))
  450.             pVals->Arg |= 0x04;
  451.           pVals->Mode = AdrModeMemReg;
  452.           break;
  453.         case 2:
  454.           if (IncMode == eIncModePreDec)
  455.           {
  456.             pVals->Arg = 0xfb;
  457.             pVals->Mode = AdrModeMemReg;
  458.           }
  459.           else if (IncMode == eIncModePostInc)
  460.           {
  461.             pVals->Arg = 0xff;
  462.             pVals->Mode = AdrModeMemReg;
  463.           }
  464.           else
  465.             goto error;
  466.           break;
  467.         default:
  468.           goto error;
  469.       }
  470.     }
  471.  
  472.     /* (disp,XYSP) */
  473.  
  474.     else if ((IndirMode == eIndirModePar) && AdrRegPresent && !DataRegPresent && !IncMode)
  475.     {
  476.       if ((AdrReg == 3) && (HasDisp))
  477.         DispAcc -= EProgCounter();
  478.  
  479.       if ((DispAcc >= 0) && (DispAcc <= 15) && (AdrReg != 3))
  480.       {
  481.         pVals->Arg = 0x40 | (AdrReg << 4) | (DispAcc & 15);
  482.         pVals->Mode = AdrModeMemReg;
  483.       }
  484.       else if (RangeCheck(DispAcc, SInt9))
  485.       {
  486.         pVals->Arg = 0xc0 | (AdrReg << 4) | ((DispAcc >> 8) & 1);
  487.         pVals->Vals[pVals->ValCnt++] = DispAcc & 0xff;
  488.         pVals->Mode = AdrModeMemReg;
  489.       }
  490.       else
  491.       {
  492.         pVals->Arg = 0xc2 | (AdrReg << 4);
  493.         pVals->Vals[pVals->ValCnt++] = (DispAcc >> 16) & 0xff;
  494.         pVals->Vals[pVals->ValCnt++] = (DispAcc >> 8) & 0xff;
  495.         pVals->Vals[pVals->ValCnt++] = DispAcc & 0xff;
  496.         pVals->Mode = AdrModeMemReg;
  497.       }
  498.     }
  499.  
  500.     /* (Dn,XYS) */
  501.  
  502.     else if ((IndirMode == eIndirModePar) && AdrRegPresent && DataRegPresent && !IncMode && !DispAcc)
  503.     {
  504.       if (AdrReg == 3)
  505.         goto error;
  506.       else
  507.       {
  508.         pVals->Arg = 0x88 | (AdrReg << 4) | DataReg;
  509.         pVals->Mode = AdrModeMemReg;
  510.       }
  511.     }
  512.  
  513.     /* (disp,Dn) */
  514.  
  515.     else if ((IndirMode == eIndirModePar) && !AdrRegPresent && DataRegPresent && !IncMode)
  516.     {
  517.       if (RangeCheck(DispAcc, UInt18))
  518.       {
  519.         pVals->Arg = 0x80 | DataReg | ((DispAcc >> 12) & 0x30);
  520.         pVals->Vals[pVals->ValCnt++] = (DispAcc >> 8) & 0xff;
  521.         pVals->Vals[pVals->ValCnt++] = DispAcc & 0xff;
  522.         pVals->Mode = AdrModeMemReg;
  523.       }
  524.       else
  525.       {
  526.         pVals->Arg = 0xe8 | DataReg;
  527.         pVals->Vals[pVals->ValCnt++] = (DispAcc >> 16) & 0xff;
  528.         pVals->Vals[pVals->ValCnt++] = (DispAcc >> 8) & 0xff;
  529.         pVals->Vals[pVals->ValCnt++] = DispAcc & 0xff;
  530.         pVals->Mode = AdrModeMemReg;
  531.       }
  532.     }
  533.  
  534.     /* [Dn,XY] */
  535.  
  536.     else if ((IndirMode == eIndirModeSquare) && AdrRegPresent && DataRegPresent && !IncMode && !DispAcc)
  537.     {
  538.       if (AdrReg >= 2)
  539.         goto error;
  540.       else
  541.       {
  542.         pVals->Arg = 0xc8 | (AdrReg << 4) | DataReg;
  543.         pVals->Mode = AdrModeMemReg;
  544.       }
  545.     }
  546.  
  547.     /* [disp,XYSP] */
  548.  
  549.     else if ((IndirMode == eIndirModeSquare) && AdrRegPresent && !DataRegPresent && !IncMode)
  550.     {
  551.       if ((AdrReg == 3) && (HasDisp))
  552.         DispAcc -= EProgCounter();
  553.  
  554.       if (RangeCheck(DispAcc, SInt9))
  555.       {
  556.         pVals->Arg = 0xc4 | (AdrReg << 4) | ((DispAcc >> 8) & 1);
  557.         pVals->Vals[pVals->ValCnt++] = DispAcc & 0xff;
  558.         pVals->Mode = AdrModeMemReg;
  559.       }
  560.       else
  561.       {
  562.         pVals->Arg = 0xc6 | (AdrReg << 4);
  563.         pVals->Vals[pVals->ValCnt++] = (DispAcc >> 16) & 0xff;
  564.         pVals->Vals[pVals->ValCnt++] = (DispAcc >> 8) & 0xff;
  565.         pVals->Vals[pVals->ValCnt++] = DispAcc & 0xff;
  566.         pVals->Mode = AdrModeMemReg;
  567.       }
  568.     }
  569.  
  570.     /* [disp] */
  571.  
  572.     else if ((IndirMode == eIndirModeSquare) && !AdrRegPresent && !DataRegPresent && !IncMode)
  573.     {
  574.       pVals->Arg = 0xfe;
  575.       pVals->Vals[pVals->ValCnt++] = (DispAcc >> 16) & 0xff;
  576.       pVals->Vals[pVals->ValCnt++] = (DispAcc >> 8) & 0xff;
  577.       pVals->Vals[pVals->ValCnt++] = DispAcc & 0xff;
  578.       pVals->Mode = AdrModeMemReg;
  579.     }
  580.  
  581.     else
  582.       goto error;
  583.  
  584.     goto done;
  585.   }
  586.  
  587.   /* absolute: */
  588.  
  589.   Address = EvalStrIntExpression(&ArgStr[ArgIndex], UInt24, &OK);
  590.   if (OK)
  591.   {
  592.     if (RangeCheck(Address, UInt14))
  593.     {
  594.       pVals->Arg = 0x00 | ((Address >> 8) & 0x3f);
  595.       pVals->Vals[pVals->ValCnt++] = Address & 0xff;
  596.     }
  597.     else if (RangeCheck(Address, UInt18))
  598.     {
  599.       pVals->Arg = 0xf8 | ((Address >> 16) & 1) | ((Address >> 15) & 4);
  600.       pVals->Vals[pVals->ValCnt++] = (Address >> 8) & 0xff;
  601.       pVals->Vals[pVals->ValCnt++] = Address & 0xff;
  602.     }
  603.     else
  604.     {
  605.       pVals->Arg = 0xfa;
  606.       pVals->Vals[pVals->ValCnt++] = (Address >> 16) & 0xff;
  607.       pVals->Vals[pVals->ValCnt++] = (Address >> 8) & 0xff;
  608.       pVals->Vals[pVals->ValCnt++] = Address & 0xff;
  609.     }
  610.     pVals->Mode = AdrModeMemReg;
  611.   }
  612.  
  613. done:
  614.   if ((pVals->Mode != AdrModeNone) && !((ModeMask >> pVals->Mode) & 1))
  615.   {
  616.     ResetAdrVals(pVals);
  617.     goto error;
  618.   }
  619.   return (pVals->Mode != AdrModeNone);
  620.  
  621. error:
  622.   WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[ArgIndex]);
  623.   return False;
  624. }
  625.  
  626. static Boolean IsImmediate(const tAdrVals *pVals, ShortInt OpSize, Byte *pImmVal)
  627. {
  628.   switch (pVals->Mode)
  629.   {
  630.     case AdrModeImm:
  631.       *pImmVal = pVals->Vals[pVals->ValCnt - 1];
  632.       return True;
  633.     case AdrModeMemReg:
  634.       if ((pVals->Arg & 0xf0) == 0x70)
  635.       {
  636.         *pImmVal = pVals->Arg & 15;
  637.         if (OpSize == OpSizeShiftCount)
  638.           *pImmVal = (*pImmVal << 1) | pVals->ShiftLSB;
  639.         else if (!*pImmVal && (OpSize < OpSizeBitPos8))
  640.           *pImmVal = 0xff;
  641.         return True;
  642.       }
  643.       /* else fall-through */
  644.     default:
  645.       *pImmVal = 0;
  646.       return False;
  647.   }
  648. }
  649.  
  650. static void ChangeImmediate(tAdrVals *pVals, ShortInt OpSize, Byte ImmVal)
  651. {
  652.   unsigned z;
  653.  
  654.   pVals->Mode = AdrModeImm;
  655.   pVals->Arg = 0;
  656.   pVals->ValCnt = OpSizeByteLen(OpSize);
  657.   pVals->Vals[pVals->ValCnt - 1] = ImmVal;
  658.   for (z = 1; z < pVals->ValCnt; z++)
  659.     pVals->Vals[z] = (ImmVal & 0x80) ? 0xff : 0x00;
  660. }
  661.  
  662. static Boolean IsReg(const tAdrVals *pVals, Byte *pReg)
  663. {
  664.   switch (pVals->Mode)
  665.   {
  666.     case AdrModeReg:
  667.       *pReg = pVals->Arg;
  668.       return True;
  669.     case AdrModeMemReg:
  670.       if ((pVals->Arg & 0xf8) == 0xb8)
  671.       {
  672.         *pReg = pVals->Arg & 7;
  673.         return True;
  674.       }
  675.       /* else fall-through */
  676.     default:
  677.       *pReg = 0;
  678.       return False;
  679.   }
  680. }
  681.  
  682. static Boolean SetOpSize(tSymbolSize NewOpSize)
  683. {
  684.   if ((OpSize == NewOpSize) || (OpSize == eSymbolSizeUnknown))
  685.   {
  686.     OpSize = NewOpSize;
  687.     return True;
  688.   }
  689.   else
  690.   {
  691.     char Str[30];
  692.  
  693.     as_snprintf(Str, sizeof(Str), "%d -> %d", (int)OpSize, (int)NewOpSize);
  694.     WrXError(ErrNum_ConfOpSizes, Str);
  695.     return False;
  696.   }
  697. }
  698.  
  699. static Boolean SizeCode2(ShortInt ThisOpSize, Byte *pSizeCode)
  700. {
  701.   switch (ThisOpSize)
  702.   {
  703.     case eSymbolSize8Bit: *pSizeCode = 0; break;
  704.     case eSymbolSize16Bit: *pSizeCode = 1; break;
  705.     case eSymbolSize24Bit: *pSizeCode = 2; break;
  706.     case eSymbolSize32Bit: *pSizeCode = 3; break;
  707.     default: return False;
  708.   }
  709.   return True;
  710. }
  711.  
  712. static Boolean DecodeImmBitField(tStrComp *pArg, Word *pResult)
  713. {
  714.   char *pSplit = strchr(pArg->str.p_str, ':'), Save;
  715.   tStrComp Left, Right;
  716.   Boolean OK;
  717.   tSymbolFlags Flags;
  718.  
  719.   if (!pSplit)
  720.   {
  721.     WrError(ErrNum_InvBitPos);
  722.     return False;
  723.   }
  724.   Save = StrCompSplitRef(&Left, &Right, pArg, pSplit);
  725.   *pResult = EvalStrIntExpressionWithFlags(&Left, UInt6, &OK, &Flags);
  726.   if (mFirstPassUnknown(Flags))
  727.     *pResult &= 31;
  728.   *pSplit = Save;
  729.   if (!OK || !ChkRange(*pResult, 1, 32))
  730.     return False;
  731.   *pResult = (*pResult << 5) | (EvalStrIntExpression(&Right, UInt5, &OK) & 31);
  732.   return OK;
  733. }
  734.  
  735. /*--------------------------------------------------------------------------*/
  736. /* Bit Symbol Handling */
  737.  
  738. /*
  739.  * Compact representation of bits and bit fields in symbol table:
  740.  * bits 0..2/3/4: (start) bit position
  741.  * bits 3/4/5...14/15/16: register address in I/O space (first 4K)
  742.  * bits 20/21: register size (0/1/2/3 for 8/16/32/24 bits)
  743.  * bits 24..28: length of bit field minus one (0 for individual bit)
  744.  */
  745.  
  746. /*!------------------------------------------------------------------------
  747.  * \fn     AssembleBitfieldSymbol(Byte BitPos, Byte Width, ShortInt OpSize, Word Address)
  748.  * \brief  build the compact internal representation of a bit field symbol
  749.  * \param  BitPos bit position in word
  750.  * \param  Width width of bit field
  751.  * \param  OpSize operand size (0..2)
  752.  * \param  Address register address
  753.  * \return compact representation
  754.  * ------------------------------------------------------------------------ */
  755.  
  756. static LongWord AssembleBitfieldSymbol(Byte BitPos, Byte Width, ShortInt OpSize, Word Address)
  757. {
  758.   LongWord CodeOpSize = (OpSize == eSymbolSize24Bit) ? 3 : OpSize;
  759.   int AddrShift = (OpSize == eSymbolSize24Bit) ? 5 : (3 + OpSize);
  760.  
  761.   return BitPos
  762.        | (((LongWord)Address & 0xfff) << AddrShift)
  763.        | (CodeOpSize << 20)
  764.        | (((LongWord)(Width - 1) & 31) << 24);
  765. }
  766.  
  767. /*!------------------------------------------------------------------------
  768.  * \fn     AssembleBitSymbol(Byte BitPos, ShortInt OpSize, Word Address)
  769.  * \brief  build the compact internal representation of a bit symbol
  770.  * \param  BitPos bit position in word
  771.  * \param  OpSize operand size (0..2)
  772.  * \param  Address register address
  773.  * \return compact representation
  774.  * ------------------------------------------------------------------------ */
  775.  
  776. static LongWord AssembleBitSymbol(Byte BitPos, ShortInt OpSize, Word Address)
  777. {
  778.   return AssembleBitfieldSymbol(BitPos, 1, OpSize, Address);
  779. }
  780.  
  781. /*!------------------------------------------------------------------------
  782.  * \fn     EvalBitPosition(const char *pBitArg, Boolean *pOK, ShortInt OpSize)
  783.  * \brief  evaluate constant bit position, with bit range depending on operand size
  784.  * \param  pBitArg bit position argument
  785.  * \param  pOK returns True if OK
  786.  * \param  OpSize operand size (0,1,2 -> 8,16,32 bits)
  787.  * \return bit position as number
  788.  * ------------------------------------------------------------------------ */
  789.  
  790. static Byte EvalBitPosition(const tStrComp *pBitArg, Boolean *pOK, ShortInt OpSize)
  791. {
  792.   switch (OpSize)
  793.   {
  794.     case eSymbolSize8Bit:
  795.       return EvalStrIntExpression(pBitArg, UInt3, pOK);
  796.     case eSymbolSize16Bit:
  797.       return EvalStrIntExpression(pBitArg, UInt4, pOK);
  798.     case eSymbolSize24Bit:
  799.     {
  800.       Byte Result;
  801.       tSymbolFlags Flags;
  802.  
  803.       Result = EvalStrIntExpressionWithFlags(pBitArg, UInt5, pOK, &Flags);
  804.       if (!*pOK)
  805.         return Result;
  806.       if (mFirstPassUnknown(Flags))
  807.         Result &= 15;
  808.       *pOK = ChkRange(Result, 0, 23);
  809.       return Result;
  810.     }
  811.     case eSymbolSize32Bit:
  812.       return EvalStrIntExpression(pBitArg, UInt5, pOK);
  813.     default:
  814.       WrError(ErrNum_InvOpSize);
  815.       *pOK = False;
  816.       return 0;
  817.   }
  818. }
  819.  
  820. /*!------------------------------------------------------------------------
  821.  * \fn     DecodeBitArg2(LongWord *pResult, const tStrComp *pRegArg, const tStrComp *pBitArg, ShortInt OpSize)
  822.  * \brief  encode a bit symbol, address & bit position separated
  823.  * \param  pResult resulting encoded bit
  824.  * \param  pRegArg register argument
  825.  * \param  pBitArg bit argument
  826.  * \param  OpSize register size (0/1/2 = 8/16/32 bit)
  827.  * \return True if success
  828.  * ------------------------------------------------------------------------ */
  829.  
  830. static Boolean DecodeBitArg2(LongWord *pResult, const tStrComp *pRegArg, const tStrComp *pBitArg, ShortInt OpSize)
  831. {
  832.   Boolean OK;
  833.   tSymbolFlags Flags;
  834.   LongWord Addr;
  835.   Byte BitPos;
  836.  
  837.   BitPos = EvalBitPosition(pBitArg, &OK, OpSize);
  838.   if (!OK)
  839.     return False;
  840.  
  841.   /* all I/O registers reside in the first 4K of the address space */
  842.  
  843.   Addr = EvalStrIntExpressionWithFlags(pRegArg, UInt12, &OK, &Flags);
  844.   if (!OK)
  845.     return False;
  846.  
  847.   *pResult = AssembleBitSymbol(BitPos, OpSize, Addr);
  848.  
  849.   return True;
  850. }
  851.  
  852. /*!------------------------------------------------------------------------
  853.  * \fn     DecodeBitfieldArg2(LongWord *pResult, const tStrComp *pRegArg, tStrComp *pBitArg, ShortInt OpSize)
  854.  * \brief  encode a bit field symbol, address & bit position separated
  855.  * \param  pResult resulting encoded bit
  856.  * \param  pRegArg register argument
  857.  * \param  pBitArg bit argument
  858.  * \param  OpSize register size (0/1/2 = 8/16/32 bit)
  859.  * \return True if success
  860.  * ------------------------------------------------------------------------ */
  861.  
  862. static Boolean DecodeBitfieldArg2(LongWord *pResult, const tStrComp *pRegArg, tStrComp *pBitArg, ShortInt OpSize)
  863. {
  864.   Boolean OK;
  865.   LongWord Addr;
  866.   Word BitSpec;
  867.  
  868.   if (!DecodeImmBitField(pBitArg, &BitSpec))
  869.     return False;
  870.  
  871.   /* all I/O registers reside in the first 4K of the address space */
  872.  
  873.   Addr = EvalStrIntExpression(pRegArg, UInt12, &OK);
  874.   if (!OK)
  875.     return False;
  876.  
  877.   *pResult = AssembleBitfieldSymbol(BitSpec & 31, (BitSpec >> 5) & 31, OpSize, Addr);
  878.  
  879.   return True;
  880. }
  881.  
  882. /*!------------------------------------------------------------------------
  883.  * \fn     DecodeBitArg(LongWord *pResult, int Start, int Stop, ShortInt OpSize)
  884.  * \brief  encode a bit symbol from instruction argument(s)
  885.  * \param  pResult resulting encoded bit
  886.  * \param  Start first argument
  887.  * \param  Stop last argument
  888.  * \param  OpSize register size (0/1/2 = 8/16/32 bit)
  889.  * \return True if success
  890.  * ------------------------------------------------------------------------ */
  891.  
  892. static Boolean DecodeBitArg(LongWord *pResult, int Start, int Stop, ShortInt OpSize)
  893. {
  894.   *pResult = 0;
  895.  
  896.   /* Just one argument -> parse as bit argument */
  897.  
  898.   if (Start == Stop)
  899.   {
  900.     tEvalResult EvalResult;
  901.  
  902.     *pResult = EvalStrIntExpressionWithResult(&ArgStr[Start], UInt32, &EvalResult);
  903.     if (EvalResult.OK)
  904.       ChkSpace(SegBData, EvalResult.AddrSpaceMask);
  905.     return EvalResult.OK;
  906.   }
  907.  
  908.   /* register & bit position are given as separate arguments */
  909.  
  910.   else if (Stop == Start + 1)
  911.     return DecodeBitArg2(pResult, &ArgStr[Start], &ArgStr[Stop], OpSize);
  912.  
  913.   /* other # of arguments not allowed */
  914.  
  915.   else
  916.   {
  917.     WrError(ErrNum_WrongArgCnt);
  918.     return False;
  919.   }
  920. }
  921.  
  922. /*!------------------------------------------------------------------------
  923.  * \fn     DecodeBitfieldArg(LongWord *pResult, int Start, int Stop, ShortInt OpSize)
  924.  * \brief  encode a bit symbol from instruction argument(s)
  925.  * \param  pResult resulting encoded bit
  926.  * \param  Start first argument
  927.  * \param  Stop last argument
  928.  * \return True if success
  929.  * ------------------------------------------------------------------------ */
  930.  
  931. static Boolean DecodeBitfieldArg(LongWord *pResult, int Start, int Stop, ShortInt OpSize)
  932. {
  933.   *pResult = 0;
  934.  
  935.   /* Just one argument -> parse as bit field argument */
  936.  
  937.   if (Start == Stop)
  938.   {
  939.     tEvalResult EvalResult;
  940.  
  941.     *pResult = EvalStrIntExpressionWithResult(&ArgStr[Start], UInt32, &EvalResult);
  942.     if (EvalResult.OK)
  943.       ChkSpace(SegBData, EvalResult.AddrSpaceMask);
  944.     return EvalResult.OK;
  945.   }
  946.  
  947.   /* register & bit position are given as separate arguments */
  948.  
  949.   else if (Stop == Start + 1)
  950.     return DecodeBitfieldArg2(pResult, &ArgStr[Start], &ArgStr[Stop], OpSize);
  951.  
  952.   /* other # of arguments not allowed */
  953.  
  954.   else
  955.   {
  956.     WrError(ErrNum_WrongArgCnt);
  957.     return False;
  958.   }
  959. }
  960.  
  961. /*!------------------------------------------------------------------------
  962.  * \fn     DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos, Byte *pWidth, tSymbolSize *pOpSize)
  963.  * \brief  transform compact represenation of bit (field) symbol into components
  964.  * \param  BitSymbol compact storage
  965.  * \param  pAddress (I/O) register address
  966.  * \param  pBitPos (start) bit position
  967.  * \param  pWidth pWidth width of bit field, always one for individual bit
  968.  * \param  pOpSize returns register size (0/1/2 for 8/16/32 bits)
  969.  * \return constant True
  970.  * ------------------------------------------------------------------------ */
  971.  
  972. static Boolean DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos, Byte *pWidth, tSymbolSize *pOpSize)
  973. {
  974.   *pOpSize = (tSymbolSize)((BitSymbol >> 20) & 3);
  975.   switch (*pOpSize)
  976.   {
  977.     case eSymbolSize8Bit:
  978.       *pAddress = (BitSymbol >> 3) & 0xfff;
  979.       *pBitPos = BitSymbol & 7;
  980.       break;
  981.     case eSymbolSize16Bit:
  982.       *pAddress = (BitSymbol >> 4) & 0xfff;
  983.       *pBitPos = BitSymbol & 15;
  984.       break;
  985.     case 3:
  986.       *pOpSize = eSymbolSize24Bit;
  987.       /* fall-through */
  988.     case eSymbolSize32Bit:
  989.       *pAddress = (BitSymbol >> 5) & 0xfff;
  990.       *pBitPos = BitSymbol & 31;
  991.     default:
  992.       break;
  993.   }
  994.   *pWidth = 1 + ((BitSymbol >> 24) & 31);
  995.   return True;
  996. }
  997.  
  998. /*!------------------------------------------------------------------------
  999.  * \fn     DissectBit_S12Z(char *pDest, size_t DestSize, LargeWord Inp)
  1000.  * \brief  dissect compact storage of bit (field) into readable form for listing
  1001.  * \param  pDest destination for ASCII representation
  1002.  * \param  DestSize destination buffer size
  1003.  * \param  Inp compact storage
  1004.  * ------------------------------------------------------------------------ */
  1005.  
  1006. static void DissectBit_S12Z(char *pDest, size_t DestSize, LargeWord Inp)
  1007. {
  1008.   Byte BitPos, BitWidth;
  1009.   Word Address;
  1010.   tSymbolSize OpSize;
  1011.   char Attribute;
  1012.  
  1013.   DissectBitSymbol(Inp, &Address, &BitPos, &BitWidth, &OpSize);
  1014.   Attribute = (OpSize == eSymbolSize24Bit) ? 'p' : "bwl"[OpSize];
  1015.  
  1016.   if (BitWidth > 1)
  1017.     as_snprintf(pDest, DestSize, "$%x(%c).%u:%u", (unsigned)Address, Attribute, (unsigned)BitWidth, (unsigned)BitPos);
  1018.   else
  1019.     as_snprintf(pDest, DestSize, "$%x(%c).%u", (unsigned)Address, Attribute, (unsigned)BitPos);
  1020. }
  1021.  
  1022. /*!------------------------------------------------------------------------
  1023.  * \fn     ExpandS12ZBit(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
  1024.  * \brief  expands bit definition when a structure is instantiated
  1025.  * \param  pVarName desired symbol name
  1026.  * \param  pStructElem element definition
  1027.  * \param  Base base address of instantiated structure
  1028.  * ------------------------------------------------------------------------ */
  1029.  
  1030. static void ExpandS12ZBit(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
  1031. {
  1032.   LongWord Address = Base + pStructElem->Offset;
  1033.  
  1034.   if (pInnermostNamedStruct)
  1035.   {
  1036.     PStructElem pElem = CloneStructElem(pVarName, pStructElem);
  1037.  
  1038.     if (!pElem)
  1039.       return;
  1040.     pElem->Offset = Address;
  1041.     AddStructElem(pInnermostNamedStruct->StructRec, pElem);
  1042.   }
  1043.   else
  1044.   {
  1045.     ShortInt OpSize = (pStructElem->OpSize < 0) ? 0 : pStructElem->OpSize;
  1046.  
  1047.     if (!ChkRange(Address, 0, 0xfff)
  1048.      || !ChkRange(pStructElem->BitPos, 0, (8 << OpSize) - 1))
  1049.       return;
  1050.  
  1051.     PushLocHandle(-1);
  1052.     EnterIntSymbol(pVarName, AssembleBitSymbol(pStructElem->BitPos, OpSize, Address), SegBData, False);
  1053.     PopLocHandle();
  1054.     /* TODO: MakeUseList? */
  1055.   }
  1056. }
  1057.  
  1058. /*!------------------------------------------------------------------------
  1059.  * \fn     ExpandS12ZBitfield(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
  1060.  * \brief  expands bit field definition when a structure is instantiated
  1061.  * \param  pVarName desired symbol name
  1062.  * \param  pStructElem element definition
  1063.  * \param  Base base address of instantiated structure
  1064.  * ------------------------------------------------------------------------ */
  1065.  
  1066. static void ExpandS12ZBitfield(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
  1067. {
  1068.   LongWord Address = Base + pStructElem->Offset;
  1069.  
  1070.   if (pInnermostNamedStruct)
  1071.   {
  1072.     PStructElem pElem = CloneStructElem(pVarName, pStructElem);
  1073.  
  1074.     if (!pElem)
  1075.       return;
  1076.     pElem->Offset = Address;
  1077.     AddStructElem(pInnermostNamedStruct->StructRec, pElem);
  1078.   }
  1079.   else
  1080.   {
  1081.     ShortInt OpSize = (pStructElem->OpSize < 0) ? 0 : pStructElem->OpSize;
  1082.  
  1083.     if (!ChkRange(Address, 0, 0xfff)
  1084.      || !ChkRange(pStructElem->BitPos, 0, (8 << OpSize) - 1)
  1085.      || !ChkRange(pStructElem->BitPos + pStructElem->BitWidthM1, 0, (8 << OpSize) - 1))
  1086.       return;
  1087.  
  1088.     PushLocHandle(-1);
  1089.     EnterIntSymbol(pVarName, AssembleBitfieldSymbol(pStructElem->BitPos, pStructElem->BitWidthM1 + 1, OpSize, Address), SegBData, False);
  1090.     PopLocHandle();
  1091.     /* TODO: MakeUseList? */
  1092.   }
  1093. }
  1094.  
  1095. /*--------------------------------------------------------------------------*/
  1096. /* Instruction Decoders */
  1097.  
  1098. static void DecodeFixed(Word Code)
  1099. {
  1100.   if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1101.   else if (ChkArgCnt(0, 0))
  1102.     PutCode(Code);
  1103. }
  1104.  
  1105. static Boolean DecodeBranchCore(int ArgIndex)
  1106. {
  1107.   Boolean OK;
  1108.   tSymbolFlags Flags;
  1109.   LongInt ShortDist, LongDist;
  1110.  
  1111.   /* manual says distance is relative to start of next instruction */
  1112.  
  1113.   ShortDist = EvalStrIntExpressionWithFlags(&ArgStr[ArgIndex], UInt24, &OK, &Flags) - (EProgCounter() + CodeLen + 1);
  1114.   if (!OK)
  1115.     return False;
  1116.   LongDist = ShortDist - 1;
  1117.  
  1118.   if (OpSize == eSymbolSizeUnknown)
  1119.     OpSize = ((ShortDist <= 63) && (ShortDist >= -64)) ? eSymbolSizeFloat32Bit : eSymbolSize32Bit;
  1120.   switch (OpSize)
  1121.   {
  1122.     case eSymbolSize32Bit:
  1123.       if (!mSymbolQuestionable(Flags) && !RangeCheck(LongDist, SInt15))
  1124.       {
  1125.         WrError(ErrNum_JmpDistTooBig);
  1126.         return False;
  1127.       }
  1128.       else
  1129.       {
  1130.         BAsmCode[CodeLen++] = 0x80 | ((LongDist >> 7) & 0x7f);
  1131.         BAsmCode[CodeLen++] = LongDist & 0xff;
  1132.       }
  1133.       break;
  1134.     case eSymbolSizeFloat32Bit:
  1135.       if (!mSymbolQuestionable(Flags) && !RangeCheck(ShortDist, SInt7))
  1136.       {
  1137.         WrError(ErrNum_JmpDistTooBig);
  1138.         return False;
  1139.       }
  1140.       else
  1141.       {
  1142.         BAsmCode[CodeLen++] = ShortDist & 0x7f;
  1143.       }
  1144.       break;
  1145.     default:
  1146.       WrStrErrorPos(ErrNum_InvOpSize, &AttrPart);
  1147.       return False;
  1148.   }
  1149.   return True;
  1150. }
  1151.  
  1152. static void DecodeBranch(Word Code)
  1153. {
  1154.   if (!ChkArgCnt(1, 1))
  1155.     return;
  1156.  
  1157.   PutCode(Code);
  1158.   if (!DecodeBranchCore(1))
  1159.     CodeLen = 0;
  1160. }
  1161.  
  1162. static void DecodeReg(Word Code)
  1163. {
  1164.   Byte Reg;
  1165.  
  1166.   if (ChkArgCnt(1, 1)
  1167.    && DecodeRegArg(1, &Reg, 0xff)
  1168.    && SetOpSize(RegSizes[Reg]))
  1169.     PutCode(Code | Reg);
  1170. }
  1171.  
  1172. static void DecodeTwoReg(Word Code)
  1173. {
  1174.   Byte SrcReg, DestReg;
  1175.  
  1176.   /* TODO: what is the operand order (source/dest)? The manual is
  1177.      unclear about this.  Assuming source is first argument, similar to TFR: */
  1178.  
  1179.   if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1180.   else if (ChkArgCnt(2, 2)
  1181.         && DecodeRegArg(2, &DestReg, 0xff)
  1182.         && DecodeRegArg(1, &SrcReg, 0xff))
  1183.   {
  1184.     PutCode(Code);
  1185.     BAsmCode[CodeLen++] = DestReg | (SrcReg << 4);
  1186.   }
  1187. }
  1188.  
  1189. static void DecodeRegMemImm(Word Code)
  1190. {
  1191.   Byte Reg;
  1192.   tAdrVals AdrVals;
  1193.  
  1194.   if (ChkArgCnt(2, 2)
  1195.    && DecodeRegArg(1, &Reg, 0xff)
  1196.    && SetOpSize(RegSizes[Reg])
  1197.    && DecodeAdr(2, MModeImm | MModeMemReg, &AdrVals))
  1198.   {
  1199.     if (AdrVals.Mode == AdrModeImm)
  1200.       PutCode(Code | Reg);
  1201.     else
  1202.     {
  1203.       PutCode((Code + 0x10) | Reg);
  1204.       BAsmCode[CodeLen++] = AdrVals.Arg;
  1205.     }
  1206.     AppendAdrVals(&AdrVals);
  1207.   }
  1208. }
  1209.  
  1210. static void DecodeSUB(Word Code)
  1211. {
  1212.   Byte Reg;
  1213.   tAdrVals AdrVals;
  1214.  
  1215.   if (ArgCnt == 3)
  1216.   {
  1217.     if (DecodeRegArg(1, &Reg, 1 << 6)
  1218.      && DecodeAdrRegArg(2, &Reg, 3)
  1219.      && DecodeAdrRegArg(3, &Reg, 1 << (1 - Reg)))
  1220.     {
  1221.       BAsmCode[CodeLen++] = 0xfe - Reg;
  1222.     }
  1223.   }
  1224.   else if (ChkArgCnt(2, 3)
  1225.    && DecodeRegArg(1, &Reg, 0xff)
  1226.    && SetOpSize(RegSizes[Reg])
  1227.    && DecodeAdr(2, MModeImm | MModeMemReg, &AdrVals))
  1228.   {
  1229.     if (AdrVals.Mode == AdrModeImm)
  1230.       PutCode(Code | Reg);
  1231.     else
  1232.     {
  1233.       PutCode((Code + 0x10) | Reg);
  1234.       BAsmCode[CodeLen++] = AdrVals.Arg;
  1235.     }
  1236.     AppendAdrVals(&AdrVals);
  1237.   }
  1238. }
  1239.  
  1240. static void DecodeCMP(Word Code)
  1241. {
  1242.   if (ChkArgCnt(2, 2))
  1243.   {
  1244.     Byte Reg;
  1245.     tAdrVals AdrVals;
  1246.  
  1247.     DecodeAdr(1, MModeReg | MModeAReg, &AdrVals);
  1248.     Reg = AdrVals.Arg;
  1249.     switch (AdrVals.Mode)
  1250.     {
  1251.       case AdrModeReg:
  1252.         if (SetOpSize(RegSizes[Reg])
  1253.          && DecodeAdr(2, MModeImm | MModeMemReg, &AdrVals))
  1254.         {
  1255.           if (AdrVals.Mode == AdrModeImm)
  1256.             PutCode(Code | Reg);
  1257.           else
  1258.           {
  1259.             PutCode((Code + 0x10) | Reg);
  1260.             BAsmCode[CodeLen++] = AdrVals.Arg;
  1261.           }
  1262.           AppendAdrVals(&AdrVals);
  1263.         }
  1264.         break;
  1265.       case AdrModeAReg:
  1266.         if (Reg == 3) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  1267.         else if (SetOpSize(eSymbolSize24Bit))
  1268.         {
  1269.           DecodeAdr(2, MModeImm | MModeMemReg | MModeAReg, &AdrVals);
  1270.           switch (AdrVals.Mode)
  1271.           {
  1272.             case AdrModeImm:
  1273.               PutCode((Reg == 2) ? 0x1b04 : (0xe8 | Reg));
  1274.               AppendAdrVals(&AdrVals);
  1275.               break;
  1276.             case AdrModeMemReg:
  1277.               PutCode((Reg == 2) ? 0x1b02 : (0xf8 | Reg));
  1278.               BAsmCode[CodeLen++] = AdrVals.Arg;
  1279.               AppendAdrVals(&AdrVals);
  1280.               break;
  1281.             case AdrModeAReg:
  1282.               if (Reg != 0) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  1283.               else if (AdrVals.Arg != 1) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  1284.               else
  1285.                 PutCode(0xfc);
  1286.               break;
  1287.             default:
  1288.               break;
  1289.           }
  1290.         }
  1291.         break;
  1292.       default:
  1293.         break;
  1294.     }
  1295.   }
  1296. }
  1297.  
  1298. static void DecodeImm8(Word Code)
  1299. {
  1300.   tAdrVals AdrVals;
  1301.  
  1302.   if (ChkArgCnt(1, 1) && SetOpSize(eSymbolSize8Bit) && DecodeAdr(1, MModeImm, &AdrVals))
  1303.   {
  1304.     PutCode(Code);
  1305.     AppendAdrVals(&AdrVals);
  1306.   }
  1307. }
  1308.  
  1309. static void DecodeShift(Word Code)
  1310. {
  1311.   if (ChkArgCnt(2,3))
  1312.   {
  1313.     tAdrVals CntAdrVals, OpAdrVals;
  1314.     tSymbolSize SaveOpSize;
  1315.     Boolean IsASL = (Code == 0xc0),
  1316.             IsASR = (Code == 0x80);
  1317.     Boolean ImmediateCnt, DestIsReg;
  1318.     Byte ImmCnt, SizeCode, OpReg, DestReg;
  1319.  
  1320.     /* force operand size to 5 bits for count */
  1321.  
  1322.     SaveOpSize = OpSize;
  1323.     OpSize = OpSizeShiftCount;
  1324.     if (!DecodeAdr(ArgCnt, MModeImm | MModeMemReg | MModeReg, &CntAdrVals))
  1325.       return;
  1326.     ImmediateCnt = IsImmediate(&CntAdrVals, OpSize, &ImmCnt);
  1327.     OpSize = SaveOpSize;
  1328.  
  1329.     /* source or source-and-dest operand */
  1330.  
  1331.     if (!DecodeAdr(ArgCnt - 1, MModeMemReg | MModeReg, &OpAdrVals))
  1332.       return;
  1333.  
  1334.     /* operand size not yet set - then set from source */
  1335.  
  1336.     if (IsReg(&OpAdrVals, &OpReg))
  1337.       SetOpSize(RegSizes[OpReg]);
  1338.     if (OpSize < 0)
  1339.     {
  1340.       WrError(ErrNum_UndefOpSizes);
  1341.       return;
  1342.     }
  1343.     else if (!SizeCode2(OpSize, &SizeCode))
  1344.     {
  1345.       WrError(ErrNum_InvOpSize);
  1346.       return;
  1347.     }
  1348.  
  1349.     /* for three args, destination is always a register */
  1350.  
  1351.     if (ArgCnt == 3)
  1352.     {
  1353.       /* dest reg does not set operand size - opsize is from src
  1354.          operand which may be memory */
  1355.  
  1356.       if (!DecodeRegArg(1, &DestReg, 0xff))
  1357.         return;
  1358.       DestIsReg = True;
  1359.     }
  1360.     else
  1361.       DestIsReg = IsReg(&OpAdrVals, &DestReg);
  1362.  
  1363.     /* REG-REG-OPR1/2/3 only allowed with ASL: convert to (REG-)OPR1/2/3-OPR1/2/3 for other instructions,
  1364.        unless count is immediate: */
  1365.  
  1366.     if (!IsASL && DestIsReg && (OpAdrVals.Mode == AdrModeReg) && !ImmediateCnt && (CntAdrVals.Mode == AdrModeMemReg))
  1367.     {
  1368.       OpAdrVals.Mode = AdrModeMemReg;
  1369.       OpAdrVals.Arg |= 0xb8;
  1370.     }
  1371.  
  1372.     /* REG-REG */
  1373.  
  1374.     if (DestIsReg && (OpAdrVals.Mode == AdrModeReg) && (CntAdrVals.Mode == AdrModeReg))
  1375.     {
  1376.       BAsmCode[CodeLen++] = 0x10 | DestReg;
  1377.       BAsmCode[CodeLen++] = Code | (IsASL ? 0x10 : 0x20) | OpAdrVals.Arg;
  1378.       BAsmCode[CodeLen++] = 0xb8 | CntAdrVals.Arg;
  1379.     }
  1380.  
  1381.     /* REG-IMM with n=1..2 */
  1382.  
  1383.     else if (DestIsReg && (OpAdrVals.Mode == AdrModeReg) && ImmediateCnt && (ImmCnt >= 1) && (ImmCnt <= 2))
  1384.     {
  1385.       BAsmCode[CodeLen++] = (IsASR ? 0x00 : 0x10) | DestReg;
  1386.       BAsmCode[CodeLen++] = Code | (IsASR ? 0x10 : 0x00) | ((ImmCnt - 1) << 3) | OpAdrVals.Arg;
  1387.     }
  1388.  
  1389.     /* REG-IMM with arbitrary n */
  1390.  
  1391.     else if (DestIsReg && (OpAdrVals.Mode == AdrModeReg) && ImmediateCnt)
  1392.     {
  1393.       BAsmCode[CodeLen++] = 0x10 | DestReg;
  1394.       BAsmCode[CodeLen++] = Code | (IsASL ? 0x00 : 0x10) | ((ImmCnt & 1) << 3) | OpAdrVals.Arg;
  1395.       BAsmCode[CodeLen++] = 0x70 | ((ImmCnt >> 1) & 7);
  1396.     }
  1397.  
  1398.     /* REG-OPR1/2/3 - ASL only */
  1399.  
  1400.     else if (IsASL && DestIsReg && (OpAdrVals.Mode == AdrModeReg) && (CntAdrVals.Mode == AdrModeMemReg))
  1401.     {
  1402.       BAsmCode[CodeLen++] = 0x10 | DestReg;
  1403.       BAsmCode[CodeLen++] = Code | (CntAdrVals.ShiftLSB << 3) | OpAdrVals.Arg;
  1404.       BAsmCode[CodeLen++] = CntAdrVals.Arg;
  1405.       AppendAdrVals(&CntAdrVals);
  1406.     }
  1407.  
  1408.     /* (REG-)OPR1/2/3-IMM with n=1..2 */
  1409.  
  1410.     else if (DestIsReg && ImmediateCnt && (ImmCnt >= 1) && (ImmCnt <= 2))
  1411.     {
  1412.       BAsmCode[CodeLen++] = 0x10 | DestReg;
  1413.       BAsmCode[CodeLen++] = Code | 0x20 | ((ImmCnt - 1) << 3) | SizeCode;
  1414.       BAsmCode[CodeLen++] = OpAdrVals.Arg;
  1415.       AppendAdrVals(&OpAdrVals);
  1416.     }
  1417.  
  1418.     /* (REG-)OPR1/2/3-IMM with arbitrary n */
  1419.  
  1420.     else if (DestIsReg && ImmediateCnt && (OpAdrVals.Mode == AdrModeMemReg))
  1421.     {
  1422.       BAsmCode[CodeLen++] = 0x10 | DestReg;
  1423.       BAsmCode[CodeLen++] = Code | 0x30 | ((ImmCnt & 1) << 3) | SizeCode;
  1424.       BAsmCode[CodeLen++] = OpAdrVals.Arg;
  1425.       AppendAdrVals(&OpAdrVals);
  1426.       BAsmCode[CodeLen++] = 0x70 | ((ImmCnt >> 1) & 0x0f);
  1427.     }
  1428.  
  1429.     /* (REG-)OPR1/2/3-OPR1/2/3 */
  1430.  
  1431.     else if (DestIsReg && (OpAdrVals.Mode == AdrModeMemReg) && (CntAdrVals.Mode == AdrModeMemReg))
  1432.     {
  1433.       BAsmCode[CodeLen++] = 0x10 | DestReg;
  1434.       BAsmCode[CodeLen++] = Code | 0x30 | (CntAdrVals.ShiftLSB << 3) | SizeCode;
  1435.       BAsmCode[CodeLen++] = OpAdrVals.Arg;
  1436.       AppendAdrVals(&OpAdrVals);
  1437.       BAsmCode[CodeLen++] = CntAdrVals.Arg;
  1438.       AppendAdrVals(&CntAdrVals);
  1439.     }
  1440.  
  1441.     /* (src-)OPR/1/2/3-IMM (n=1..2) */
  1442.  
  1443.     else if ((OpAdrVals.Mode == AdrModeMemReg) && ImmediateCnt && (ImmCnt >= 1) && (ImmCnt <= 2))
  1444.     {
  1445.       BAsmCode[CodeLen++] = 0x10;
  1446.       BAsmCode[CodeLen++] = Code | 0x34 | ((ImmCnt - 1) << 3) | SizeCode;
  1447.       BAsmCode[CodeLen++] = OpAdrVals.Arg;
  1448.       AppendAdrVals(&OpAdrVals);
  1449.     }
  1450.  
  1451.     else
  1452.       WrError(ErrNum_InvAddrMode);
  1453.   }
  1454. }
  1455.  
  1456. static void DecodeBit(Word Code)
  1457. {
  1458.   tSymbolSize SaveOpSize;
  1459.   tAdrVals PosAdrVals, OpAdrVals;
  1460.   Byte ImmPos, ImmWidth, SizeCode, OpReg;
  1461.   Boolean ImmediatePos;
  1462.  
  1463.   if (!ChkArgCnt(1, 2))
  1464.     return;
  1465.  
  1466.   /* bit operand: */
  1467.  
  1468.   if (1 == ArgCnt)
  1469.   {
  1470.     LongWord BitArg;
  1471.     tSymbolSize ThisOpSize;
  1472.     Word Address;
  1473.  
  1474.     if (DecodeBitArg(&BitArg, 1, 1, OpSize)
  1475.      && DissectBitSymbol(BitArg, &Address, &ImmPos, &ImmWidth, &ThisOpSize)
  1476.      && SetOpSize(ThisOpSize))
  1477.     {
  1478.       /* TODO: warn if ImmWidth != 1 */
  1479.       if (!SizeCode2(OpSize, &SizeCode) || (SizeCode == 2))
  1480.       {
  1481.         WrError(ErrNum_InvOpSize);
  1482.         return;
  1483.       }
  1484.       ImmediatePos = True;
  1485.       OpAdrVals.Mode = AdrModeMemReg;
  1486.       OpAdrVals.Arg = Hi(Address);
  1487.       OpAdrVals.Vals[0] = Lo(Address);
  1488.       OpAdrVals.ValCnt = 1;
  1489.     }
  1490.     else
  1491.       return;
  1492.     OpReg = 0;
  1493.   }
  1494.  
  1495.   /* other operand */
  1496.  
  1497.   else
  1498.   {
  1499.     if (!DecodeAdr(1, MModeMemReg | MModeReg, &OpAdrVals))
  1500.       return;
  1501.  
  1502.     /* operand size not yet set - then set from source */
  1503.  
  1504.     if (IsReg(&OpAdrVals, &OpReg))
  1505.       SetOpSize(RegSizes[OpReg]);
  1506.     if (OpSize < 0)
  1507.     {
  1508.       WrError(ErrNum_UndefOpSizes);
  1509.       return;
  1510.     }
  1511.  
  1512.     else if (!SizeCode2(OpSize, &SizeCode) || (SizeCode == 2))
  1513.     {
  1514.       WrError(ErrNum_InvOpSize);
  1515.       return;
  1516.     }
  1517.  
  1518.     /* force operand size to 3/4/5 bits for bit position */
  1519.  
  1520.     SaveOpSize = OpSize;
  1521.     OpSize = OpSizeBitPos8 + OpSize;
  1522.     if (!DecodeAdr(2, MModeImm | MModeReg, &PosAdrVals))
  1523.       return;
  1524.     ImmediatePos = IsImmediate(&PosAdrVals, OpSize, &ImmPos);
  1525.     OpSize = SaveOpSize;
  1526.   }
  1527.  
  1528.   switch (OpAdrVals.Mode)
  1529.   {
  1530.     case AdrModeReg:
  1531.       BAsmCode[CodeLen++] = Code;
  1532.       if (ImmediatePos)
  1533.         BAsmCode[CodeLen++] = (ImmPos << 3) | OpReg;
  1534.       else
  1535.       {
  1536.         BAsmCode[CodeLen++] = 0x81 | (PosAdrVals.Arg << 4);
  1537.         BAsmCode[CodeLen++] = 0xb8 | OpReg;
  1538.       }
  1539.       break;
  1540.     case AdrModeMemReg:
  1541.       BAsmCode[CodeLen++] = Code;
  1542.       if (ImmediatePos)
  1543.       {
  1544.         BAsmCode[CodeLen] = 0x80 | ((ImmPos & 7) << 4);
  1545.         if (OpSize >= eSymbolSize16Bit)
  1546.           BAsmCode[CodeLen] |= (1 << SizeCode) | ((ImmPos >> 3) & SizeCode);
  1547.         CodeLen++;
  1548.       }
  1549.       else
  1550.         BAsmCode[CodeLen++] = 0x81 | (PosAdrVals.Arg << 4) | (SizeCode << 2);
  1551.       BAsmCode[CodeLen++] = OpAdrVals.Arg;
  1552.       AppendAdrVals(&OpAdrVals);
  1553.       break;
  1554.     default:
  1555.       break;
  1556.   }
  1557. }
  1558.  
  1559. static void DecodeBitField(Word Code)
  1560. {
  1561.   if (!ChkArgCnt(2, 3))
  1562.     return;
  1563.  
  1564.   /* if two arguments, bit field is symbolic and is
  1565.      - the destination (first arg) for BFINS
  1566.      - the source (second arg) for BFEXT */
  1567.  
  1568.   if (2 == ArgCnt)
  1569.   {
  1570.     LongWord BitfieldArg;
  1571.     Byte Reg, ImmPos, ImmWidth, SizeCode;
  1572.     Word FieldSpec, Address;
  1573.     tSymbolSize ThisOpSize;
  1574.     int RegArg = (Code == 0x80) ? 2 : 1;
  1575.  
  1576.     if (DecodeRegArg(RegArg, &Reg, 0xff)
  1577.      && DecodeBitfieldArg(&BitfieldArg, 3 - RegArg, 3 - RegArg, OpSize)
  1578.      && DissectBitSymbol(BitfieldArg, &Address, &ImmPos, &ImmWidth, &ThisOpSize)
  1579.      && SetOpSize(ThisOpSize)
  1580.      && SizeCode2(OpSize, &SizeCode))
  1581.     {
  1582.       FieldSpec = ImmPos | ((ImmWidth < 32) ? ((Word)ImmWidth << 5) : 0);
  1583.       BAsmCode[CodeLen++] = 0x1b;
  1584.       BAsmCode[CodeLen++] = 0x08 | Reg;
  1585.       BAsmCode[CodeLen++] = (Code ? 0xf0: 0x60) | (SizeCode << 2) | Hi(FieldSpec);
  1586.       BAsmCode[CodeLen++] = Lo(FieldSpec);
  1587.       BAsmCode[CodeLen++] = Hi(Address);
  1588.       BAsmCode[CodeLen++] = Lo(Address);
  1589.     }
  1590.   }
  1591.   else
  1592.   {
  1593.     Byte ParamReg, SizeCode;
  1594.     Word ParamImm;
  1595.     tAdrVals SrcAdrVals, DestAdrVals;
  1596.  
  1597.     if (*ArgStr[3].str.p_str == '#')
  1598.     {
  1599.       tStrComp Field;
  1600.  
  1601.       StrCompRefRight(&Field, &ArgStr[3], 1);
  1602.       if (!DecodeImmBitField(&Field, &ParamImm))
  1603.         return;
  1604.       ParamReg = 16; /* immediate flag */
  1605.     }
  1606.  
  1607.     /* only D2...D5 allowed as parameter */
  1608.  
  1609.     else if (!DecodeRegStr(ArgStr[3].str.p_str, &ParamReg) || (ParamReg >= 4))
  1610.     {
  1611.       WrStrErrorPos(ErrNum_InvReg, &ArgStr[3]);
  1612.       return;
  1613.     }
  1614.  
  1615.     DecodeAdr(2, MModeReg | MModeImm | MModeMemReg, &SrcAdrVals);
  1616.     switch (SrcAdrVals.Mode)
  1617.     {
  1618.       case AdrModeReg:
  1619.         DecodeAdr(1, MModeReg | MModeMemReg, &DestAdrVals);
  1620.         switch (DestAdrVals.Mode)
  1621.         {
  1622.           case AdrModeReg:
  1623.             BAsmCode[CodeLen++] = 0x1b;
  1624.             BAsmCode[CodeLen++] = 0x08 | DestAdrVals.Arg;
  1625.             if (16 == ParamReg)
  1626.             {
  1627.               BAsmCode[CodeLen++] = Code | 0x20 | (SrcAdrVals.Arg << 2) | Hi(ParamImm);
  1628.               BAsmCode[CodeLen++] = Lo(ParamImm);
  1629.             }
  1630.             else
  1631.               BAsmCode[CodeLen++] = Code | (SrcAdrVals.Arg << 2) | ParamReg;
  1632.             break;
  1633.           case AdrModeMemReg:
  1634.             if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1635.             else if (!SizeCode2(OpSize, &SizeCode)) WrError(ErrNum_InvOpSize);
  1636.             else
  1637.             {
  1638.               BAsmCode[CodeLen++] = 0x1b;
  1639.               BAsmCode[CodeLen++] = 0x08 | SrcAdrVals.Arg;
  1640.               if (16 == ParamReg)
  1641.               {
  1642.                 BAsmCode[CodeLen++] = Code | 0x70 | (SizeCode << 2) | Hi(ParamImm);
  1643.                 BAsmCode[CodeLen++] = Lo(ParamImm);
  1644.               }
  1645.               else
  1646.                 BAsmCode[CodeLen++] = Code | 0x50 | (SizeCode << 2) | ParamReg;
  1647.               BAsmCode[CodeLen++] = DestAdrVals.Arg;
  1648.               AppendAdrVals(&DestAdrVals);
  1649.             }
  1650.             break;
  1651.           default:
  1652.             break;
  1653.         }
  1654.         break;
  1655.       case AdrModeMemReg:
  1656.         DecodeAdr(1, MModeReg, &DestAdrVals);
  1657.         switch (DestAdrVals.Mode)
  1658.         {
  1659.           case AdrModeReg:
  1660.             if (OpSize  == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1661.             else if (!SizeCode2(OpSize, &SizeCode)) WrError(ErrNum_InvOpSize);
  1662.             else
  1663.             {
  1664.               BAsmCode[CodeLen++] = 0x1b;
  1665.               BAsmCode[CodeLen++] = 0x08 | DestAdrVals.Arg;
  1666.               if (16 == ParamReg)
  1667.               {
  1668.                 BAsmCode[CodeLen++] = Code | 0x60 | (SizeCode << 2) | Hi(ParamImm);
  1669.                 BAsmCode[CodeLen++] = Lo(ParamImm);
  1670.               }
  1671.               else
  1672.                 BAsmCode[CodeLen++] = Code | 0x40 | (SizeCode << 2) | ParamReg;
  1673.               BAsmCode[CodeLen++] = SrcAdrVals.Arg;
  1674.               AppendAdrVals(&SrcAdrVals);
  1675.             }
  1676.             break;
  1677.           default:
  1678.             break;
  1679.         }
  1680.         break;
  1681.       case AdrModeImm: /* immediate only allowed for short immediate in MemReg op */
  1682.         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  1683.         break;
  1684.       default:
  1685.         break;
  1686.     }
  1687.   }
  1688. }
  1689.  
  1690. static void DecodeBitRel(Word Code)
  1691. {
  1692.   if (!ChkArgCnt(3, 3))
  1693.     return;
  1694.  
  1695.   ArgCnt--;
  1696.   DecodeBit(Code);
  1697.   if (!CodeLen)
  1698.     return;
  1699.  
  1700.   /* operand size attribute is consumed by bit operand */
  1701.  
  1702.   OpSize = eSymbolSizeUnknown;
  1703.   if (!DecodeBranchCore(3))
  1704.     CodeLen = 0;
  1705. }
  1706.  
  1707. static void DecodeCLR(Word Code)
  1708. {
  1709.   tAdrVals AdrVals;
  1710.  
  1711.   UNUSED(Code);
  1712.  
  1713.   if (ChkArgCnt(1, 1) && DecodeAdr(1, MModeReg | MModeAReg | MModeMemReg, &AdrVals))
  1714.   {
  1715.     switch (AdrVals.Mode)
  1716.     {
  1717.       case AdrModeReg:
  1718.         if (SetOpSize(RegSizes[AdrVals.Arg]))
  1719.           PutCode(0x0038 | AdrVals.Arg);
  1720.         break;
  1721.       case AdrModeAReg:
  1722.         if (!SetOpSize(eSymbolSize24Bit));
  1723.         else if (AdrVals.Arg > 1) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  1724.         else
  1725.           PutCode(0x009a | AdrVals.Arg);
  1726.         break;
  1727.       case AdrModeMemReg:
  1728.       {
  1729.         Byte SizeCode;
  1730.  
  1731.         if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1732.         else if (!SizeCode2(OpSize, &SizeCode)) WrError(ErrNum_InvOpSize);
  1733.         else
  1734.         {
  1735.           BAsmCode[CodeLen++] = 0xbc | SizeCode;
  1736.           BAsmCode[CodeLen++] = AdrVals.Arg;
  1737.           AppendAdrVals(&AdrVals);
  1738.         }
  1739.         break;
  1740.       }
  1741.       default:
  1742.         break;
  1743.     }
  1744.   }
  1745. }
  1746.  
  1747. static void DecodeCOM_NEG(Word Code)
  1748. {
  1749.   tAdrVals AdrVals;
  1750.   Byte OpReg, SizeCode;
  1751.  
  1752.   if (!ChkArgCnt(1, 1))
  1753.     return;
  1754.   DecodeAdr(1, MModeMemReg, &AdrVals);
  1755.  
  1756.   /* operand size not yet set - then set from (register) op */
  1757.  
  1758.   if (IsReg(&AdrVals, &OpReg))
  1759.   {
  1760.     if (!SetOpSize(RegSizes[OpReg]))
  1761.       return;
  1762.   }
  1763.   if (OpSize == eSymbolSizeUnknown)
  1764.   {
  1765.     WrError(ErrNum_UndefOpSizes);
  1766.     return;
  1767.   }
  1768.   if (!SizeCode2(OpSize, &SizeCode) || (OpSize == eSymbolSize24Bit))
  1769.   {
  1770.     WrError(ErrNum_InvOpSize);
  1771.     return;
  1772.   }
  1773.   PutCode(Code | SizeCode);
  1774.   BAsmCode[CodeLen++] = AdrVals.Arg;
  1775.   AppendAdrVals(&AdrVals);
  1776. }
  1777.  
  1778. static void DecodeDBcc(Word Code)
  1779. {
  1780.   tAdrVals AdrVals;
  1781.   Byte OpReg, SizeCode;
  1782.  
  1783.   if (!ChkArgCnt(2, 2))
  1784.     return;
  1785.   DecodeAdr(1, MModeReg | MModeAReg | MModeMemReg, &AdrVals);
  1786.  
  1787.   if (IsReg(&AdrVals, &OpReg))
  1788.   {
  1789.     if (!SetOpSize(RegSizes[OpReg]))
  1790.       return;
  1791.   }
  1792.   else if (AdrVals.Mode == AdrModeAReg)
  1793.   {
  1794.     if (!SetOpSize(eSymbolSize24Bit))
  1795.       return;
  1796.   }
  1797.   if (OpSize == eSymbolSizeUnknown)
  1798.   {
  1799.     WrError(ErrNum_UndefOpSizes);
  1800.     return;
  1801.   }
  1802.   if (!SizeCode2(OpSize, &SizeCode))
  1803.   {
  1804.     WrError(ErrNum_InvOpSize);
  1805.     return;
  1806.   }
  1807.   switch (AdrVals.Mode)
  1808.   {
  1809.     case AdrModeReg:
  1810.       PutCode(Code | AdrVals.Arg);
  1811.       break;
  1812.     case AdrModeAReg:
  1813.       if (AdrVals.Arg > 1) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  1814.       else
  1815.         PutCode(Code | 0x0008 | AdrVals.Arg);
  1816.       break;
  1817.     case AdrModeMemReg:
  1818.       PutCode(Code | 0x000c | SizeCode);
  1819.       BAsmCode[CodeLen++] = AdrVals.Arg;
  1820.       AppendAdrVals(&AdrVals);
  1821.       break;
  1822.     default:
  1823.       break;
  1824.   }
  1825.  
  1826.   if (CodeLen > 0)
  1827.   {
  1828.     /* operand size attribute consumed by operand */
  1829.  
  1830.     OpSize = eSymbolSizeUnknown;
  1831.  
  1832.     if (!DecodeBranchCore(2))
  1833.       CodeLen = 0;
  1834.   }
  1835. }
  1836.  
  1837. static void DecodeINC_DEC(Word Code)
  1838. {
  1839.   tAdrVals AdrVals;
  1840.  
  1841.   if (ChkArgCnt(1, 1) && DecodeAdr(1, MModeReg | MModeMemReg, &AdrVals))
  1842.   {
  1843.     switch (AdrVals.Mode)
  1844.     {
  1845.       case AdrModeReg:
  1846.         if (SetOpSize(RegSizes[AdrVals.Arg]))
  1847.           PutCode(Code + AdrVals.Arg);
  1848.         break;
  1849.       case AdrModeMemReg:
  1850.       {
  1851.         Byte SizeCode;
  1852.  
  1853.         if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1854.         else if (!SizeCode2(OpSize, &SizeCode) || (OpSize == eSymbolSize24Bit)) WrError(ErrNum_UndefOpSizes);
  1855.         else
  1856.         {
  1857.           BAsmCode[CodeLen++] = (Code + 0x6c) | SizeCode;
  1858.           BAsmCode[CodeLen++] = AdrVals.Arg;
  1859.           AppendAdrVals(&AdrVals);
  1860.         }
  1861.         break;
  1862.       }
  1863.       default:
  1864.         break;
  1865.     }
  1866.   }
  1867. }
  1868.  
  1869. static void DecodeDIV_MOD(Word Code)
  1870. {
  1871.   tAdrVals DividentAdrVals, DivisorAdrVals;
  1872.   Byte DividentSizeCode, DivisorSizeCode, DestReg, DivisorReg;
  1873.   Word EffCode, LoCode;
  1874.  
  1875.   EffCode = Hi(Code) | ((Lo(Code) & 0x01) ? 0x1b00 : 0x0000);
  1876.   LoCode = Lo(Code) & 0x80;
  1877.  
  1878.   /* destination is always a register */
  1879.  
  1880.   if (!ChkArgCnt(3, 3) || !DecodeRegArg(1, &DestReg, 0xff))
  1881.     return;
  1882.  
  1883.   DecodeAdr(2, MModeImm | MModeReg | MModeMemReg, &DividentAdrVals);
  1884.   switch (DividentAdrVals.Mode)
  1885.   {
  1886.     case AdrModeReg:
  1887.       DecodeAdr(3, MModeImm | MModeReg | MModeMemReg, &DivisorAdrVals);
  1888.       switch (DivisorAdrVals.Mode)
  1889.       {
  1890.         case AdrModeReg:
  1891.           PutCode(EffCode | DestReg);
  1892.           BAsmCode[CodeLen++] = LoCode | (DividentAdrVals.Arg << 3) | DivisorAdrVals.Arg;
  1893.           break;
  1894.         case AdrModeImm:
  1895.           if (!SizeCode2(OpSize, &DivisorSizeCode) || (OpSize == eSymbolSize24Bit)) WrError(ErrNum_UndefOpSizes);
  1896.           else
  1897.           {
  1898.             PutCode(EffCode | DestReg);
  1899.             BAsmCode[CodeLen++] = LoCode | 0x44 | (DividentAdrVals.Arg << 3) | DivisorSizeCode;
  1900.             AppendAdrVals(&DivisorAdrVals);
  1901.           }
  1902.           break;
  1903.         case AdrModeMemReg:
  1904.           if (!SizeCode2(OpSize, &DivisorSizeCode) || (OpSize == eSymbolSize24Bit)) WrError(ErrNum_UndefOpSizes);
  1905.           else
  1906.           {
  1907.             PutCode(EffCode | DestReg);
  1908.             BAsmCode[CodeLen++] = LoCode | 0x40 | (DividentAdrVals.Arg << 3) | DivisorSizeCode;
  1909.             BAsmCode[CodeLen++] = DivisorAdrVals.Arg;
  1910.             AppendAdrVals(&DivisorAdrVals);
  1911.           }
  1912.           break;
  1913.         default:
  1914.           break;
  1915.       }
  1916.       break;
  1917.     case AdrModeMemReg:
  1918.       /* divident==register is filtered out before, so divident size cannot be set from register */
  1919.       if (!SizeCode2(OpSize, &DividentSizeCode) || (OpSize == eSymbolSize24Bit)) WrError(ErrNum_UndefOpSizes);
  1920.       else
  1921.       {
  1922.         OpSize = OpSize2;
  1923.         DecodeAdr(3, MModeImm | MModeMemReg, &DivisorAdrVals);
  1924.         switch (DivisorAdrVals.Mode)
  1925.         {
  1926.           case AdrModeMemReg:
  1927.             if ((OpSize == eSymbolSizeUnknown) && IsReg(&DivisorAdrVals, &DivisorReg))
  1928.               SetOpSize(RegSizes[DivisorReg]);
  1929.             if (!SizeCode2(OpSize, &DivisorSizeCode) || (OpSize == eSymbolSize24Bit)) WrError(ErrNum_UndefOpSizes);
  1930.             else
  1931.             {
  1932.               PutCode(EffCode | DestReg);
  1933.               BAsmCode[CodeLen++] = LoCode | 0x42 | (DividentSizeCode << 4) | (DivisorSizeCode << 2);
  1934.               BAsmCode[CodeLen++] = DividentAdrVals.Arg;
  1935.               AppendAdrVals(&DividentAdrVals);
  1936.               BAsmCode[CodeLen++] = DivisorAdrVals.Arg;
  1937.               AppendAdrVals(&DivisorAdrVals);
  1938.             }
  1939.             break;
  1940.           case AdrModeImm: /* was only allowed for short imm in MemReg */
  1941.             WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[3]);
  1942.             break;
  1943.           default:
  1944.             break;
  1945.         }
  1946.       }
  1947.       break;
  1948.     case AdrModeImm: /* was only allowed for short imm in MemReg */
  1949.       WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  1950.       break;
  1951.     default:
  1952.       break;
  1953.   }
  1954. }
  1955.  
  1956. static void DecodeEXG_TFR(Word Code)
  1957. {
  1958.   Byte SrcReg, DestReg;
  1959.  
  1960.   if (ChkArgCnt(2, 2)
  1961.    && DecodeGenRegArg(1, &SrcReg)
  1962.    && DecodeGenRegArg(2, &DestReg))
  1963.   {
  1964.     if ((OpSizeByteLen(RegSizes[SrcReg]) >= OpSizeByteLen(RegSizes[DestReg])) && Hi(Code))
  1965.       WrError(ErrNum_SrcLEThanDest);
  1966.     BAsmCode[CodeLen++] = Lo(Code);
  1967.     BAsmCode[CodeLen++] = (SrcReg << 4) | DestReg;
  1968.   }
  1969. }
  1970.  
  1971. static void DecodeJMP_JSR(Word Code)
  1972. {
  1973.   tAdrVals AdrVals;
  1974.  
  1975.   if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1976.   else if (ChkArgCnt(1, 1) && DecodeAdr(1, MModeMemReg, &AdrVals))
  1977.   {
  1978.     Byte Dummy;
  1979.  
  1980.     if (IsReg(&AdrVals, &Dummy)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  1981.     else
  1982.     {
  1983.       if (AdrVals.Arg == 0xfa)
  1984.         PutCode(Code | 0x10);
  1985.       else
  1986.       {
  1987.         PutCode(Code);
  1988.         BAsmCode[CodeLen++] = AdrVals.Arg;
  1989.       }
  1990.       AppendAdrVals(&AdrVals);
  1991.     }
  1992.   }
  1993. }
  1994.  
  1995. static void DecodeLD_ST(Word Code)
  1996. {
  1997.   tAdrVals SrcAdrVals, DestAdrVals;
  1998.  
  1999.   if (ChkArgCnt(2, 2) && DecodeAdr(1, MModeReg | MModeAReg, &DestAdrVals))
  2000.   {
  2001.     switch (DestAdrVals.Mode)
  2002.     {
  2003.       case AdrModeReg:
  2004.         if (!SetOpSize(RegSizes[DestAdrVals.Arg]))
  2005.           return;
  2006.         DecodeAdr(2, (Code ? 0 : MModeImm) | MModeMemReg, &SrcAdrVals);
  2007.         switch (SrcAdrVals.Mode)
  2008.         {
  2009.           case AdrModeMemReg:
  2010.           {
  2011.             Byte ImmVal;
  2012.  
  2013.             if ((OpSize == eSymbolSize8Bit) && IsImmediate(&SrcAdrVals, OpSize, &ImmVal)) /* same instr length for byte, but what people expect? */
  2014.             {
  2015.               ChangeImmediate(&SrcAdrVals, OpSize, ImmVal);
  2016.               goto immediate;
  2017.             }
  2018.             if (SrcAdrVals.Arg == 0xfa)
  2019.               BAsmCode[CodeLen++] = (0xb0 + Code) | DestAdrVals.Arg;
  2020.             else
  2021.             {
  2022.               BAsmCode[CodeLen++] = (0xa0 + Code) | DestAdrVals.Arg;
  2023.               BAsmCode[CodeLen++] = SrcAdrVals.Arg;
  2024.             }
  2025.             AppendAdrVals(&SrcAdrVals);
  2026.             break;
  2027.           }
  2028.           case AdrModeImm:
  2029.           immediate:
  2030.             BAsmCode[CodeLen++] = 0x90 | DestAdrVals.Arg;
  2031.             AppendAdrVals(&SrcAdrVals);
  2032.             break;
  2033.           default:
  2034.             break;
  2035.         }
  2036.         break;
  2037.       case AdrModeAReg:
  2038.         if (DestAdrVals.Arg > 2)
  2039.         {
  2040.           WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  2041.         }
  2042.         if (!SetOpSize(eSymbolSize24Bit))
  2043.           return;
  2044.         DecodeAdr(2, (Code ? 0 : MModeImm) | MModeMemReg, &SrcAdrVals);
  2045.         switch (SrcAdrVals.Mode)
  2046.         {
  2047.           case AdrModeMemReg:
  2048.             if ((DestAdrVals.Arg < 2) && (SrcAdrVals.Arg == 0xfa))
  2049.               BAsmCode[CodeLen++] = (0xb8 + Code) | DestAdrVals.Arg;
  2050.             else if (2 == DestAdrVals.Arg)
  2051.             {
  2052.               BAsmCode[CodeLen++] = 0x1b;
  2053.               BAsmCode[CodeLen++] = 0x00 + !!Code;
  2054.               BAsmCode[CodeLen++] = SrcAdrVals.Arg;
  2055.             }
  2056.             else
  2057.             {
  2058.               BAsmCode[CodeLen++] = (0xa8 + Code) | DestAdrVals.Arg;
  2059.               BAsmCode[CodeLen++] = SrcAdrVals.Arg;
  2060.             }
  2061.             AppendAdrVals(&SrcAdrVals);
  2062.             break;
  2063.           case AdrModeImm:
  2064.             /* SrcAdrVals.Cnt must be 3 */
  2065.             if ((DestAdrVals.Arg < 2) && (SrcAdrVals.Vals[0] < 0x04))
  2066.             {
  2067.               BAsmCode[CodeLen++] = 0xca | DestAdrVals.Arg | (SrcAdrVals.Vals[0] << 4);
  2068.               BAsmCode[CodeLen++] = SrcAdrVals.Vals[1];
  2069.               BAsmCode[CodeLen++] = SrcAdrVals.Vals[2];
  2070.             }
  2071.             else
  2072.             {
  2073.               PutCode((DestAdrVals.Arg == 2) ? 0x1b03 : (0x98 | DestAdrVals.Arg));
  2074.               AppendAdrVals(&SrcAdrVals);
  2075.             }
  2076.             break;
  2077.           default:
  2078.             break;
  2079.         }
  2080.         break;
  2081.       default:
  2082.         break;
  2083.     }
  2084.   }
  2085. }
  2086.  
  2087. static void DecodeLEA(Word Code)
  2088. {
  2089.   tAdrVals DestAdrVals, SrcAdrVals;
  2090.   Byte Reg;
  2091.  
  2092.   UNUSED(Code);
  2093.  
  2094.   if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  2095.   else if (ChkArgCnt(2, 2) && DecodeAdr(1, MModeReg | MModeAReg, &DestAdrVals))
  2096.   {
  2097.     switch (DestAdrVals.Mode)
  2098.     {
  2099.       case AdrModeReg:
  2100.         if (DestAdrVals.Arg < 6) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  2101.         else if (DecodeAdr(2, MModeMemReg, &SrcAdrVals))
  2102.         {
  2103.           if (IsReg(&SrcAdrVals, &Reg)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2104.           else
  2105.           {
  2106.             BAsmCode[CodeLen++] = 0x00 | DestAdrVals.Arg;
  2107.             BAsmCode[CodeLen++] = SrcAdrVals.Arg;
  2108.             AppendAdrVals(&SrcAdrVals);
  2109.           }
  2110.         }
  2111.         break;
  2112.       case AdrModeAReg:
  2113.         if (DestAdrVals.Arg > 2) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  2114.         else if (DecodeAdr(2, MModeMemReg, &SrcAdrVals))
  2115.         {
  2116.           if (IsReg(&SrcAdrVals, &Reg)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2117.           else
  2118.           {
  2119.             /* XYS,(i8,XYS) */
  2120.  
  2121.             if (((SrcAdrVals.Arg & 0xce) == 0xc0) /* ...,(XYS,i9) */
  2122.              && ((SrcAdrVals.Arg & 0x01) == ((SrcAdrVals.Vals[0] >> 7) & 1)) /* i9 is i8 */
  2123.              && (DestAdrVals.Arg == ((SrcAdrVals.Arg >> 4) & 3))) /* destreg==srcreg */
  2124.             {
  2125.               BAsmCode[CodeLen++] = 0x18 | DestAdrVals.Arg;
  2126.               BAsmCode[CodeLen++] = SrcAdrVals.Vals[0];
  2127.             }
  2128.             else
  2129.             {
  2130.               BAsmCode[CodeLen++] = 0x08 | DestAdrVals.Arg;
  2131.               BAsmCode[CodeLen++] = SrcAdrVals.Arg;
  2132.               AppendAdrVals(&SrcAdrVals);
  2133.             }
  2134.           }
  2135.         }
  2136.         break;
  2137.       default:
  2138.         break;
  2139.     }
  2140.   }
  2141. }
  2142.  
  2143. static void DecodeMIN_MAX(Word Code)
  2144. {
  2145.   tAdrVals AdrVals;
  2146.   Byte Reg;
  2147.  
  2148.   if (ChkArgCnt(2, 2)
  2149.    && DecodeRegArg(1, &Reg, 0xff)
  2150.    && SetOpSize(RegSizes[Reg])
  2151.    && DecodeAdr(2, MModeMemReg | MModeImm, &AdrVals))
  2152.   {
  2153.     switch (AdrVals.Mode)
  2154.     {
  2155.       case AdrModeMemReg:
  2156.         PutCode(Code | Reg);
  2157.         BAsmCode[CodeLen++] = AdrVals.Arg;
  2158.         AppendAdrVals(&AdrVals);
  2159.         break;
  2160.       case AdrModeImm: /* was only allowed for short immediate in MemReg */
  2161.         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2162.         break;
  2163.       default:
  2164.         break;
  2165.     }
  2166.   }
  2167. }
  2168.  
  2169. static void DecodeMOV(Word Code)
  2170. {
  2171.   tAdrVals SrcAdrVals, DestAdrVals;
  2172.   Byte Reg, SizeCode;
  2173.  
  2174.   UNUSED(Code);
  2175.  
  2176.   if (ChkArgCnt(2, 2)
  2177.    && DecodeAdr(2, MModeMemReg, &DestAdrVals))
  2178.   {
  2179.     /* prefer attribute to destination... */
  2180.  
  2181.     if (IsReg(&DestAdrVals, &Reg) && (OpSize == eSymbolSizeUnknown))
  2182.       SetOpSize(RegSizes[Reg]);
  2183.  
  2184.     if (!DecodeAdr(1, MModeMemReg | MModeImm, &SrcAdrVals))
  2185.       return;
  2186.  
  2187.     /* ...to source operand size */
  2188.  
  2189.     if (IsReg(&SrcAdrVals, &Reg) && (OpSize == eSymbolSizeUnknown))
  2190.       SetOpSize(RegSizes[Reg]);
  2191.  
  2192.     if (!SizeCode2(OpSize, &SizeCode))
  2193.     {
  2194.       WrError(ErrNum_InvOpSize);
  2195.       return;
  2196.     }
  2197.  
  2198.     switch (SrcAdrVals.Mode)
  2199.     {
  2200.       case AdrModeImm:
  2201.         PutCode(0x0c + SizeCode);
  2202.         AppendAdrVals(&SrcAdrVals);
  2203.         BAsmCode[CodeLen++] = DestAdrVals.Arg;
  2204.         AppendAdrVals(&DestAdrVals);
  2205.         break;
  2206.       case AdrModeMemReg:
  2207.         PutCode(0x1c | SizeCode);
  2208.         BAsmCode[CodeLen++] = SrcAdrVals.Arg;
  2209.         AppendAdrVals(&SrcAdrVals);
  2210.         BAsmCode[CodeLen++] = DestAdrVals.Arg;
  2211.         AppendAdrVals(&DestAdrVals);
  2212.         break;
  2213.       default:
  2214.         break;
  2215.     }
  2216.   }
  2217. }
  2218.  
  2219. static void DecodePSH_PUL(Word Code)
  2220. {
  2221.   Word RegMask = 0, ThisRegMask;
  2222.   int z;
  2223.   Byte Reg;
  2224.   static const Word RegMasks[8] = { 0x0002, 0x0001, 0x2000, 0x1000, 0x0008, 0x004, 0x0800, 0x0400 };
  2225.  
  2226.   if (!ChkArgCnt(1, ArgCntMax))
  2227.     return;
  2228.   for (z = 1; z <= ArgCnt; z++)
  2229.   {
  2230.     if (!as_strcasecmp(ArgStr[z].str.p_str, "ALL"))
  2231.       ThisRegMask = 0x3f3f;
  2232.     else if (!as_strcasecmp(ArgStr[z].str.p_str, "ALL16b"))
  2233.       ThisRegMask = 0x3003;
  2234.     else if (DecodeRegStr(ArgStr[z].str.p_str, &Reg))
  2235.       ThisRegMask = RegMasks[Reg];
  2236.     else if (!as_strcasecmp(ArgStr[z].str.p_str, "CCH"))
  2237.       ThisRegMask = 0x0020;
  2238.     else if (!as_strcasecmp(ArgStr[z].str.p_str, "CCL"))
  2239.       ThisRegMask = 0x0010;
  2240.     else if (DecodeAdrRegStr(ArgStr[z].str.p_str, &Reg) && (Reg < 2))
  2241.       ThisRegMask = 0x0200 >> Reg;
  2242.     else
  2243.     {
  2244.       WrStrErrorPos(ErrNum_InvReg, &ArgStr[z]);
  2245.       return;
  2246.     }
  2247.     if (ThisRegMask & RegMask)
  2248.     {
  2249.       WrStrErrorPos(ErrNum_DoubleReg, &ArgStr[z]);
  2250.       return;
  2251.     }
  2252.     RegMask |= ThisRegMask;
  2253.   }
  2254.   if (RegMask == 0x3f3f)
  2255.     PutCode(Code | 0x00);
  2256.   else if (RegMask == 0x3003)
  2257.     PutCode(Code | 0x40);
  2258.   else if (Hi(RegMask) && !Lo(RegMask))
  2259.     PutCode(Code | 0x40 | Hi(RegMask));
  2260.   else if (Lo(RegMask) && !Hi(RegMask))
  2261.     PutCode(Code | 0x00 | Lo(RegMask));
  2262.   else
  2263.     WrError(ErrNum_InvRegList);
  2264. }
  2265.  
  2266. static void DecodeROL_ROR(Word Code)
  2267. {
  2268.   tAdrVals AdrVals;
  2269.   Byte Reg, SizeCode;
  2270.  
  2271.   if (ChkArgCnt(1, 1) && DecodeAdr(1, MModeMemReg, &AdrVals))
  2272.   {
  2273.     if (IsReg(&AdrVals, &Reg) && !SetOpSize(RegSizes[Reg]))
  2274.       return;
  2275.     if (OpSize == eSymbolSizeUnknown)
  2276.     {
  2277.       WrError(ErrNum_UndefOpSizes);
  2278.       return;
  2279.     }
  2280.     if (!SizeCode2(OpSize, &SizeCode))
  2281.     {
  2282.       WrError(ErrNum_InvOpSize);
  2283.       return;
  2284.     }
  2285.     PutCode(Code | SizeCode);
  2286.     BAsmCode[CodeLen++] = AdrVals.Arg;
  2287.     AppendAdrVals(&AdrVals);
  2288.   }
  2289. }
  2290.  
  2291. static void DecodeTBcc(Word Code)
  2292. {
  2293.   tAdrVals AdrVals;
  2294.  
  2295.   if (!ChkArgCnt(2, 2) || !DecodeAdr(1, MModeReg | MModeAReg | MModeMemReg | MModeImm, &AdrVals))
  2296.     return;
  2297.  
  2298.   switch (AdrVals.Mode)
  2299.   {
  2300.     case AdrModeReg:
  2301.       if (!SetOpSize(RegSizes[AdrVals.Arg]))
  2302.         return;
  2303.       PutCode(Code | AdrVals.Arg);
  2304.       break;
  2305.     case AdrModeAReg:
  2306.       if (AdrVals.Arg >= 2)
  2307.       {
  2308.         WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  2309.         return;
  2310.       }
  2311.       if (!SetOpSize(eSymbolSize24Bit))
  2312.         return;
  2313.       PutCode(Code | 0x0008 | AdrVals.Arg);
  2314.       break;
  2315.     case AdrModeMemReg:
  2316.     {
  2317.       Byte SizeCode;
  2318.  
  2319.       if (OpSize == eSymbolSizeUnknown)
  2320.       {
  2321.         WrError(ErrNum_UndefOpSizes);
  2322.         return;
  2323.       }
  2324.       if (!SizeCode2(OpSize, &SizeCode))
  2325.       {
  2326.         WrError(ErrNum_InvOpSize);
  2327.         return;
  2328.       }
  2329.       PutCode(Code | 0x000c | SizeCode);
  2330.       BAsmCode[CodeLen++] = AdrVals.Arg;
  2331.       AppendAdrVals(&AdrVals);
  2332.       break;
  2333.     }
  2334.     case AdrModeImm: /* was only allowed for short immediate */
  2335.       WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  2336.       return;
  2337.     default:
  2338.       return;
  2339.   }
  2340.  
  2341.   OpSize = OpSize2;
  2342.   if (!DecodeBranchCore(2))
  2343.     CodeLen = 0;
  2344. }
  2345.  
  2346. static void DecodeTRAP(Word Code)
  2347. {
  2348.   tAdrVals AdrVals;
  2349.  
  2350.   UNUSED(Code);
  2351.  
  2352.   if (ChkArgCnt(1, 1) && SetOpSize(eSymbolSize8Bit) && DecodeAdr(1, MModeImm, &AdrVals))
  2353.   {
  2354.     BAsmCode[CodeLen++] = 0x1b;
  2355.     BAsmCode[CodeLen++] = AdrVals.Vals[0];
  2356.     switch ((AdrVals.Vals[0] >> 4) & 0x0f)
  2357.     {
  2358.       case 12: case 13: case 14: case 15:
  2359.         break;
  2360.       case 10: case 11:
  2361.         if ((AdrVals.Vals[0] & 0x0f) >= 8)
  2362.           break;
  2363.         else
  2364.           goto warn;
  2365.       case 9:
  2366.         if ((AdrVals.Vals[0] & 0x0f) >= 2)
  2367.           break;
  2368.         /* else fall-through */
  2369.       default:
  2370.       warn:
  2371.         WrError(ErrNum_TrapValidInstruction);
  2372.     }
  2373.   }
  2374. }
  2375.  
  2376. static void DecodeDEFBIT(Word Code)
  2377. {
  2378.   LongWord BitSpec;
  2379.  
  2380.   UNUSED(Code);
  2381.  
  2382.   /* if in structure definition, add special element to structure */
  2383.  
  2384.   if (ActPC == StructSeg)
  2385.   {
  2386.     Boolean OK;
  2387.     Byte BitPos;
  2388.     PStructElem pElement;
  2389.  
  2390.     if (!ChkArgCnt(2, 2))
  2391.       return;
  2392.     BitPos = EvalBitPosition(&ArgStr[2], &OK, (OpSize == eSymbolSizeUnknown) ? eSymbolSize32Bit : OpSize);
  2393.     if (!OK)
  2394.       return;
  2395.     pElement = CreateStructElem(&LabPart);
  2396.     if (!pElement)
  2397.       return;
  2398.     pElement->pRefElemName = as_strdup(ArgStr[1].str.p_str);
  2399.     pElement->OpSize = OpSize;
  2400.     pElement->BitPos = BitPos;
  2401.     pElement->ExpandFnc = ExpandS12ZBit;
  2402.     AddStructElem(pInnermostNamedStruct->StructRec, pElement);
  2403.   }
  2404.   else
  2405.   {
  2406.     if (OpSize == eSymbolSizeUnknown)
  2407.       OpSize = eSymbolSize8Bit;
  2408.     if (OpSize > eSymbolSize32Bit)
  2409.     {
  2410.       WrError(ErrNum_InvOpSize);
  2411.       return;
  2412.     }
  2413.  
  2414.     if (DecodeBitArg(&BitSpec, 1, ArgCnt, OpSize))
  2415.     {
  2416.       *ListLine = '=';
  2417.       DissectBit_S12Z(ListLine + 1, STRINGSIZE - 3, BitSpec);
  2418.       PushLocHandle(-1);
  2419.       EnterIntSymbol(&LabPart, BitSpec, SegBData, False);
  2420.       PopLocHandle();
  2421.       /* TODO: MakeUseList? */
  2422.     }
  2423.   }
  2424. }
  2425.  
  2426. static void DecodeDEFBITFIELD(Word Code)
  2427. {
  2428.   UNUSED(Code);
  2429.  
  2430.   /* if in structure definition, add special element to structure */
  2431.  
  2432.   if (ActPC == StructSeg)
  2433.   {
  2434.     Word BitField;
  2435.     PStructElem pElement;
  2436.  
  2437.     if (!ChkArgCnt(2, 2))
  2438.       return;
  2439.     if (!DecodeImmBitField(&ArgStr[2], &BitField))
  2440.       return;
  2441.     pElement = CreateStructElem(&LabPart);
  2442.     if (!pElement)
  2443.       return;
  2444.     pElement->pRefElemName = as_strdup(ArgStr[1].str.p_str);
  2445.     pElement->OpSize = OpSize;
  2446.     pElement->BitPos = BitField & 31;
  2447.     pElement->BitWidthM1 = (BitField >> 5) - 1;
  2448.     pElement->ExpandFnc = ExpandS12ZBitfield;
  2449.     AddStructElem(pInnermostNamedStruct->StructRec, pElement);
  2450.   }
  2451.   else
  2452.   {
  2453.     LongWord BitfieldSpec;
  2454.  
  2455.     /* opposed to bit operations, bit field operations also work
  2456.         24 bit operands: */
  2457.  
  2458.     if (OpSize == eSymbolSizeUnknown)
  2459.       OpSize = eSymbolSize8Bit;
  2460.     if ((OpSize > eSymbolSize32Bit) && (OpSize != eSymbolSize24Bit))
  2461.     {
  2462.       WrError(ErrNum_InvOpSize);
  2463.       return;
  2464.     }
  2465.  
  2466.     if (DecodeBitfieldArg(&BitfieldSpec, 1, ArgCnt, OpSize))
  2467.     {
  2468.       *ListLine = '=';
  2469.       DissectBit_S12Z(ListLine + 1, STRINGSIZE - 3, BitfieldSpec);
  2470.       PushLocHandle(-1);
  2471.       EnterIntSymbol(&LabPart, BitfieldSpec, SegBData, False);
  2472.       PopLocHandle();
  2473.       /* TODO: MakeUseList? */
  2474.     }
  2475.   }
  2476. }
  2477.  
  2478. /*--------------------------------------------------------------------------*/
  2479. /* Code Table Handling */
  2480.  
  2481. static void AddFixed(const char *pName, Word Code)
  2482. {
  2483.   AddInstTable(InstTable, pName, Code, DecodeFixed);
  2484. }
  2485.  
  2486. static void AddBranch(const char *pName, Word Code)
  2487. {
  2488.   AddInstTable(InstTable, pName, Code, DecodeBranch);
  2489. }
  2490.  
  2491. static void AddReg(const char *pName, Word Code)
  2492. {
  2493.   AddInstTable(InstTable, pName, Code, DecodeReg);
  2494. }
  2495.  
  2496. static void AddRegMemImm(const char *pName, Word Code)
  2497. {
  2498.   AddInstTable(InstTable, pName, Code, DecodeRegMemImm);
  2499. }
  2500.  
  2501. static void AddCondition(const char *pName, Word Code, InstProc Proc)
  2502. {
  2503.   char InstrName[20];
  2504.  
  2505.   as_snprintf(InstrName, sizeof(InstrName), pName, "NE"); AddInstTable(InstTable, InstrName, Code | (0 << 4), Proc);
  2506.   as_snprintf(InstrName, sizeof(InstrName), pName, "EQ"); AddInstTable(InstTable, InstrName, Code | (1 << 4), Proc);
  2507.   as_snprintf(InstrName, sizeof(InstrName), pName, "PL"); AddInstTable(InstTable, InstrName, Code | (2 << 4), Proc);
  2508.   as_snprintf(InstrName, sizeof(InstrName), pName, "MI"); AddInstTable(InstTable, InstrName, Code | (3 << 4), Proc);
  2509.   as_snprintf(InstrName, sizeof(InstrName), pName, "GT"); AddInstTable(InstTable, InstrName, Code | (4 << 4), Proc);
  2510.   as_snprintf(InstrName, sizeof(InstrName), pName, "LE"); AddInstTable(InstTable, InstrName, Code | (5 << 4), Proc);
  2511. }
  2512.  
  2513. static void InitFields(void)
  2514. {
  2515.   InstTable = CreateInstTable(405);
  2516.   SetDynamicInstTable(InstTable);
  2517.  
  2518.   AddFixed("NOP",  NOPCode);
  2519.   AddFixed("BGND", 0x0000);
  2520.   AddFixed("CLC",  0xcefe);
  2521.   AddFixed("CLI",  0xceef);
  2522.   AddFixed("CLV",  0xcefd);
  2523.   AddFixed("RTI",  0x1b90);
  2524.   AddFixed("RTS",  0x0005);
  2525.   AddFixed("SEC",  0xde01);
  2526.   AddFixed("SEI",  0xde10);
  2527.   AddFixed("SEV",  0xde02);
  2528.   AddFixed("STOP", 0x1b05);
  2529.   AddFixed("SWI",  0x00ff);
  2530.   AddFixed("SYS",  0x1b07);
  2531.   AddFixed("WAI",  0x1b06);
  2532.   AddFixed("SPARE", 0x00ef);
  2533.  
  2534.   AddBranch("BCC", 0x0024);
  2535.   AddBranch("BCS", 0x0025);
  2536.   AddBranch("BEQ", 0x0027);
  2537.   AddBranch("BGE", 0x002c);
  2538.   AddBranch("BGT", 0x002e);
  2539.   AddBranch("BHI", 0x0022);
  2540.   AddBranch("BHS", 0x0024);
  2541.   AddBranch("BLE", 0x002f);
  2542.   AddBranch("BLO", 0x0025);
  2543.   AddBranch("BLS", 0x0023);
  2544.   AddBranch("BLT", 0x002d);
  2545.   AddBranch("BMI", 0x002b);
  2546.   AddBranch("BNE", 0x0026);
  2547.   AddBranch("BPL", 0x002a);
  2548.   AddBranch("BRA", 0x0020);
  2549.   AddBranch("BSR", 0x0021);
  2550.   AddBranch("BVC", 0x0028);
  2551.   AddBranch("BVS", 0x0029);
  2552.  
  2553.   AddReg("ABS", 0x1b40);
  2554.   AddReg("SAT", 0x1ba0);
  2555.  
  2556.   AddRegMemImm("ADC",  0x1b50);
  2557.   AddRegMemImm("ADD",  0x0050);
  2558.   AddRegMemImm("AND",  0x0058);
  2559.   AddRegMemImm("BIT",  0x1b58);
  2560.   AddRegMemImm("EOR",  0x1b78);
  2561.   AddRegMemImm("OR",   0x0078);
  2562.   AddRegMemImm("SBC",  0x1b70);
  2563.  
  2564.   AddInstTable(InstTable, "SUB", 0x0070, DecodeSUB);
  2565.   AddInstTable(InstTable, "CMP", 0x00e0, DecodeCMP);
  2566.  
  2567.   AddInstTable(InstTable, "ANDCC", 0x00ce, DecodeImm8);
  2568.   AddInstTable(InstTable, "ORCC" , 0x00de, DecodeImm8);
  2569.   AddInstTable(InstTable, "TRAP" , 0, DecodeTRAP);
  2570.  
  2571.   AddInstTable(InstTable, "ASL", 0xc0, DecodeShift);
  2572.   AddInstTable(InstTable, "ASR", 0x80, DecodeShift);
  2573.   AddInstTable(InstTable, "LSL", 0x40, DecodeShift);
  2574.   AddInstTable(InstTable, "LSR", 0x00, DecodeShift);
  2575.  
  2576.   AddInstTable(InstTable, "BCLR", 0xec, DecodeBit);
  2577.   AddInstTable(InstTable, "BSET", 0xed, DecodeBit);
  2578.   AddInstTable(InstTable, "BTGL", 0xee, DecodeBit);
  2579.  
  2580.   AddInstTable(InstTable, "BFEXT", 0x00, DecodeBitField);
  2581.   AddInstTable(InstTable, "BFINS", 0x80, DecodeBitField);
  2582.  
  2583.   AddInstTable(InstTable, "BRCLR", 0x02, DecodeBitRel);
  2584.   AddInstTable(InstTable, "BRSET", 0x03, DecodeBitRel);
  2585.  
  2586.   AddInstTable(InstTable, "CLB", 0x1b91, DecodeTwoReg);
  2587.  
  2588.   AddInstTable(InstTable, "CLR", 0x0000, DecodeCLR);
  2589.   AddInstTable(InstTable, "COM", 0x00cc, DecodeCOM_NEG);
  2590.   AddInstTable(InstTable, "NEG", 0x00dc, DecodeCOM_NEG);
  2591.   AddCondition("DB%s", 0x0d80, DecodeDBcc);
  2592.   AddInstTable(InstTable, "DEC", 0x0040, DecodeINC_DEC);
  2593.   AddInstTable(InstTable, "INC", 0x0030, DecodeINC_DEC);
  2594.  
  2595.   AddInstTable(InstTable, "DIVS", 0x3081, DecodeDIV_MOD);
  2596.   AddInstTable(InstTable, "DIVU", 0x3001, DecodeDIV_MOD);
  2597.   AddInstTable(InstTable, "MODS", 0x3881, DecodeDIV_MOD);
  2598.   AddInstTable(InstTable, "MODU", 0x3801, DecodeDIV_MOD);
  2599.   AddInstTable(InstTable, "MACS", 0x4881, DecodeDIV_MOD);
  2600.   AddInstTable(InstTable, "MACU", 0x4801, DecodeDIV_MOD);
  2601.   AddInstTable(InstTable, "MULS", 0x4880, DecodeDIV_MOD);
  2602.   AddInstTable(InstTable, "MULU", 0x4800, DecodeDIV_MOD);
  2603.   AddInstTable(InstTable,"QMULS", 0xb081, DecodeDIV_MOD);
  2604.   AddInstTable(InstTable,"QMULU", 0xb001, DecodeDIV_MOD);
  2605.  
  2606.   AddInstTable(InstTable, "EXG", 0x00ae, DecodeEXG_TFR);
  2607.   AddInstTable(InstTable, "TFR", 0x009e, DecodeEXG_TFR);
  2608.   AddInstTable(InstTable, "SEX", 0x01ae, DecodeEXG_TFR);
  2609.   AddInstTable(InstTable, "ZEX", 0x019e, DecodeEXG_TFR);
  2610.  
  2611.   AddInstTable(InstTable, "JMP", 0x00aa, DecodeJMP_JSR);
  2612.   AddInstTable(InstTable, "JSR", 0x00ab, DecodeJMP_JSR);
  2613.  
  2614.   AddInstTable(InstTable, "LD" , 0x0000, DecodeLD_ST);
  2615.   AddInstTable(InstTable, "ST" , 0x0020, DecodeLD_ST);
  2616.   AddInstTable(InstTable, "MOV" , 0x0000, DecodeMOV);
  2617.   AddInstTable(InstTable, "LEA" , 0x0000, DecodeLEA);
  2618.  
  2619.   AddInstTable(InstTable, "MAXS", 0x1b28, DecodeMIN_MAX);
  2620.   AddInstTable(InstTable, "MAXU", 0x1b18, DecodeMIN_MAX);
  2621.   AddInstTable(InstTable, "MINS", 0x1b20, DecodeMIN_MAX);
  2622.   AddInstTable(InstTable, "MINU", 0x1b10, DecodeMIN_MAX);
  2623.  
  2624.   AddInstTable(InstTable, "PSH", 0x0400, DecodePSH_PUL);
  2625.   AddInstTable(InstTable, "PUL", 0x0480, DecodePSH_PUL);
  2626.  
  2627.   AddInstTable(InstTable, "ROL", 0x1064, DecodeROL_ROR);
  2628.   AddInstTable(InstTable, "ROR", 0x1024, DecodeROL_ROR);
  2629.  
  2630.   AddCondition("TB%s", 0x0b00, DecodeTBcc);
  2631.  
  2632.   AddInstTable(InstTable, "DEFBIT", 0, DecodeDEFBIT);
  2633.   AddInstTable(InstTable, "DEFBITFIELD", 0, DecodeDEFBITFIELD);
  2634.  
  2635.   init_moto8_pseudo(InstTable, e_moto_8_be | e_moto_8_db | e_moto_8_dw);
  2636. }
  2637.  
  2638. static void DeinitFields(void)
  2639. {
  2640.   DestroyInstTable(InstTable);
  2641. }
  2642.  
  2643. /*--------------------------------------------------------------------------*/
  2644. /* Semiglobal Functions */
  2645.  
  2646. static Boolean DecodeAttrPart_S12Z(void)
  2647. {
  2648.   int z;
  2649.  
  2650.   if (strlen(AttrPart.str.p_str) > 2)
  2651.   {
  2652.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  2653.     return False;
  2654.   }
  2655.  
  2656.   for (z = 0; z < 2; z++)
  2657.   {
  2658.     if (AttrPart.str.p_str[z] == '\0')
  2659.       break;
  2660.     if (!DecodeMoto16AttrSize(AttrPart.str.p_str[z], &AttrPartOpSize[z], True))
  2661.       return False;
  2662.   }
  2663.   return True;
  2664. }
  2665.  
  2666. static void MakeCode_S12Z(void)
  2667. {
  2668.   CodeLen = 0;
  2669.   DontPrint = False;
  2670.  
  2671.   OpSize = (AttrPartOpSize[0] != eSymbolSizeUnknown) ? AttrPartOpSize[0] : eSymbolSizeUnknown;
  2672.   OpSize2 = (AttrPartOpSize[1] != eSymbolSizeUnknown) ? AttrPartOpSize[1] : eSymbolSizeUnknown;
  2673.  
  2674.   /* zu ignorierendes */
  2675.  
  2676.   if (Memo(""))
  2677.     return;
  2678.  
  2679.   /* Pseudoanweisungen */
  2680.  
  2681.   /* TODO: handle eSymbolSize24Bit in DC/DS */
  2682.  
  2683.   if (DecodeMoto16Pseudo(OpSize, True)) return;
  2684.  
  2685.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  2686.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  2687. }
  2688.  
  2689. static Boolean IsDef_S12Z(void)
  2690. {
  2691.   return Memo("DEFBIT") || Memo("DEFBITFIELD");
  2692. }
  2693.  
  2694. static void SwitchTo_S12Z(void)
  2695. {
  2696.   const TFamilyDescr *pDescr = FindFamilyByName("S12Z");
  2697.   TurnWords = False;
  2698.   SetIntConstMode(eIntConstModeMoto);
  2699.  
  2700.   PCSymbol = "*";
  2701.   HeaderID = pDescr->Id;
  2702.   NOPCode = 0x01;
  2703.   DivideChars = ",";
  2704.   HasAttrs = True;
  2705.   AttrChars = ".";
  2706.  
  2707.   ValidSegs = (1 << SegCode);
  2708.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  2709.   SegLimits[SegCode] = 0xffffff;
  2710.   DecodeAttrPart = DecodeAttrPart_S12Z;
  2711.   MakeCode = MakeCode_S12Z;
  2712.   IsDef = IsDef_S12Z;
  2713.   SwitchFrom = DeinitFields;
  2714.   DissectBit = DissectBit_S12Z;
  2715.   InitFields();
  2716.   AddMoto16PseudoONOFF(False);
  2717. }
  2718.  
  2719. void codes12z_init(void)
  2720. {
  2721.   (void)AddCPU("S912ZVC19F0MKH" , SwitchTo_S12Z);
  2722.   (void)AddCPU("S912ZVC19F0MLF" , SwitchTo_S12Z);
  2723.   (void)AddCPU("S912ZVCA19F0MKH", SwitchTo_S12Z);
  2724.   (void)AddCPU("S912ZVCA19F0MLF", SwitchTo_S12Z);
  2725.   (void)AddCPU("S912ZVCA19F0WKH", SwitchTo_S12Z);
  2726.   (void)AddCPU("S912ZVH128F2CLQ", SwitchTo_S12Z);
  2727.   (void)AddCPU("S912ZVH128F2CLL", SwitchTo_S12Z);
  2728.   (void)AddCPU("S912ZVH64F2CLQ" , SwitchTo_S12Z);
  2729.   (void)AddCPU("S912ZVHY64F1CLQ", SwitchTo_S12Z);
  2730.   (void)AddCPU("S912ZVHY32F1CLQ", SwitchTo_S12Z);
  2731.   (void)AddCPU("S912ZVHY64F1CLL", SwitchTo_S12Z);
  2732.   (void)AddCPU("S912ZVHY32F1CLL", SwitchTo_S12Z);
  2733.   (void)AddCPU("S912ZVHL64F1CLQ", SwitchTo_S12Z);
  2734.   (void)AddCPU("S912ZVHL32F1CLQ", SwitchTo_S12Z);
  2735.   (void)AddCPU("S912ZVHL64F1CLL", SwitchTo_S12Z);
  2736.   (void)AddCPU("S912ZVHL32F1CLL", SwitchTo_S12Z);
  2737.   (void)AddCPU("S912ZVFP64F1CLQ", SwitchTo_S12Z);
  2738.   (void)AddCPU("S912ZVFP64F1CLL", SwitchTo_S12Z);
  2739.   (void)AddCPU("S912ZVH128F2VLQ", SwitchTo_S12Z);
  2740.   (void)AddCPU("S912ZVH128F2VLL", SwitchTo_S12Z);
  2741.   (void)AddCPU("S912ZVH64F2VLQ" , SwitchTo_S12Z);
  2742.   (void)AddCPU("S912ZVHY64F1VLQ", SwitchTo_S12Z);
  2743.   (void)AddCPU("S912ZVHY32F1VLQ", SwitchTo_S12Z);
  2744.   (void)AddCPU("S912ZVHY64F1VL" , SwitchTo_S12Z);
  2745.   (void)AddCPU("S912ZVHY32F1VLL", SwitchTo_S12Z);
  2746.   (void)AddCPU("S912ZVHL64F1VLQ", SwitchTo_S12Z);
  2747. }
  2748.