Subversion Repositories pentevo

Rev

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

  1. /* codenv60.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Code Generator NEC V60                                                    */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include "bpemu.h"
  14. #include "strutil.h"
  15.  
  16. #include "headids.h"
  17. #include "asmdef.h"
  18. #include "asmsub.h"
  19. #include "asmpars.h"
  20. #include "asmallg.h"
  21. #include "asmitree.h"
  22. #include "codevars.h"
  23. #include "codepseudo.h"
  24. #include "motpseudo.h"
  25. #include "onoff_common.h"
  26.  
  27. #include "codev60.h"
  28.  
  29. #define REG_SP 31
  30. #define REG_FP 30
  31. #define REG_AP 29
  32. #define REG_PC 64
  33.  
  34. /* NOTE: only 3 code flags are available, since machine sub code
  35.    is 5 bits long: */
  36.  
  37. #define CODE_FLAG_SUPMODE (1 << 15)
  38. #define CODE_FLAG_OP2_IMM (1 << 14)
  39. #define CODE_FLAG_LIM32 (1 << 13)
  40.  
  41. typedef enum
  42. {
  43.   ModReg = 0,
  44.   ModImm = 1,
  45.   ModMem = 2,
  46.   ModIO  = 3
  47. } tAdrMode;
  48.  
  49. #define MModReg (1 << ModReg)
  50. #define MModImm (1 << ModImm)
  51. #define MModMem (1 << ModMem)
  52. #define MModIO  (1 << ModIO)
  53. #define MModImm7Bit (1 << 7)
  54. #define MModImmCondition (1 << 6)
  55.  
  56. /* Count = 0 implies error/invalid, since at least mod byte must be present */
  57.  
  58. typedef struct
  59. {
  60.   unsigned count;
  61.   Byte m, vals[10];
  62.   tSymbolSize forced_disp_size, data_op_size;
  63.   tSymbolFlags immediate_flags;
  64.   Boolean bit_offset_immediate;
  65.   LongInt bit_offset;
  66. } tAdrVals;
  67.  
  68. typedef struct
  69. {
  70.   Byte val;
  71.   tSymbolFlags immediate_flags;
  72. } tLenVals;
  73.  
  74. typedef struct
  75. {
  76.   char name[3];
  77.   Byte code;
  78. } tCondition;
  79.  
  80. static tSymbolSize OpSize;
  81. static tCondition *Conditions;
  82.  
  83. /*-------------------------------------------------------------------------*/
  84. /* Register Symbols */
  85.  
  86. /*!------------------------------------------------------------------------
  87.  * \fn     DecodeRegCore(const char *pArg, Byte *pResult)
  88.  * \brief  check whether argument is a CPU register
  89.  * \param  pArg argument to check
  90.  * \param  pResult numeric register value if yes
  91.  * \return True if yes
  92.  * ------------------------------------------------------------------------ */
  93.  
  94. static Boolean DecodeRegCore(const char *pArg, Byte *pResult)
  95. {
  96.   size_t l;
  97.  
  98.   if (!as_strcasecmp(pArg, "SP"))
  99.   {
  100.     *pResult = REG_SP | REGSYM_FLAG_ALIAS;
  101.     return True;
  102.   }
  103.   else if (!as_strcasecmp(pArg, "FP"))
  104.   {
  105.     *pResult = REG_FP | REGSYM_FLAG_ALIAS;
  106.     return True;
  107.   }
  108.   else if (!as_strcasecmp(pArg, "AP"))
  109.   {
  110.     *pResult = REG_AP | REGSYM_FLAG_ALIAS;
  111.     return True;
  112.   }
  113.  
  114.   l = strlen(pArg);
  115.   if ((l < 2) || (l > 3) || (as_toupper(*pArg) != 'R'))
  116.     return False;
  117.   *pResult = 0;
  118.   for (pArg++; *pArg; pArg++)
  119.   {
  120.     if (!isdigit(*pArg))
  121.       return False;
  122.     *pResult = (*pResult * 10) + (*pArg - '0');
  123.   }
  124.   return (*pResult < 32);
  125. }
  126.  
  127. /*!------------------------------------------------------------------------
  128.  * \fn     DissectReg_V60(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  129.  * \brief  dissect register symbols - V60 variant
  130.  * \param  pDest destination buffer
  131.  * \param  DestSize destination buffer size
  132.  * \param  Value numeric register value
  133.  * \param  InpSize register size
  134.  * ------------------------------------------------------------------------ */
  135.  
  136. static void DissectReg_V60(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  137. {
  138.   if (InpSize == eSymbolSize32Bit)
  139.   {
  140.     switch (Value)
  141.     {
  142.       case REGSYM_FLAG_ALIAS | REG_SP:
  143.         as_snprintf(pDest, DestSize, "SP");
  144.         break;
  145.       case REGSYM_FLAG_ALIAS | REG_FP:
  146.         as_snprintf(pDest, DestSize, "FP");
  147.         break;
  148.       case REGSYM_FLAG_ALIAS | REG_AP:
  149.         as_snprintf(pDest, DestSize, "AP");
  150.         break;
  151.       default:
  152.         as_snprintf(pDest, DestSize, "R%u", (unsigned)(Value & 31));
  153.     }
  154.   }
  155.   else
  156.     as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
  157. }
  158.  
  159. /*--------------------------------------------------------------------------*/
  160. /* Address Expression Parser */
  161.  
  162. /*!------------------------------------------------------------------------
  163.  * \fn     ResetAdrVals(tAdrVals *p_vals)
  164.  * \brief  reset to invalid/empty state
  165.  * \param  p_vals arg to clear
  166.  * ------------------------------------------------------------------------ */
  167.  
  168. static void ResetAdrVals(tAdrVals *p_vals)
  169. {
  170.   p_vals->count = 0;
  171.   p_vals->m = 0;
  172.   p_vals->forced_disp_size =
  173.   p_vals->data_op_size = eSymbolSizeUnknown;
  174.   p_vals->immediate_flags = eSymbolFlag_None;
  175.   p_vals->bit_offset_immediate = False;
  176.   p_vals->bit_offset = 0;
  177. }
  178.  
  179. /*!------------------------------------------------------------------------
  180.  * \fn     DecodeReg(const tStrComp *pArg, Byte *pResult, Boolean MustBeReg)
  181.  * \brief  check whether argument is a CPU register or register alias
  182.  * \param  pArg argument to check
  183.  * \param  pResult numeric register value if yes
  184.  * \param  MustBeReg argument is expected to be a register
  185.  * \return RegEvalResult
  186.  * ------------------------------------------------------------------------ */
  187.  
  188. static tRegEvalResult DecodeReg(const tStrComp *pArg, Byte *pResult, Boolean MustBeReg)
  189. {
  190.   tRegDescr RegDescr;
  191.   tEvalResult EvalResult;
  192.   tRegEvalResult RegEvalResult;
  193.  
  194.   if (DecodeRegCore(pArg->str.p_str, pResult))
  195.   {
  196.     *pResult &= ~REGSYM_FLAG_ALIAS;
  197.     return eIsReg;
  198.   }
  199.  
  200.   RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSize32Bit, MustBeReg);
  201.   *pResult = RegDescr.Reg & ~REGSYM_FLAG_ALIAS;
  202.   return RegEvalResult;
  203. }
  204.  
  205. /*!------------------------------------------------------------------------
  206.  * \fn     DecodeCondition(const char *p_arg, LongWord *p_result)
  207.  * \brief  check whether argument is a condition identifier
  208.  * \param  p_arg source argument
  209.  * \param  p_result result buffer if yes
  210.  * \return True if yes
  211.  * ------------------------------------------------------------------------ */
  212.  
  213. static Boolean DecodeCondition(const char *p_arg, LongWord *p_result)
  214. {
  215.   int z;
  216.  
  217.   for (z = 0; Conditions[z].name[0]; z++)
  218.     if (!as_strcasecmp(p_arg, Conditions[z].name))
  219.     {
  220.       *p_result = Conditions[z].code;
  221.       return True;
  222.     }
  223.   return False;
  224. }
  225.  
  226. /*!------------------------------------------------------------------------
  227.  * \fn     DecodeAdr(const tStrComp *pArg, tAdrVals *pResult, unsigned ModeMask)
  228.  * \brief  decode address expression
  229.  * \param  pArg source argument
  230.  * \param  pResult result buffer
  231.  * \param  MayImm allow immediate?
  232.  * \return True if successfully decoded
  233.  * ------------------------------------------------------------------------ */
  234.  
  235. static Boolean check_mode_mask(const tStrComp *p_arg, tAdrMode address_mode, unsigned mode_mask)
  236. {
  237.   if ((mode_mask >> address_mode) & 1)
  238.     return True;
  239.   {
  240.     WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  241.     return False;
  242.   }
  243. }
  244.  
  245. static int BaseQualifier(const char *pArg, int NextNonBlankPos, int SplitPos)
  246. {
  247.   return (pArg[NextNonBlankPos] == ']') ? SplitPos : -1;
  248. }
  249.  
  250. static void CutSize(tStrComp *pArg, tSymbolSize *pSize)
  251. {
  252.   static const char Suffixes[6][3] = { "B", "8", "H", "16", "W", "32" };
  253.   static const tSymbolSize Sizes[3] = { eSymbolSize8Bit, eSymbolSize16Bit, eSymbolSize32Bit };
  254.   size_t ArgLen = strlen(pArg->str.p_str), ThisLen;
  255.   unsigned z;
  256.  
  257.   for (z = 0; z < 6; z++)
  258.   {
  259.     ThisLen = strlen(Suffixes[z]);
  260.     if ((ArgLen > ThisLen + 1)
  261.      && (pArg->str.p_str[ArgLen - ThisLen - 1] == '.')
  262.      && !as_strcasecmp(pArg->str.p_str + ArgLen - ThisLen, Suffixes[z]))
  263.     {
  264.       *pSize = Sizes[z / 2];
  265.       StrCompShorten(pArg, ThisLen + 1);
  266.       break;
  267.     }
  268.   }
  269. }
  270.  
  271. static void AppendToVals(tAdrVals *p_vals, LongWord Value, tSymbolSize Size)
  272. {
  273.   p_vals->vals[p_vals->count++] = Value & 0xff;
  274.   if (Size >= eSymbolSize16Bit)
  275.   {
  276.     p_vals->vals[p_vals->count++] = (Value >> 8) & 0xff;
  277.     if (Size >= eSymbolSize32Bit)
  278.     {
  279.       p_vals->vals[p_vals->count++] = (Value >> 16) & 0xff;
  280.       p_vals->vals[p_vals->count++] = (Value >> 24) & 0xff;
  281.     }
  282.   }
  283. }
  284.  
  285. static Boolean IsPredecrement(const tStrComp *pArg, Byte *pResult, tRegEvalResult *pRegEvalResult)
  286. {
  287.   tStrComp RegComp;
  288.  
  289.   if (*pArg->str.p_str != '-')
  290.     return False;
  291.   StrCompRefRight(&RegComp, pArg, 1);
  292.   KillPrefBlanksStrComp(&RegComp);
  293.   *pRegEvalResult = DecodeReg(&RegComp, pResult, False);
  294.   return (*pRegEvalResult != eIsNoReg);
  295. }
  296.  
  297. static Boolean IsPostincrement(const tStrComp *pArg, Byte *pResult, tRegEvalResult *pRegEvalResult)
  298. {
  299.   String Reg;
  300.   tStrComp RegComp;
  301.   size_t ArgLen = strlen(pArg->str.p_str);
  302.  
  303.   if (!ArgLen || (pArg->str.p_str[ArgLen - 1] != '+'))
  304.     return False;
  305.   StrCompMkTemp(&RegComp, Reg, sizeof(Reg));
  306.   StrCompCopySub(&RegComp, pArg, 0, ArgLen - 1);
  307.   KillPostBlanksStrComp(&RegComp);
  308.   *pRegEvalResult = DecodeReg(&RegComp, pResult, False);
  309.   return (*pRegEvalResult != eIsNoReg);
  310. }
  311.  
  312. static Boolean DecodeRegOrPC(const tStrComp *pArg, Byte *pResult)
  313. {
  314.   if (!as_strcasecmp(pArg->str.p_str, "PC"))
  315.   {
  316.     *pResult = REG_PC;
  317.     return True;
  318.   }
  319.   else
  320.     return (DecodeReg(pArg, pResult, True) == eIsReg);
  321. }
  322.  
  323. static LongInt EvalDispOpt(const tStrComp *pArg, tEvalResult *pEvalResult, Boolean PCRelative)
  324. {
  325.   if (*pArg->str.p_str)
  326.     return EvalStrIntExpressionWithResult(pArg, Int32, pEvalResult) - (PCRelative ? EProgCounter() : 0);
  327.   else
  328.   {
  329.     memset(pEvalResult, 0, sizeof(*pEvalResult));
  330.     pEvalResult->OK = True;
  331.     return 0;
  332.   }
  333. }
  334.  
  335. static Boolean ProcessAbsolute(const tStrComp *pArg, tAdrVals *pResult, Byte IndexReg, Byte ModByte, unsigned mode_mask)
  336. {
  337.   tEvalResult eval_result;
  338.   LongWord Address;
  339.  
  340.   Address = EvalStrIntExpressionOffsWithResult(pArg, 1, UInt32, &eval_result);
  341.   pResult->count = 0;
  342.   if (!eval_result.OK)
  343.     return False;
  344.   if (mode_mask & MModIO)
  345.     ChkSpace(SegIO, eval_result.AddrSpaceMask);
  346.   if (!check_mode_mask(pArg, ModMem, mode_mask))
  347.     return False;
  348.  
  349.   if (IndexReg != REGSYM_FLAG_ALIAS)
  350.   {
  351.     pResult->vals[pResult->count++] = 0xc0 | IndexReg;
  352.     pResult->m = 1;
  353.   }
  354.   else
  355.     pResult->m = 0;
  356.   pResult->vals[pResult->count++] = ModByte;
  357.   AppendToVals(pResult, Address, eSymbolSize32Bit);
  358.  
  359.   return True;
  360. }
  361.  
  362. static Boolean DeduceAndCheckDispSize(const tStrComp *pArg, LongInt Value, tSymbolSize *pSize, const tEvalResult *pEvalResult)
  363. {
  364.   if (*pSize == eSymbolSizeUnknown)
  365.   {
  366.     if (RangeCheck(Value, SInt8))
  367.       *pSize = eSymbolSize8Bit;
  368.     else if (RangeCheck(Value, SInt16))
  369.       *pSize = eSymbolSize16Bit;
  370.     else
  371.       *pSize = eSymbolSize32Bit;
  372.   }
  373.   if (mFirstPassUnknownOrQuestionable(pEvalResult->Flags))
  374.     return True;
  375.   switch (*pSize)
  376.   {
  377.     case eSymbolSize8Bit:
  378.       return ChkRangePos(Value, -128, 127, pArg);
  379.     case eSymbolSize16Bit:
  380.       return ChkRangePos(Value, -32768, 32767, pArg);
  381.     case eSymbolSize32Bit:
  382.       return True;
  383.     default:
  384.       WrStrErrorPos(ErrNum_OverRange, pArg);
  385.   }
  386.   return False;
  387. }
  388.  
  389. static Boolean DecodeAdr(tStrComp *pArg, tAdrVals *pResult, unsigned ModeMask)
  390. {
  391.   int IndexSplitPos, OuterDispSplitPos, ArgLen;
  392.   Byte IndexReg = REGSYM_FLAG_ALIAS, BaseReg = REGSYM_FLAG_ALIAS;
  393.   tEvalResult EvalResult;
  394.  
  395.   ResetAdrVals(pResult);
  396.   pResult->data_op_size = OpSize;
  397.  
  398.   /* immediate */
  399.  
  400.   if (*pArg->str.p_str == '#')
  401.   {
  402.     LongWord Value;
  403.  
  404.     if (!check_mode_mask(pArg, ModImm, ModeMask))
  405.       return False;
  406.     if ((ModeMask & MModImmCondition) && DecodeCondition(pArg->str.p_str + 1, &Value))
  407.       EvalResult.OK = True;
  408.     else switch (OpSize)
  409.     {
  410.       case eSymbolSize8Bit:
  411.         Value = EvalStrIntExpressionOffsWithResult(pArg, 1, (ModeMask & MModImm7Bit) ? UInt7 : Int8, &EvalResult);
  412.         break;
  413.       case eSymbolSize16Bit:
  414.         Value = EvalStrIntExpressionOffsWithResult(pArg, 1, Int16, &EvalResult);
  415.         break;
  416.       case eSymbolSize32Bit:
  417.         Value = EvalStrIntExpressionOffsWithResult(pArg, 1, Int32, &EvalResult);
  418.         break;
  419.       default:
  420.         WrStrErrorPos(ErrNum_InvOpSize, pArg);
  421.         EvalResult.OK = False;
  422.         break;
  423.     }
  424.     if (!EvalResult.OK)
  425.       return EvalResult.OK;
  426.  
  427.     pResult->m = 0;
  428.     if (Value <= 15)
  429.     {
  430.       pResult->vals[0] = 0xe0 | (Value & 0x0f);
  431.       pResult->count = 1;
  432.     }
  433.     else
  434.     {
  435.       pResult->vals[0] = 0xf4;
  436.       pResult->count = 1;
  437.       AppendToVals(pResult, Value, OpSize);
  438.     }
  439.     pResult->immediate_flags = EvalResult.Flags;
  440.     return EvalResult.OK;
  441.   }
  442.  
  443.   /* split off index register '(Rx)': */
  444.  
  445.   IndexSplitPos = FindDispBaseSplitWithQualifier(pArg->str.p_str, &ArgLen, BaseQualifier, "()");
  446.   if (IndexSplitPos > 0)
  447.   {
  448.     String RegStr;
  449.     tStrComp RegComp;
  450.  
  451.     StrCompMkTemp(&RegComp, RegStr, sizeof(RegStr));
  452.     StrCompCopySub(&RegComp, pArg, IndexSplitPos + 1, ArgLen - IndexSplitPos - 2);
  453.     KillPostBlanksStrComp(&RegComp);
  454.     KillPrefBlanksStrComp(&RegComp);
  455.     switch (DecodeReg(&RegComp, &IndexReg, False))
  456.     {
  457.       case eRegAbort:
  458.         return False;
  459.       case eIsReg:
  460.         StrCompShorten(pArg, ArgLen - IndexSplitPos);
  461.         break;
  462.       default:
  463.         break;
  464.     }
  465.   }
  466.  
  467.   /* absolute */
  468.  
  469.   if (*pArg->str.p_str == '/')
  470.     return ProcessAbsolute(pArg, pResult, IndexReg, 0xf3, ModeMask);
  471.  
  472.   /* indirect modes remain (must end on ]) */
  473.  
  474.   KillPostBlanksStrComp(pArg);
  475.   OuterDispSplitPos = FindDispBaseSplitWithQualifier(pArg->str.p_str, &ArgLen, NULL, "[]");
  476.   if (OuterDispSplitPos >= 0)
  477.   {
  478.     tStrComp OuterDisp, InnerComp, InnerDisp;
  479.     LongInt OuterDispValue = 0, InnerDispValue = 0;
  480.     tSymbolSize OuterDispSize = eSymbolSizeUnknown,
  481.                 InnerDispSize = eSymbolSizeUnknown;
  482.     tEvalResult OuterEvalResult, InnerEvalResult;
  483.     tRegEvalResult RegEvalResult;
  484.     int InnerDispSplitPos;
  485.  
  486.     /* split off outer displacement */
  487.  
  488.     StrCompSplitRef(&OuterDisp, &InnerComp, pArg, &pArg->str.p_str[OuterDispSplitPos]);
  489.     StrCompShorten(&InnerComp, 1);
  490.     KillPostBlanksStrComp(&InnerComp);
  491.     KillPrefBlanksStrCompRef(&InnerComp);
  492.     KillPostBlanksStrComp(&OuterDisp);
  493. #if 0
  494.     DumpStrComp("OuterDisp", &OuterDisp);
  495.     DumpStrComp("InnerComp", &InnerComp);
  496. #endif
  497.  
  498.     /* nested indirect? */
  499.  
  500.     InnerDispSplitPos = FindDispBaseSplitWithQualifier(InnerComp.str.p_str, &ArgLen, NULL, "[]");
  501.     if (InnerDispSplitPos >= 0)
  502.     {
  503.       StrCompSplitRef(&InnerDisp, &InnerComp, &InnerComp, &InnerComp.str.p_str[InnerDispSplitPos]);
  504.       StrCompShorten(&InnerComp, 1);
  505.       KillPostBlanksStrComp(&InnerComp);
  506.       KillPrefBlanksStrCompRef(&InnerComp);
  507.       KillPostBlanksStrComp(&InnerDisp);
  508. #if 0
  509.       DumpStrComp("InnerDisp", &InnerDisp);
  510.       DumpStrComp("InnerComp(2)", &InnerComp);
  511. #endif
  512.  
  513.       /* inner comp must be register */
  514.  
  515.       if (!DecodeRegOrPC(&InnerComp, &BaseReg))
  516.         return False;
  517.  
  518.       if (*InnerDisp.str.p_str)
  519.         CutSize(&InnerDisp, &InnerDispSize);
  520.       InnerDispValue = EvalDispOpt(&InnerDisp, &InnerEvalResult, BaseReg == REG_PC);
  521.       if (!InnerEvalResult.OK)
  522.         return False;
  523.       (void)InnerDispValue;
  524.     }
  525.  
  526.     /* postincr/predecr? */
  527.  
  528.     else if (IsPredecrement(&InnerComp, &pResult->vals[0], &RegEvalResult))
  529.     {
  530.       if ((eRegAbort == RegEvalResult) || !check_mode_mask(pArg, ModMem, ModeMask))
  531.         return False;
  532.       if (*OuterDisp.str.p_str)
  533.       {
  534.         WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  535.         return False;
  536.       }
  537.       pResult->vals[0] |= 0xa0;
  538.       pResult->count = 1;
  539.       pResult->m = 1;
  540.       return True;
  541.     }
  542.  
  543.     else if (IsPostincrement(&InnerComp, &pResult->vals[0], &RegEvalResult))
  544.     {
  545.       if ((eRegAbort == RegEvalResult) || !check_mode_mask(pArg, ModMem, ModeMask))
  546.         return False;
  547.       if (*OuterDisp.str.p_str)
  548.       {
  549.         WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  550.         return False;
  551.       }
  552.       pResult->vals[0] |= 0x80;
  553.       pResult->count = 1;
  554.       pResult->m = 1;
  555.       return True;
  556.     }
  557.  
  558.     /* direct deferred: */
  559.  
  560.     else if (*InnerComp.str.p_str == '/')
  561.       return ProcessAbsolute(&InnerComp, pResult, IndexReg, 0xfb, ModeMask);
  562.  
  563.     /* no pre/post, double indir, direct -> must be plain register */
  564.  
  565.     else
  566.     {
  567.       if (!DecodeRegOrPC(&InnerComp, &BaseReg))
  568.         return False;
  569.     }
  570.  
  571.     /* for both single & double indirect, outer displacement */
  572.  
  573.     if (*OuterDisp.str.p_str)
  574.       CutSize(&OuterDisp, &OuterDispSize);
  575.     OuterDispValue = EvalDispOpt(&OuterDisp, &OuterEvalResult, (BaseReg == REG_PC) && (InnerDispSplitPos < 0));
  576.     if (!OuterEvalResult.OK)
  577.       return False;
  578.  
  579.     /* now, decide about the whole mess: no double []: */
  580.  
  581.     if (InnerDispSplitPos < 0)
  582.     {
  583.       /* [Rn] */
  584.  
  585.       if (!*OuterDisp.str.p_str && (BaseReg != REG_PC))
  586.       {
  587.         if (!check_mode_mask(pArg, ModMem, ModeMask))
  588.           return False;
  589.         if (IndexReg != REGSYM_FLAG_ALIAS)
  590.         {
  591.           pResult->vals[pResult->count++] = 0xc0 | IndexReg;
  592.           pResult->vals[pResult->count++] = 0x60 | BaseReg;
  593.           pResult->m = 1;
  594.         }
  595.         else
  596.         {
  597.           pResult->vals[pResult->count++] = 0x60 | BaseReg;
  598.           pResult->m = 0;
  599.         }
  600.         return True;
  601.       }
  602.  
  603.       pResult->forced_disp_size = InnerDispSize;
  604.       if (!DeduceAndCheckDispSize(&OuterDisp, OuterDispValue, &OuterDispSize, &OuterEvalResult))
  605.         return False;
  606.  
  607.       if (IndexReg != REGSYM_FLAG_ALIAS)
  608.       {
  609.         pResult->vals[pResult->count++] = 0xc0 | IndexReg;
  610.         pResult->m = 1;
  611.       }
  612.       else
  613.         pResult->m = 0;
  614.       if (REG_PC == BaseReg)
  615.         pResult->vals[pResult->count++] = 0xf0 + OuterDispSize;
  616.       else
  617.         pResult->vals[pResult->count++] = (OuterDispSize << 5) | BaseReg;
  618.       AppendToVals(pResult, OuterDispValue, OuterDispSize);
  619.     }
  620.  
  621.     /* double [[]] and no outer displacement: */
  622.  
  623.     else if (!*OuterDisp.str.p_str)
  624.     {
  625.       pResult->forced_disp_size = InnerDispSize;
  626.       if (!DeduceAndCheckDispSize(&InnerDisp, InnerDispValue, &InnerDispSize, &InnerEvalResult))
  627.         return False;
  628.  
  629.       if (IndexReg != REGSYM_FLAG_ALIAS)
  630.       {
  631.         pResult->vals[pResult->count++] = 0xc0 | IndexReg;
  632.         pResult->m = 1;
  633.       }
  634.       else
  635.         pResult->m = 0;
  636.       if (REG_PC == BaseReg)
  637.         pResult->vals[pResult->count++] = 0xf8 + InnerDispSize;
  638.       else
  639.         pResult->vals[pResult->count++] = 0x80 | (InnerDispSize << 5) | BaseReg;
  640.       AppendToVals(pResult, InnerDispValue, InnerDispSize);
  641.     }
  642.  
  643.     /* double [[]] and both displacements - no index register allowed! */
  644.  
  645.     else if (IndexReg != REGSYM_FLAG_ALIAS)
  646.     {
  647.       WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  648.       return False;
  649.     }
  650.     else
  651.     {
  652.       /* Both displacements must have same size.  If both are left undefined, use the maximum needed: */
  653.  
  654.       if ((InnerDispSize == eSymbolSizeUnknown) && (OuterDispSize == eSymbolSizeUnknown))
  655.       {
  656.         DeduceAndCheckDispSize(&InnerDisp, InnerDispValue, &InnerDispSize, &InnerEvalResult);
  657.         DeduceAndCheckDispSize(&OuterDisp, OuterDispValue, &OuterDispSize, &OuterEvalResult);
  658.         if (InnerDispSize > OuterDispSize)
  659.           OuterDispSize = InnerDispSize;
  660.         else if (OuterDispSize > InnerDispSize)
  661.           InnerDispSize = OuterDispSize;
  662.       }
  663.  
  664.       /* Otherwise, accept one size hint also for the other displacement: */
  665.  
  666.       else
  667.       {
  668.         if (InnerDispSize == eSymbolSizeUnknown)
  669.           pResult->forced_disp_size = InnerDispSize = OuterDispSize;
  670.         else if (OuterDispSize == eSymbolSizeUnknown)
  671.           pResult->forced_disp_size = OuterDispSize = InnerDispSize;
  672.         if (InnerDispSize != OuterDispSize)
  673.         {
  674.           WrStrErrorPos(ErrNum_ConfOpSizes, pArg);
  675.           return False;
  676.         }
  677.         else
  678.           pResult->forced_disp_size = OuterDispSize;
  679.         if (!DeduceAndCheckDispSize(&InnerDisp, InnerDispValue, &InnerDispSize, &InnerEvalResult)
  680.          || !DeduceAndCheckDispSize(&OuterDisp, OuterDispValue, &OuterDispSize, &OuterEvalResult))
  681.           return False;
  682.       }
  683.  
  684.       if (REG_PC == BaseReg)
  685.       {
  686.         pResult->vals[pResult->count++] = 0xfc + InnerDispSize;
  687.         pResult->m = 0;
  688.       }
  689.       else
  690.       {
  691.         pResult->vals[pResult->count++] = (InnerDispSize << 5) | BaseReg;
  692.         pResult->m = 1;
  693.       }
  694.       AppendToVals(pResult, InnerDispValue, InnerDispSize);
  695.       AppendToVals(pResult, OuterDispValue, OuterDispSize);
  696.     }
  697.   }
  698.   else
  699.   {
  700.     tSymbolSize DispSize = eSymbolSizeUnknown;
  701.     LongInt DispValue;
  702.  
  703.     /* bare address: register? */
  704.  
  705.     switch (DecodeReg(pArg, pResult->vals, False))
  706.     {
  707.       case eIsReg:
  708.         if (!check_mode_mask(pArg, ModReg, ModeMask))
  709.           return False;
  710.         if (((OpSize == eSymbolSize64Bit) || (OpSize == eSymbolSizeFloat64Bit))
  711.          && (pResult->vals[0] == 31))
  712.           WrStrErrorPos(ErrNum_Unpredictable, pArg);
  713.         pResult->vals[0] |= 0x60;
  714.         pResult->m = 1;
  715.         pResult->count = 1;
  716.         return True;
  717.       case eRegAbort:
  718.         return False;
  719.       default:
  720.         break;
  721.     }
  722.  
  723.     /* treat bare address as PC-relative */
  724.  
  725.     CutSize(pArg, &DispSize);
  726.     DispValue = EvalDispOpt(pArg, &EvalResult, True);
  727.     if (!EvalResult.OK)
  728.       return False;
  729.     pResult->forced_disp_size = DispSize;
  730.     if (!DeduceAndCheckDispSize(pArg, DispValue, &DispSize, &EvalResult))
  731.       return False;
  732.     if (IndexReg != REGSYM_FLAG_ALIAS)
  733.     {
  734.       pResult->vals[pResult->count++] = 0xc0 | IndexReg;
  735.       pResult->m = 1;
  736.     }
  737.     else
  738.       pResult->m = 0;
  739.     pResult->vals[pResult->count++] = 0xf0 + DispSize;
  740.     AppendToVals(pResult, DispValue, DispSize);
  741.   }
  742.  
  743.   return (pResult->count > 0) && check_mode_mask(pArg, ModMem, ModeMask);
  744. }
  745.  
  746. /*!------------------------------------------------------------------------
  747.  * \fn     IsReg(const tAdrVals *p_vals)
  748.  * \brief  check whether encoded address expression is register-direct ( Rn )
  749.  * \param  p_vals encoded address expression
  750.  * \return True if yes
  751.  * ------------------------------------------------------------------------ */
  752.  
  753. static Boolean IsReg(const tAdrVals *p_vals)
  754. {
  755.   return ((p_vals->count == 1)
  756.        && (p_vals->m == 1)
  757.        && ((p_vals->vals[0] & 0xe0) == 0x60));
  758. }
  759.  
  760. /*!------------------------------------------------------------------------
  761.  * \fn     IsRegIndirect(const tAdrVals *p_vals)
  762.  * \brief  check whether encoded address expression is register indirect ( [Rn] )
  763.  * \param  p_vals encoded address expression
  764.  * \return True if yes
  765.  * ------------------------------------------------------------------------ */
  766.  
  767. static Boolean IsRegIndirect(const tAdrVals *p_vals)
  768. {
  769.   return ((p_vals->count == 1)
  770.        && (p_vals->m == 0)
  771.        && ((p_vals->vals[0] & 0xe0) == 0x60));
  772. }
  773.  
  774. /*!------------------------------------------------------------------------
  775.  * \fn     IsPreDecrement(const tAdrVals *p_vals, Byte *p_reg)
  776.  * \brief  check whether encoded address expression is pre-decrement ( [-Rn] )
  777.  * \param  p_vals encoded address expression
  778.  * \param  p_reg return buffer for used register
  779.  * \return True if yes
  780.  * ------------------------------------------------------------------------ */
  781.  
  782. static Boolean IsPreDecrement(const tAdrVals *p_vals, Byte *p_reg)
  783. {
  784.   if ((p_vals->count == 1)
  785.    && (p_vals->m == 1)
  786.    && ((p_vals->vals[0] & 0xe0) == 0xa0))
  787.   {
  788.     if (p_reg) *p_reg = p_vals->vals[0] & 0x1f;
  789.     return True;
  790.   }
  791.   else
  792.     return False;
  793. }
  794.  
  795. /*!------------------------------------------------------------------------
  796.  * \fn     IsPostIncrement(const tAdrVals *p_vals, Byte *p_reg)
  797.  * \brief  check whether encoded address expression is post-increment ( [Rn+] )
  798.  * \param  p_vals encoded address expression
  799.  * \param  p_reg return buffer for used register
  800.  * \return True if yes
  801.  * ------------------------------------------------------------------------ */
  802.  
  803. static Boolean IsPostIncrement(const tAdrVals *p_vals, Byte *p_reg)
  804. {
  805.   if ((p_vals->count == 1)
  806.    && (p_vals->m == 1)
  807.    && ((p_vals->vals[0] & 0xe0) == 0x80))
  808.   {
  809.     if (p_reg) *p_reg = p_vals->vals[0] & 0x1f;
  810.     return True;
  811.   }
  812.   else
  813.     return False;
  814. }
  815.  
  816. /*!------------------------------------------------------------------------
  817.  * \fn     IsAbsolute(const tAdrVals *p_vals)
  818.  * \brief  check whether encoded address expression is absolute ( /abs )
  819.  * \param  p_vals encoded address expression
  820.  * \return True if yes
  821.  * ------------------------------------------------------------------------ */
  822.  
  823. static Boolean IsAbsolute(const tAdrVals *p_vals)
  824. {
  825.   return ((p_vals->count == 5)
  826.        && (p_vals->m == 0)
  827.        && (p_vals->vals[0] == 0xf3));
  828. }
  829.  
  830. /*!------------------------------------------------------------------------
  831.  * \fn     IsAbsoluteIndirect(const tAdrVals *p_vals)
  832.  * \brief  check whether encoded address expression is absolute indirect ( [/abs] )
  833.  * \param  p_vals encoded address expression
  834.  * \return True if yes
  835.  * ------------------------------------------------------------------------ */
  836.  
  837. static Boolean IsAbsoluteIndirect(const tAdrVals *p_vals)
  838. {
  839.   return ((p_vals->count == 5)
  840.        && (p_vals->m == 0)
  841.        && (p_vals->vals[0] == 0xfb));
  842. }
  843.  
  844. /*!------------------------------------------------------------------------
  845.  * \fn     IsDisplacement(const tAdrVals *p_vals)
  846.  * \brief  check whether encoded address expression is displacement
  847.  * \param  p_vals encoded address expression
  848.  * \return True if yes
  849.  * ------------------------------------------------------------------------ */
  850.  
  851. static Boolean IsDisplacement(const tAdrVals *p_vals)
  852. {
  853.   Byte base_mode = p_vals->vals[0],
  854.        base_mode_mode = base_mode & 0xe0;
  855.  
  856.   return (p_vals->m == 0)
  857.       && (p_vals->count > 1)
  858.       && ((base_mode_mode == 0x000) /* disp8[Rn]  */
  859.        || (base_mode      == 0x0f0) /* disp8[PC]  */
  860.        || (base_mode_mode == 0x020) /* disp16[Rn] */
  861.        || (base_mode      == 0x0f1) /* disp16[PC] */
  862.        || (base_mode_mode == 0x040) /* disp32[Rn] */
  863.        || (base_mode      == 0x0f2)); /* disp32[PC] */
  864. }
  865.  
  866. /*!------------------------------------------------------------------------
  867.  * \fn     IsIndirectDisplacement(const tAdrVals *p_vals)
  868.  * \brief  check whether encoded address expression is indirect displacement
  869.  * \param  p_vals encoded address expression
  870.  * \return True if yes
  871.  * ------------------------------------------------------------------------ */
  872.  
  873. static Boolean IsIndirectDisplacement(const tAdrVals *p_vals)
  874. {
  875.   Byte base_mode = p_vals->vals[0],
  876.        base_mode_mode = base_mode & 0xe0;
  877.  
  878.   return (p_vals->m == 0)
  879.       && (p_vals->count > 1)
  880.       && ((base_mode_mode == 0x080) /* [disp8[Rn]]  */
  881.        || (base_mode      == 0x0f8) /* [disp8[PC]]  */
  882.        || (base_mode_mode == 0x0a0) /* [disp16[Rn]] */
  883.        || (base_mode      == 0x0f9) /* [disp16[PC]] */
  884.        || (base_mode_mode == 0x0c0) /* [disp32[Rn]] */
  885.        || (base_mode      == 0x0fa)); /* [disp32[PC]] */
  886. }
  887.  
  888. /*!------------------------------------------------------------------------
  889.  * \fn     IsImmediate(const tAdrVals *p_adr_vals, LongWord *p_imm_value)
  890.  * \brief  check whether encoded address expression is immediate
  891.  * \param  p_vals encoded address expression
  892.  * \param  p_imm_value return buffer for immediate value
  893.  * \return True if immediate
  894.  * ------------------------------------------------------------------------ */
  895.  
  896. static Boolean IsImmediate(const tAdrVals *p_adr_vals, LongWord *p_imm_value)
  897. {
  898.   if ((p_adr_vals->vals[0] & 0xf0) == 0xe0)
  899.   {
  900.     *p_imm_value = p_adr_vals->vals[0] & 0x0f;
  901.     return True;
  902.   }
  903.   else if ((p_adr_vals->vals[0] == 0xf4) && (p_adr_vals->count > 1))
  904.   {
  905.     unsigned z;
  906.  
  907.     *p_imm_value = 0;
  908.     for (z = p_adr_vals->count - 1; z > 0; z--)
  909.       *p_imm_value = (*p_imm_value << 8) | p_adr_vals->vals[z];
  910.     return True;
  911.   }
  912.   else
  913.     return False;
  914. }
  915.  
  916. /*!------------------------------------------------------------------------
  917.  * \fn     IsSPAutoIncDec(const tAdrVals *p_adr_vals)
  918.  * \brief  check whether encoded address expression is auto-increment/decrement with SP
  919.  * \param  p_adr_vals encoded address expression
  920.  * \return True if yes
  921.  * ------------------------------------------------------------------------ */
  922.  
  923. static Boolean IsSPAutoIncDec(const tAdrVals *p_adr_vals)
  924. {
  925.   return ((p_adr_vals->count == 1)
  926.        && p_adr_vals->m
  927.        && ((p_adr_vals->vals[0] == (0x80 | REG_SP))
  928.         || (p_adr_vals->vals[0] == (0xa0 | REG_SP))));
  929. }
  930.  
  931. /*!------------------------------------------------------------------------
  932.  * \fn     IsIndexed(const tAdrVals *p_adr_vals, Byte *p_reg)
  933.  * \brief  check whether encoded address expression uses an index register
  934.  * \param  p_adr_vals encoded address expression
  935.  * \param  p_reg return buffer for index register if yes
  936.  * \return True if yes
  937.  * ------------------------------------------------------------------------ */
  938.  
  939. static Boolean IsIndexed(const tAdrVals *p_adr_vals, Byte *p_reg)
  940. {
  941.   if ((p_adr_vals->count >= 1)
  942.    && p_adr_vals->m
  943.    && ((p_adr_vals->vals[0] & 0xe0) == 0xc0))
  944.   {
  945.     if (p_reg) *p_reg = p_adr_vals->vals[0] & 0x1f;
  946.     return True;
  947.   }
  948.   else
  949.     return False;
  950. }
  951.  
  952. /*!------------------------------------------------------------------------
  953.  * \fn     DecodeBitAdr(tStrComp *p_arg, tAdrVals *p_result, unsigned ModeMask)
  954.  * \brief  parse bit address expression
  955.  * \param  p_arg source argument
  956.  * \param  p_result result buffer
  957.  * \return True if success
  958.  * ------------------------------------------------------------------------ */
  959.  
  960. static void insert_index(tAdrVals *p_result, Byte index_reg)
  961. {
  962.   memmove(p_result->vals + 1, p_result->vals, p_result->count);
  963.   p_result->vals[0] = 0xc0 | index_reg;
  964.   p_result->count++;
  965.   p_result->m = 1;
  966. }
  967.  
  968. static void extend_adrvals_size(tAdrVals *p_result, tSymbolSize *p_curr_size, tSymbolSize target_size, Byte mod_incr)
  969. {
  970.   while (*p_curr_size < target_size)
  971.   {
  972.     Byte ext = (p_result->vals[p_result->count - 1] & 0x80) ? 0xff : 0x00;
  973.     p_result->vals[0] += mod_incr;
  974.     *p_curr_size = (tSymbolSize)(*p_curr_size + 1);
  975.     switch (*p_curr_size)
  976.     {
  977.       case eSymbolSize32Bit:
  978.         p_result->vals[p_result->count++] = ext;
  979.         /* FALL-THRU */
  980.       case eSymbolSize16Bit:
  981.         p_result->vals[p_result->count++] = ext;
  982.         break;
  983.       default:
  984.         break;
  985.     }
  986.   }
  987. }
  988.  
  989. static Boolean DecodeBitAdr(tStrComp *p_arg, tAdrVals *p_result, unsigned ModeMask)
  990. {
  991.   char *p_sep;
  992.   tStrComp offset_arg, base_arg;
  993.   Byte offs_reg;
  994.   tEvalResult eval_result;
  995.  
  996.   /* find '@' that separates bit offset & byte base address, which MUST be present: */
  997.  
  998.   p_sep = QuotPos(p_arg->str.p_str, '@');
  999.   if (!p_sep)
  1000.   {
  1001.     WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  1002.     return False;
  1003.   }
  1004.   StrCompSplitRef(&offset_arg, &base_arg, p_arg, p_sep);
  1005.   KillPostBlanksStrComp(&offset_arg);
  1006.   KillPrefBlanksStrCompRef(&base_arg);
  1007.  
  1008.   /* parse the base address */
  1009.  
  1010.   (void)ModeMask;
  1011.   if (!DecodeAdr(&base_arg, p_result, MModMem))
  1012.     return False;
  1013.  
  1014.   /* no offset: the encoding remains the same, just check for valid addressing modes: */
  1015.  
  1016.   if (!offset_arg.str.p_str[0])
  1017.   {
  1018.     eval_result.OK =
  1019.          IsRegIndirect(p_result)
  1020.       || IsPostIncrement(p_result, NULL)
  1021.       || IsPreDecrement(p_result, NULL)
  1022.       || IsIndirectDisplacement(p_result)
  1023.       || IsAbsolute(p_result)
  1024.       || IsAbsoluteIndirect(p_result);
  1025.     if (!eval_result.OK)
  1026.       WrStrErrorPos(ErrNum_InvAddrMode, &base_arg);
  1027.   }
  1028.  
  1029.   else switch (DecodeReg(&offset_arg, &offs_reg, False))
  1030.   {
  1031.     /* offset is register: if this is a valid addressing mode, insert register
  1032.        as index register: */
  1033.  
  1034.     case eIsReg:
  1035.       eval_result.OK = True;
  1036.       if (IsRegIndirect(p_result)
  1037.        || IsDisplacement(p_result)
  1038.        || IsIndirectDisplacement(p_result)
  1039.        || IsAbsolute(p_result)
  1040.        || IsAbsoluteIndirect(p_result))
  1041.         insert_index(p_result, offs_reg);
  1042.       else
  1043.         eval_result.OK = False;
  1044.       if (!eval_result.OK)
  1045.         WrStrErrorPos(ErrNum_InvAddrMode, &base_arg);
  1046.       break;
  1047.  
  1048.     /* offset is immediate value: */
  1049.  
  1050.     case eIsNoReg:
  1051.     {
  1052.       tSymbolSize forced_offset_size = eSymbolSizeUnknown, offset_size;
  1053.  
  1054.       CutSize(&offset_arg, &forced_offset_size);
  1055.       p_result->bit_offset = EvalStrIntExpressionWithResult(&offset_arg, SInt32, &eval_result);
  1056.       if (!eval_result.OK)
  1057.         break;
  1058.       p_result->immediate_flags = eval_result.Flags;
  1059.       offset_size = forced_offset_size;
  1060.       if (!(eval_result.OK = DeduceAndCheckDispSize(&offset_arg, p_result->bit_offset, &offset_size, &eval_result)))
  1061.         break;
  1062.  
  1063.       /* base addressing mode has no displacement so far: append as first displacement */
  1064.  
  1065.       if (IsRegIndirect(p_result))
  1066.       {
  1067.         p_result->vals[0] = (p_result->vals[0] & 0x1f) | (offset_size << 5);
  1068.         AppendToVals(p_result, p_result->bit_offset, offset_size);
  1069.       }
  1070.  
  1071.       /* single (indirect) displacement becomes double displacement */
  1072.  
  1073.       else if (IsIndirectDisplacement(p_result))
  1074.       {
  1075.         Boolean base_pc = !!(p_result->vals[0] & 0x10);
  1076.         /* extract operand size of base displacement */
  1077.         tSymbolSize base_disp_size = (tSymbolSize)((p_result->vals[0] >> (base_pc ? 0 : 5)) & 3);
  1078.  
  1079.         /* Similar to disp1 & disp2, base & offset must have same length, so if
  1080.            lengths are unequal, extend one of them, or complain if we cannot make
  1081.            things fit: */
  1082.  
  1083.         /* (1) No explicit length given for either: extend the other one as needed
  1084.            if actual sizes differ: */
  1085.  
  1086.         if ((p_result->forced_disp_size == eSymbolSizeUnknown)
  1087.          && (forced_offset_size == eSymbolSizeUnknown))
  1088.         {
  1089.           if (offset_size < base_disp_size)
  1090.             offset_size = base_disp_size;
  1091.           else if (base_disp_size < offset_size)
  1092.             extend_adrvals_size(p_result, &base_disp_size, offset_size, p_result->vals[0] += base_pc ? 0x01 : 0x20);
  1093.         }
  1094.  
  1095.         /* (2a) Only base displacement size is fixed: see if offset size can be extended */
  1096.  
  1097.         else if (forced_offset_size == eSymbolSizeUnknown)
  1098.         {
  1099.           if (offset_size < base_disp_size)
  1100.             offset_size = base_disp_size;
  1101.           else
  1102.           {
  1103.             WrStrErrorPos(ErrNum_OverRange, &offset_arg);
  1104.             return False;
  1105.           }
  1106.         }
  1107.  
  1108.         /* (2b) Vice versa, if only offset size is fixed: */
  1109.  
  1110.         else if (p_result->forced_disp_size == eSymbolSizeUnknown)
  1111.         {
  1112.           if (base_disp_size < offset_size)
  1113.             extend_adrvals_size(p_result, &base_disp_size, offset_size, p_result->vals[0] += base_pc ? 0x01 : 0x20);
  1114.           else
  1115.           {
  1116.             WrStrErrorPos(ErrNum_OverRange, &base_arg);
  1117.             return False;
  1118.           }
  1119.         }
  1120.  
  1121.         /* (3) if both sizes are fixed, they must be equal: */
  1122.  
  1123.         else if (p_result->forced_disp_size != forced_offset_size)
  1124.         {
  1125.           WrStrErrorPos(ErrNum_ConfOpSizes, p_arg);
  1126.           return False;
  1127.         }
  1128.  
  1129.         /* All fine: Change addressing mode to double displacement,
  1130.            and add bit offset as second displacement */
  1131.  
  1132.         if (base_pc)
  1133.           p_result->vals[0] |= 0x04;
  1134.         else
  1135.         {
  1136.           p_result->m = 1;
  1137.           p_result->vals[0] &= ~0x80;
  1138.         }
  1139.         AppendToVals(p_result, p_result->bit_offset, offset_size);
  1140.       }
  1141.  
  1142.       /* everything else not allowed */
  1143.  
  1144.       else
  1145.       {
  1146.         WrStrErrorPos(ErrNum_InvAddrMode, &base_arg);
  1147.         eval_result.OK = False;
  1148.       }
  1149.  
  1150.       p_result->bit_offset_immediate = True;
  1151.       break;
  1152.     }
  1153.     default: /* eRegAbort */
  1154.       eval_result.OK = False;
  1155.   }
  1156.  
  1157.   return eval_result.OK;
  1158. }
  1159.  
  1160. /*--------------------------------------------------------------------------*/
  1161. /* Utility Functions */
  1162.  
  1163. /*!------------------------------------------------------------------------
  1164.  * \fn     ChkNoAttrPart(void)
  1165.  * \brief  check for no attribute part
  1166.  * \return True if no attribute
  1167.  * ------------------------------------------------------------------------ */
  1168.  
  1169. static Boolean ChkNoAttrPart(void)
  1170. {
  1171.   if (*AttrPart.str.p_str)
  1172.   {
  1173.     WrError(ErrNum_UseLessAttr);
  1174.     return False;
  1175.   }
  1176.   return True;
  1177. }
  1178.  
  1179. /*!------------------------------------------------------------------------
  1180.  * \fn     ChkOpSize(int Op8, int Op16, int Op32, int Op64)
  1181.  * \brief  check for valid (single) (integer) operand size
  1182.  * \param  Op8 machine code if size is 8 bits
  1183.  * \param  Op16 machine code if size is 16 bits
  1184.  * \param  Op32 machine code if size is 32 bits
  1185.  * \param  Op64 machine code if size is 64 bits
  1186.  * \return True if size is OK
  1187.  * ------------------------------------------------------------------------ */
  1188.  
  1189. static Boolean ChkOpSize(int Op8, int Op16, int Op32, int Op64)
  1190. {
  1191.   if (AttrPartOpSize[1] != eSymbolSizeUnknown)
  1192.   {
  1193.     WrStrErrorPos(ErrNum_InvOpSize, &AttrPart);
  1194.     return False;
  1195.   }
  1196.   if (OpSize == eSymbolSizeUnknown)
  1197.   {
  1198.     if (AttrPartOpSize[0] != eSymbolSizeUnknown)
  1199.       OpSize = AttrPartOpSize[0];
  1200.     else if ((Op8 >= 0) && Hi(Op8))
  1201.       OpSize = eSymbolSize8Bit;
  1202.     else if ((Op16 >= 0) && Hi(Op16))
  1203.       OpSize = eSymbolSize16Bit;
  1204.     else if ((Op32 >= 0) && Hi(Op32))
  1205.       OpSize = eSymbolSize32Bit;
  1206.     else if ((Op64 >= 0) && Hi(Op64))
  1207.       OpSize = eSymbolSize64Bit;
  1208.   }
  1209.   switch (OpSize)
  1210.   {
  1211.     case eSymbolSize8Bit:
  1212.       if (Op8 < 0)
  1213.         goto Bad;
  1214.       BAsmCode[CodeLen] = Op8;
  1215.       return True;
  1216.     case eSymbolSize16Bit:
  1217.       if (Op16 < 0)
  1218.         goto Bad;
  1219.       BAsmCode[CodeLen] = Op16;
  1220.       return True;
  1221.     case eSymbolSize32Bit:
  1222.       if (Op32 < 0)
  1223.         goto Bad;
  1224.       BAsmCode[CodeLen] = Op32;
  1225.       return True;
  1226.     case eSymbolSize64Bit:
  1227.       if (Op64 < 0)
  1228.         goto Bad;
  1229.       BAsmCode[CodeLen] = Op64;
  1230.       return True;
  1231.     default:
  1232.     Bad:
  1233.       WrStrErrorPos(ErrNum_InvOpSize, &OpPart);
  1234.       return False;
  1235.   }
  1236. }
  1237.  
  1238. /*!------------------------------------------------------------------------
  1239.  * \fn     ChkFOpSize(int op_short, int op_long)
  1240.  * \brief  check for valid (real) operand size
  1241.  * \param  op_short machine code if size short real
  1242.  * \param  op_long machine code if size is long real
  1243.  * \return True if size is OK
  1244.  * ------------------------------------------------------------------------ */
  1245.  
  1246. static Boolean ChkFOpSize(int op_short, int op_long)
  1247. {
  1248.   if (AttrPartOpSize[1] != eSymbolSizeUnknown)
  1249.   {
  1250.     WrStrErrorPos(ErrNum_InvOpSize, &AttrPart);
  1251.     return False;
  1252.   }
  1253.   if (OpSize == eSymbolSizeUnknown)
  1254.   {
  1255.     if (AttrPartOpSize[0] != eSymbolSizeUnknown)
  1256.       OpSize = AttrPartOpSize[0];
  1257.     else if ((op_short >= 0) && Hi(op_short))
  1258.       OpSize = eSymbolSizeFloat32Bit;
  1259.     else if ((op_long >= 0) && Hi(op_long))
  1260.       OpSize = eSymbolSizeFloat64Bit;
  1261.   }
  1262.   switch (OpSize)
  1263.   {
  1264.     case eSymbolSizeFloat32Bit:
  1265.       if (op_short < 0)
  1266.         goto Bad;
  1267.       BAsmCode[CodeLen] = op_short;
  1268.       return True;
  1269.     case eSymbolSizeFloat64Bit:
  1270.       if (op_long < 0)
  1271.         goto Bad;
  1272.       BAsmCode[CodeLen] = op_long;
  1273.       return True;
  1274.     default:
  1275.     Bad:
  1276.       WrStrErrorPos(ErrNum_InvOpSize, &OpPart);
  1277.       return False;
  1278.   }
  1279. }
  1280.  
  1281. /*!------------------------------------------------------------------------
  1282.  * \fn     ChkPtrOpSize(int op_ptr)
  1283.  * \brief  check for valid (pointer) operand size
  1284.  * \param  op_ptr machine code if size is pointer
  1285.  * \return True if size is OK
  1286.  * ------------------------------------------------------------------------ */
  1287.  
  1288. static Boolean ChkPtrOpSize(int op_ptr)
  1289. {
  1290.   if (AttrPartOpSize[1] != eSymbolSizeUnknown)
  1291.   {
  1292.     WrStrErrorPos(ErrNum_InvOpSize, &AttrPart);
  1293.     return False;
  1294.   }
  1295.   if (OpSize == eSymbolSizeUnknown)
  1296.   {
  1297.     if (AttrPartOpSize[0] != eSymbolSizeUnknown)
  1298.       OpSize = AttrPartOpSize[0];
  1299.     else if ((op_ptr >= 0) && Hi(op_ptr))
  1300.       OpSize = eSymbolSize24Bit;
  1301.   }
  1302.   switch (OpSize)
  1303.   {
  1304.     case eSymbolSize24Bit:
  1305.       if (op_ptr < 0)
  1306.         goto Bad;
  1307.       OpSize = eSymbolSize32Bit;
  1308.       BAsmCode[CodeLen] = Lo(op_ptr);
  1309.       return True;
  1310.     default:
  1311.     Bad:
  1312.       WrStrErrorPos(ErrNum_InvOpSize, &OpPart);
  1313.       return False;
  1314.   }
  1315. }
  1316.  
  1317. /*!------------------------------------------------------------------------
  1318.  * \fn     chk_sup_mode(Word code)
  1319.  * \brief  check whether privileged instructions are enabled
  1320.  * \param  code machine code with sup mode flag
  1321.  * \return True if enabled or not required
  1322.  * ------------------------------------------------------------------------ */
  1323.  
  1324. static Boolean chk_sup_mode(Word code)
  1325. {
  1326.   if ((code & CODE_FLAG_SUPMODE) && !SupAllowed)
  1327.   {
  1328.     WrStrErrorPos(ErrNum_PrivOrder, &OpPart);
  1329.     return False;
  1330.   }
  1331.   else
  1332.     return True;
  1333. }
  1334.  
  1335. /*!------------------------------------------------------------------------
  1336.  * \fn     AppendAdrVals(const tAdrVals *p_vals)
  1337.  * \brief  append addressing mode extension values to instruction
  1338.  * \param  p_vals holds encoded addressing expression
  1339.  * ------------------------------------------------------------------------ */
  1340.  
  1341. static void AppendAdrVals(const tAdrVals *p_vals)
  1342. {
  1343.   memcpy(&BAsmCode[CodeLen], p_vals->vals, p_vals->count);
  1344.   CodeLen += p_vals->count;
  1345. }
  1346.  
  1347. /*!------------------------------------------------------------------------
  1348.  * \fn     DecodeLength(tStrComp *p_arg, tLenVals *p_len_vals)
  1349.  * \brief  decode length argument of bit string insns
  1350.  * \param  p_arg source argument
  1351.  * \param  p_len_vals encoded length argument
  1352.  * \return True if success
  1353.  * ------------------------------------------------------------------------ */
  1354.  
  1355. static Boolean DecodeLength(tStrComp *p_arg, tLenVals *p_len_vals)
  1356. {
  1357.   tAdrVals adr_vals;
  1358.   LongWord length;
  1359.  
  1360.   if (!DecodeAdr(p_arg, &adr_vals, MModReg | MModImm | MModImm7Bit))
  1361.     return False;
  1362.   p_len_vals->immediate_flags = adr_vals.immediate_flags;
  1363.   if (IsReg(&adr_vals))
  1364.     p_len_vals->val = 0x80 | (adr_vals.vals[0] & 0x1f);
  1365.   else if (IsImmediate(&adr_vals, &length))
  1366.     p_len_vals->val = length & 127;
  1367.   else
  1368.   {
  1369.     WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  1370.     return False;
  1371.   }
  1372.   return True;
  1373. }
  1374.  
  1375. /*!------------------------------------------------------------------------
  1376.  * \fn     IsImmediateLength(const tLenVals *p_len_vals, LongWord *p_imm_val)
  1377.  * \brief  check whether encoded bit field length is immediate value
  1378.  * \param  p_len_vals encoded length field from instruction
  1379.  * \param  p_imm_val return buffer if immediate
  1380.  * \return True if yes
  1381.  * ------------------------------------------------------------------------ */
  1382.  
  1383. static Boolean IsImmediateLength(const tLenVals *p_len_vals, LongWord *p_imm_val)
  1384. {
  1385.   if (p_len_vals->val & 0x80)
  1386.     return False;
  1387.   else
  1388.   {
  1389.     *p_imm_val = p_len_vals->val & 0x7f;
  1390.     return True;
  1391.   }
  1392. }
  1393.  
  1394. /*!------------------------------------------------------------------------
  1395.  * \fn     imm_mask_cond(Word code)
  1396.  * \brief  check whether immediate mode is allowed and return accordingly
  1397.  * \param  code machine code holding CODE_FLAG_OP2_IMM in MSB or not
  1398.  * \return immediate mask if allowed or 0
  1399.  * ------------------------------------------------------------------------ */
  1400.  
  1401. static unsigned imm_mask_cond(Word code)
  1402. {
  1403.   return (code & CODE_FLAG_OP2_IMM) ? MModImm : 0;
  1404. }
  1405.  
  1406. /*!------------------------------------------------------------------------
  1407.  * \fn     check_addrmodes_unpredictable(const tAdrVals *p_first_vals, const tAdrVals *p_second_vals)
  1408.  * \brief  check whether the combination of two addressing modes may yield unpredictable results
  1409.  * \param  p_first_vals encoded first operand
  1410.  * \param  p_second_vals encoded second operand
  1411.  * \return True if unpredictable result may occur
  1412.  * ------------------------------------------------------------------------ */
  1413.  
  1414. static Boolean check_addrmodes_unpredictable(const tAdrVals *p_first_vals, const tAdrVals *p_second_vals)
  1415. {
  1416.   Byte first_reg = 0, second_reg = 0;
  1417.  
  1418.   /* For all unpredictable combinations, first operand must be auto-increment: */
  1419.  
  1420.   if (!IsPreDecrement(p_first_vals, &first_reg)
  1421.    && !IsPostIncrement(p_first_vals, &first_reg))
  1422.     return False;
  1423.  
  1424.   /* If second operand is auto-increment with same register,
  1425.      result is unpredictable if both operand sizes differ: */
  1426.  
  1427.   if ((IsPreDecrement(p_second_vals, &second_reg) || IsPostIncrement(p_second_vals, &second_reg))
  1428.    && (second_reg == first_reg)
  1429.    && (p_first_vals->data_op_size != p_second_vals->data_op_size))
  1430.   {
  1431.     WrError(ErrNum_Unpredictable);
  1432.     return True;
  1433.   }
  1434.  
  1435.   /* If second operand uses same register as index register,
  1436.      result is unpredictable: */
  1437.  
  1438.   else if (IsIndexed(p_second_vals, &second_reg) && (second_reg == first_reg))
  1439.   {
  1440.     WrError(ErrNum_Unpredictable);
  1441.     return True;
  1442.   }
  1443.  
  1444.   else
  1445.     return False;
  1446. }
  1447.  
  1448. /*!------------------------------------------------------------------------
  1449.  * \fn     EncodeFormat1(Byte Reg, const tAdrVals *pSecond)
  1450.  * \brief  encode instruction in format I
  1451.  * \param  Reg Register# + direction bit
  1452.  * \param  pSecond second operand
  1453.  * ------------------------------------------------------------------------ */
  1454.  
  1455. static void EncodeFormat1(Byte Reg, const tAdrVals *pSecond)
  1456. {
  1457.   CodeLen++;
  1458.   BAsmCode[CodeLen++] = Reg | (pSecond->m << 6);
  1459.   AppendAdrVals(pSecond);
  1460. }
  1461.  
  1462. /*!------------------------------------------------------------------------
  1463.  * \fn     EncodeFormat2(Byte SubOp, const tAdrVals *pFirst, const tAdrVals *pSecond)
  1464.  * \brief  encode instruction in format II
  1465.  * \param  SubOp extension byte
  1466.  * \param  pFirst first operand
  1467.  * \param  pSecond second operand
  1468.  * ------------------------------------------------------------------------ */
  1469.  
  1470. static void EncodeFormat2(Byte SubOp, const tAdrVals *pFirst, const tAdrVals *pSecond)
  1471. {
  1472.   CodeLen++;
  1473.   BAsmCode[CodeLen++] = SubOp | 0x80 | (pSecond->m << 5) | (pFirst->m << 6);
  1474.   AppendAdrVals(pFirst);
  1475.   AppendAdrVals(pSecond);
  1476.   check_addrmodes_unpredictable(pFirst, pSecond);
  1477. }
  1478.  
  1479. /*!------------------------------------------------------------------------
  1480.  * \fn     EncodeFormat1Or2(Byte SubOp, const tAdrVals *pFirst, const tAdrVals *pSecond)
  1481.  * \brief  encode instruction in format I if possible or format II
  1482.  * \param  SubOp extension byte for format II
  1483.  * \param  pFirst first operand
  1484.  * \param  pSecond second operand
  1485.  * ------------------------------------------------------------------------ */
  1486.  
  1487. static void EncodeFormat1Or2(Byte SubOp, const tAdrVals *pFirst, const tAdrVals *pSecond)
  1488. {
  1489.   if (IsReg(pFirst))
  1490.     EncodeFormat1(pFirst->vals[0] & 0x1f, pSecond);
  1491.   else if (IsReg(pSecond))
  1492.     EncodeFormat1((pSecond->vals[0] & 0x1f) | 0x20, pFirst);
  1493.   else
  1494.     EncodeFormat2(SubOp, pFirst, pSecond);
  1495. }
  1496.  
  1497. /*!------------------------------------------------------------------------
  1498.  * \fn     EncodeFormat3(const tAdrVals *p_adr_vals)
  1499.  * \brief  encode instruction in format III
  1500.  * \param  p_adr_vals operand
  1501.  * ------------------------------------------------------------------------ */
  1502.  
  1503. static void EncodeFormat3(const tAdrVals *p_adr_vals)
  1504. {
  1505.   BAsmCode[CodeLen] |= p_adr_vals->m;
  1506.   CodeLen++;
  1507.   AppendAdrVals(p_adr_vals);
  1508. }
  1509.  
  1510. /*!------------------------------------------------------------------------
  1511.  * \fn     chk_imm_bitfield_range(const tStrComp *p_bitfield_src_arg, const tAdrVals *p_bitfield_adr_vals, const tLenVals *p_len_vals)
  1512.  * \brief  check whether bit field's length plus offset do not exceed allowed range
  1513.  * \param  p_bitfield_src_arg source argument of bit field start+offset
  1514.  * \param  p_bitfield_adr_vals encoded value of bit field start+offset
  1515.  * \param  p_len_vals encoded value of bit field length
  1516.  * ------------------------------------------------------------------------ */
  1517.  
  1518. static void chk_imm_bitfield_range(const tStrComp *p_bitfield_src_arg, const tAdrVals *p_bitfield_adr_vals, const tLenVals *p_len_vals)
  1519. {
  1520.   LongWord imm_length;
  1521.  
  1522.   /* optional check for offset+length <= 32, if possible: */
  1523.  
  1524.   if (p_bitfield_adr_vals->bit_offset_immediate
  1525.    && !mFirstPassUnknownOrQuestionable(p_bitfield_adr_vals->immediate_flags)
  1526.    && IsImmediateLength(p_len_vals, &imm_length)
  1527.    && !mFirstPassUnknownOrQuestionable(p_len_vals->immediate_flags)
  1528.    && (p_bitfield_adr_vals->bit_offset + imm_length > 32))
  1529.   {
  1530.     char Msg[64];
  1531.  
  1532.     as_snprintf(Msg, sizeof(Msg), "%u + %u > 32",
  1533.                 (unsigned)p_bitfield_adr_vals->bit_offset,
  1534.                 (unsigned)imm_length);
  1535.     WrXErrorPos(ErrNum_ArgOutOfRange, Msg, &p_bitfield_src_arg->Pos);
  1536.   }
  1537. }
  1538.  
  1539. /*!------------------------------------------------------------------------
  1540.  * \fn     chk_imm_value_range(const tStrComp *p_src_arg, const tAdrVals *p_adr_vals, const char *p_name, unsigned max_value)
  1541.  * \brief  check whether immediate value is in range
  1542.  * \param  p_arg source argument of value
  1543.  * \param  p_adr_vals encoded value of value
  1544.  * ------------------------------------------------------------------------ */
  1545.  
  1546. static void chk_imm_value_range(const tStrComp *p_src_arg, const tAdrVals *p_adr_vals, const char *p_name, unsigned max_value)
  1547. {
  1548.   LongWord imm_value;
  1549.  
  1550.   if (IsImmediate(p_adr_vals, &imm_value)
  1551.    && !mFirstPassUnknownOrQuestionable(p_adr_vals->immediate_flags)
  1552.    && (imm_value > max_value))
  1553.   {
  1554.     char Msg[64];
  1555.  
  1556.     as_snprintf(Msg, sizeof(Msg), "%s %u > %u",
  1557.                 p_name, (unsigned)imm_value, max_value);
  1558.     WrXErrorPos(ErrNum_ArgOutOfRange, Msg, &p_src_arg->Pos);
  1559.   }
  1560. }
  1561.  
  1562. /*!------------------------------------------------------------------------
  1563.  * \fn     chk_imm_level_range(const tStrComp *p_level_src_arg, const tAdrVals *p_level_adr_vals)
  1564.  * \brief  check whether (privilege) level is in range (0..3)
  1565.  * \param  p_level_src_arg source argument of level
  1566.  * \param  p_level_adr_vals encoded value of level
  1567.  * ------------------------------------------------------------------------ */
  1568.  
  1569. static void chk_imm_level_range(const tStrComp *p_level_src_arg, const tAdrVals *p_level_adr_vals)
  1570. {
  1571.   chk_imm_value_range(p_level_src_arg, p_level_adr_vals, "lvl", 3);
  1572. }
  1573.  
  1574. /*--------------------------------------------------------------------------*/
  1575. /* Instruction Handlers */
  1576.  
  1577. /*!------------------------------------------------------------------------
  1578.  * \fn     DecodeFixed(Word Code)
  1579.  * \brief  handle instructions with no argument
  1580.  * \param  Code machine code
  1581.  * ------------------------------------------------------------------------ */
  1582.  
  1583. static void DecodeFixed(Word Code)
  1584. {
  1585.   if (ChkArgCnt(0, 0)
  1586.    && chk_sup_mode(Code)
  1587.    && ChkNoAttrPart())
  1588.     BAsmCode[CodeLen++] = Lo(Code);
  1589. }
  1590.  
  1591. /*!------------------------------------------------------------------------
  1592.  * \fn     DecodeArithF(Word code)
  1593.  * \brief  handle FPU arithmetic instructions
  1594.  * \param  code machine opcode for short op size
  1595.  * ------------------------------------------------------------------------ */
  1596.  
  1597. static void DecodeArithF(Word code)
  1598. {
  1599.   tAdrVals src_adr_vals, dest_adr_vals;
  1600.  
  1601.   if (ChkArgCnt(2, 2)
  1602.    && ChkFOpSize(0x100 | Lo(code), Lo(code) | 0x02)
  1603.    && DecodeAdr(&ArgStr[1], &src_adr_vals, MModMem | MModReg)
  1604.    && DecodeAdr(&ArgStr[2], &dest_adr_vals, MModMem | MModReg))
  1605.   {
  1606.     EncodeFormat2(Hi(code), &src_adr_vals, &dest_adr_vals);
  1607.   }
  1608. }
  1609.  
  1610. /*!------------------------------------------------------------------------
  1611.  * \fn     DecodeSCLF(Word code)
  1612.  * \brief  handle SCLF Instruction
  1613.  * \param  code machine opcode for short op size
  1614.  * ------------------------------------------------------------------------ */
  1615.  
  1616. static void DecodeSCLF(Word code)
  1617. {
  1618.   if (ChkArgCnt(2, 2)
  1619.    && ChkFOpSize(0x100 | Lo(code), Lo(code) | 0x02))
  1620.   {
  1621.     tAdrVals count_adr_vals;
  1622.     tSymbolSize save_op_size;
  1623.  
  1624.     save_op_size = OpSize;
  1625.     OpSize = eSymbolSize16Bit;
  1626.     if (DecodeAdr(&ArgStr[1], &count_adr_vals, MModMem | MModReg | MModImm))
  1627.     {
  1628.       tAdrVals  dest_adr_vals;
  1629.  
  1630.       OpSize = save_op_size;
  1631.  
  1632.       if (DecodeAdr(&ArgStr[2], &dest_adr_vals, MModMem | MModReg))
  1633.         EncodeFormat2(Hi(code), &count_adr_vals, &dest_adr_vals);
  1634.     }
  1635.   }
  1636. }
  1637.  
  1638. /*!------------------------------------------------------------------------
  1639.  * \fn     DecodeArith(Word code)
  1640.  * \brief  handle arithmetic instructions
  1641.  * \param  code machine code for 8 bit in LSB, bit 8 -> dest may be immediate
  1642.  * ------------------------------------------------------------------------ */
  1643.  
  1644. static void DecodeArith(Word code)
  1645. {
  1646.   tAdrVals src_adr_vals, dest_adr_vals;
  1647.  
  1648.   if (ChkArgCnt(2, 2)
  1649.    && ChkOpSize(Lo(code), Lo(code) + 2, 0x100 | (Lo(code) + 4), -1)
  1650.    && DecodeAdr(&ArgStr[1], &src_adr_vals, MModMem | MModReg | MModImm)
  1651.    && DecodeAdr(&ArgStr[2], &dest_adr_vals, MModMem | MModReg | imm_mask_cond(code)))
  1652.     EncodeFormat1Or2(0x00, &src_adr_vals, &dest_adr_vals);
  1653. }
  1654.  
  1655. /*!------------------------------------------------------------------------
  1656.  * \fn     DecodeArithX(Word code)
  1657.  * \brief  handle arithmetic instructions with double dest width
  1658.  * \param  code machine code for 8 bit in LSB
  1659.  * ------------------------------------------------------------------------ */
  1660.  
  1661. static void DecodeArithX(Word code)
  1662. {
  1663.   tAdrVals src_adr_vals, dest_adr_vals;
  1664.  
  1665.   if (ChkArgCnt(2, 2)
  1666.    && ChkOpSize(-1, -1, 0x100 | Lo(code), -1)
  1667.    && DecodeAdr(&ArgStr[1], &src_adr_vals, MModMem | MModReg | MModImm)
  1668.    && DecodeAdr(&ArgStr[2], &dest_adr_vals, MModMem | MModReg))
  1669.     EncodeFormat1Or2(0x00, &src_adr_vals, &dest_adr_vals);
  1670. }
  1671.  
  1672. /*!------------------------------------------------------------------------
  1673.  * \fn     DecodeXCH(Word code)
  1674.  * \brief  handle XCH instruction
  1675.  * \param  code machine code for 8 bit operand size
  1676.  * ------------------------------------------------------------------------ */
  1677.  
  1678. static void DecodeXCH(Word code)
  1679. {
  1680.   tAdrVals dest1_adr_vals, dest2_adr_vals;
  1681.  
  1682.   if (ChkArgCnt(2, 2)
  1683.    && ChkOpSize(Lo(code), Lo(code) + 2, 0x100 | (Lo(code) + 4), -1)
  1684.    && DecodeAdr(&ArgStr[1], &dest1_adr_vals, MModMem | MModReg)
  1685.    && DecodeAdr(&ArgStr[2], &dest2_adr_vals, MModMem | MModReg))
  1686.   {
  1687.     if (IsReg(&dest1_adr_vals))
  1688.       EncodeFormat1(dest1_adr_vals.vals[0] & 0x1f, &dest2_adr_vals);
  1689.     else if (IsReg(&dest2_adr_vals))
  1690.       EncodeFormat1(dest2_adr_vals.vals[0] & 0x1f, &dest1_adr_vals);
  1691.     else
  1692.       WrError(ErrNum_InvArgPair);
  1693.   }
  1694. }
  1695.  
  1696. /*!------------------------------------------------------------------------
  1697.  * \fn     DecodeSETF(Word code)
  1698.  * \brief  handle SETF instruction
  1699.  * \param  code machine code
  1700.  * ------------------------------------------------------------------------ */
  1701.  
  1702. static void DecodeSETF(Word code)
  1703. {
  1704.   tAdrVals cond_adr_vals, dest_adr_vals;
  1705.  
  1706.   if (ChkArgCnt(2, 2)
  1707.    && ChkOpSize(0x100 | Lo(code), -1, -1, -1)
  1708.    && DecodeAdr(&ArgStr[1], &cond_adr_vals, MModMem | MModReg | MModImm | MModImmCondition)
  1709.    && DecodeAdr(&ArgStr[2], &dest_adr_vals, MModMem | MModReg))
  1710.   {
  1711.     EncodeFormat1Or2(0, &cond_adr_vals, &dest_adr_vals);
  1712.   }
  1713. }
  1714.  
  1715. /*!------------------------------------------------------------------------
  1716.  * \fn     DecodeShift(Word code)
  1717.  * \brief  handle shift instructions
  1718.  * \param  code machine code for 8 bit in LSB
  1719.  * ------------------------------------------------------------------------ */
  1720.  
  1721. static Boolean DecodeShiftCnt(tStrComp *p_arg, tAdrVals *p_adr_vals)
  1722. {
  1723.   tSymbolSize save_size;
  1724.   Boolean ret;
  1725.  
  1726.   save_size = OpSize;
  1727.   OpSize = eSymbolSize8Bit;
  1728.   ret = DecodeAdr(p_arg, p_adr_vals, MModMem | MModReg | MModImm);
  1729.   OpSize = save_size;
  1730.   return ret;
  1731. }
  1732.  
  1733. static void DecodeShift(Word code)
  1734. {
  1735.   tAdrVals shift_adr_vals, dest_adr_vals;
  1736.  
  1737.   if (ChkArgCnt(2, 2)
  1738.    && ChkOpSize(Lo(code), Lo(code) + 2, 0x100 | (Lo(code) + 4), -1)
  1739.    && DecodeShiftCnt(&ArgStr[1], &shift_adr_vals)
  1740.    && DecodeAdr(&ArgStr[2], &dest_adr_vals, MModMem | MModReg))
  1741.     EncodeFormat1Or2(0x00, &shift_adr_vals, &dest_adr_vals);
  1742. }
  1743.  
  1744. /*!------------------------------------------------------------------------
  1745.  * \fn     DecodeArith_7c(Word code)
  1746.  * \brief  handle arithmetic instructions
  1747.  * \param  code machine code in LSB, sub-code in MSB
  1748.  * ------------------------------------------------------------------------ */
  1749.  
  1750. static void DecodeArith_7c(Word code)
  1751. {
  1752.   tAdrVals src_adr_vals, dest_adr_vals;
  1753.  
  1754.   if (ChkArgCnt(3, 3)
  1755.    && ChkOpSize(0x100 | Lo(code), -1, -1, -1)
  1756.    && DecodeAdr(&ArgStr[1], &src_adr_vals, MModMem | MModReg | MModImm)
  1757.    && DecodeAdr(&ArgStr[2], &dest_adr_vals, MModMem | MModReg))
  1758.   {
  1759.     Boolean ok;
  1760.     Byte mask = EvalStrIntExpressionOffs(&ArgStr[3], ArgStr[3].str.p_str[0] == '#', Int8, &ok);
  1761.  
  1762.     if (ok)
  1763.     {
  1764.       EncodeFormat2(Hi(code), &src_adr_vals, &dest_adr_vals);
  1765.       BAsmCode[CodeLen++] = mask;
  1766.     }
  1767.   }
  1768. }
  1769.  
  1770. /*!------------------------------------------------------------------------
  1771.  * \fn     DecodeBitString_7b(Word code)
  1772.  * \brief  handle bit string instructions
  1773.  * \param  code machine code in LSB, sub-code in MSB
  1774.  * ------------------------------------------------------------------------ */
  1775.  
  1776. static void DecodeBitString_7b(Word code)
  1777. {
  1778.   tAdrVals src_adr_vals, dest_adr_vals;
  1779.   tLenVals length;
  1780.  
  1781.   if (ChkArgCnt(3, 3)
  1782.    && ChkNoAttrPart())
  1783.   {
  1784.     OpSize = eSymbolSize8Bit;
  1785.  
  1786.     if (DecodeBitAdr(&ArgStr[1], &src_adr_vals, MModMem)
  1787.      && DecodeLength(&ArgStr[2], &length)
  1788.      && DecodeBitAdr(&ArgStr[3], &dest_adr_vals, MModMem))
  1789.     {
  1790.       BAsmCode[CodeLen++] = Lo(code);
  1791.       BAsmCode[CodeLen++] = Hi(code) | 0x80 | (dest_adr_vals.m << 5) | (src_adr_vals.m << 6);
  1792.       AppendAdrVals(&src_adr_vals);
  1793.       BAsmCode[CodeLen++] = length.val;
  1794.       AppendAdrVals(&dest_adr_vals);
  1795.     }
  1796.   }
  1797. }
  1798.  
  1799. /*!------------------------------------------------------------------------
  1800.  * \fn     DecodeBitField_7b(Word code)
  1801.  * \brief  handle bit field instructions
  1802.  * \param  code machine code in LSB, sub-code in MSB
  1803.  * ------------------------------------------------------------------------ */
  1804.  
  1805. static void DecodeBitField_7b(Word code)
  1806. {
  1807.   tAdrVals bsrc_adr_vals, src_adr_vals;
  1808.   tLenVals length;
  1809.  
  1810.   if (ChkArgCnt(3, 3)
  1811.    && ChkNoAttrPart())
  1812.   {
  1813.     OpSize = eSymbolSize32Bit;
  1814.  
  1815.     if (DecodeBitAdr(&ArgStr[1], &bsrc_adr_vals, MModMem)
  1816.      && DecodeLength(&ArgStr[2], &length)
  1817.      && DecodeAdr(&ArgStr[3], &src_adr_vals, MModReg | MModMem | imm_mask_cond(code)))
  1818.     {
  1819.       /* optional check for offset+length <= 32, if possible: */
  1820.  
  1821.       if (code & CODE_FLAG_LIM32)
  1822.         chk_imm_bitfield_range(&ArgStr[1], &bsrc_adr_vals, &length);
  1823.  
  1824.       BAsmCode[CodeLen++] = Lo(code);
  1825.       BAsmCode[CodeLen++] = (Hi(code) & 0x1f) | 0x80 | (src_adr_vals.m << 5) | (bsrc_adr_vals.m << 6);
  1826.       AppendAdrVals(&bsrc_adr_vals);
  1827.       BAsmCode[CodeLen++] = length.val;
  1828.       AppendAdrVals(&src_adr_vals);
  1829.     }
  1830.   }
  1831. }
  1832.  
  1833. /*!------------------------------------------------------------------------
  1834.  * \fn     DecodeBitField_7c(Word code)
  1835.  * \brief  handle bit field instructions
  1836.  * \param  code machine code in LSB, sub-code in MSB
  1837.  * ------------------------------------------------------------------------ */
  1838.  
  1839. static void DecodeBitField_7c(Word code)
  1840. {
  1841.   tAdrVals src_adr_vals, bdst_adr_vals;
  1842.   tLenVals length;
  1843.  
  1844.   if (ChkArgCnt(3, 3)
  1845.    && ChkNoAttrPart())
  1846.   {
  1847.     OpSize = eSymbolSize32Bit;
  1848.  
  1849.     if (DecodeAdr(&ArgStr[1], &src_adr_vals, MModReg | MModMem | MModImm)
  1850.      && DecodeBitAdr(&ArgStr[2], &bdst_adr_vals, MModMem)
  1851.      && DecodeLength(&ArgStr[3], &length))
  1852.     {
  1853.       /* optional check for offset+length <= 32, if possible: */
  1854.  
  1855.       if (code & CODE_FLAG_LIM32)
  1856.         chk_imm_bitfield_range(&ArgStr[2], &bdst_adr_vals, &length);
  1857.  
  1858.       BAsmCode[CodeLen++] = Lo(code);
  1859.       BAsmCode[CodeLen++] = (Hi(code) & 0x1f) | 0x80 | (bdst_adr_vals.m << 5) | (src_adr_vals.m << 6);
  1860.       AppendAdrVals(&src_adr_vals);
  1861.       AppendAdrVals(&bdst_adr_vals);
  1862.       BAsmCode[CodeLen++] = length.val;
  1863.     }
  1864.   }
  1865. }
  1866.  
  1867. /*!------------------------------------------------------------------------
  1868.  * \fn     DecodeString_7a(Word code)
  1869.  * \brief  Handle Format VIIa String Instructons
  1870.  * \param  code machine code (LSB) and subcode (MSB)
  1871.  * ------------------------------------------------------------------------ */
  1872.  
  1873. static void DecodeString_7a(Word code)
  1874. {
  1875.   tAdrVals src_adr_vals, dest_adr_vals;
  1876.   tLenVals src_length, dest_length;
  1877.  
  1878.   if (ChkArgCnt(4, 4)
  1879.    && ChkOpSize(0x100 | (Lo(code)), Lo(code) + 2, -1, -1)
  1880.    && DecodeAdr(&ArgStr[1], &src_adr_vals, MModMem)
  1881.    && DecodeLength(&ArgStr[2], &src_length)
  1882.    && DecodeAdr(&ArgStr[3], &dest_adr_vals, MModMem)
  1883.    && DecodeLength(&ArgStr[4], &dest_length))
  1884.   {
  1885.     CodeLen++;
  1886.     BAsmCode[CodeLen++] = (Hi(code) & 0x1f) | 0x80 | (dest_adr_vals.m << 5) | (src_adr_vals.m << 6);
  1887.     AppendAdrVals(&src_adr_vals);
  1888.     BAsmCode[CodeLen++] = src_length.val;
  1889.     AppendAdrVals(&dest_adr_vals);
  1890.     BAsmCode[CodeLen++] = dest_length.val;
  1891.   }
  1892. }
  1893.  
  1894. /*!------------------------------------------------------------------------
  1895.  * \fn     DecodeString_7b(Word code)
  1896.  * \brief  Handle Format VIIb String Instructons
  1897.  * \param  code machine code (LSB) and subcode (MSB)
  1898.  * ------------------------------------------------------------------------ */
  1899.  
  1900. static void DecodeString_7b(Word code)
  1901. {
  1902.   tAdrVals src_adr_vals, char_adr_vals;
  1903.   tLenVals src_length;
  1904.  
  1905.   if (ChkArgCnt(3, 3)
  1906.    && ChkOpSize(0x100 | (Lo(code)), Lo(code) + 2, -1, -1)
  1907.    && DecodeAdr(&ArgStr[1], &src_adr_vals, MModMem)
  1908.    && DecodeLength(&ArgStr[2], &src_length)
  1909.    && DecodeAdr(&ArgStr[3], &char_adr_vals, MModReg | MModMem | MModImm))
  1910.   {
  1911.     CodeLen++;
  1912.     BAsmCode[CodeLen++] = (Hi(code) & 0x1f) | 0x80 | (char_adr_vals.m << 5) | (src_adr_vals.m << 6);
  1913.     AppendAdrVals(&src_adr_vals);
  1914.     BAsmCode[CodeLen++] = src_length.val;
  1915.     AppendAdrVals(&char_adr_vals);
  1916.   }
  1917. }
  1918.  
  1919. /*!------------------------------------------------------------------------
  1920.  * \fn     Decode_4(Word code)
  1921.  * \brief  handle relative branches
  1922.  * \param  code machine code for 16 bit displacement
  1923.  * ------------------------------------------------------------------------ */
  1924.  
  1925. static void Decode_4(Word code)
  1926. {
  1927.   if (ChkArgCnt(1, 1))
  1928.   {
  1929.     Boolean ok;
  1930.     const Boolean allow_8 = (code & 0xf0) == 0x70;
  1931.     tSymbolFlags flags;
  1932.     LongWord addr = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt32, &ok, &flags);
  1933.  
  1934.     if (ok)
  1935.     {
  1936.       LongInt delta = addr - EProgCounter();
  1937.  
  1938.       switch (AttrPartOpSize[0])
  1939.       {
  1940.         case eSymbolSizeUnknown:
  1941.           if ((delta > -128) && (delta < 127) && allow_8)
  1942.             goto br_short;
  1943.           else
  1944.             goto br_long;
  1945.         case eSymbolSizeFloat32Bit: /* .s */
  1946.         case eSymbolSize8Bit:  /* .b */
  1947.         br_short:
  1948.           if (!allow_8)
  1949.           {
  1950.             WrStrErrorPos(ErrNum_InvOpSize, &AttrPart);
  1951.             return;
  1952.           }
  1953.           code -= 0x10;
  1954.           if (!mFirstPassUnknownOrQuestionable(flags) && ((delta < -128) || (delta > 127))) WrError(ErrNum_JmpDistTooBig);
  1955.           else
  1956.           {
  1957.             BAsmCode[CodeLen++] = code;
  1958.             BAsmCode[CodeLen++] = delta & 0xff;
  1959.           }
  1960.           break;
  1961.         case eSymbolSizeFloat64Bit: /* .l */
  1962.         case eSymbolSize16Bit: /* .h */
  1963.         br_long:
  1964.           if (!mFirstPassUnknownOrQuestionable(flags) && ((delta < -32768) || (delta > 32767))) WrError(ErrNum_JmpDistTooBig);
  1965.           else
  1966.           {
  1967.             BAsmCode[CodeLen++] = code;
  1968.             BAsmCode[CodeLen++] = delta & 0xff;
  1969.             BAsmCode[CodeLen++] = (delta >> 8) & 0xff;
  1970.           }
  1971.           break;
  1972.         default:
  1973.           WrStrErrorPos(ErrNum_InvOpSize, &AttrPart);
  1974.           return;
  1975.       }
  1976.     }
  1977.   }
  1978. }
  1979.  
  1980. /*!------------------------------------------------------------------------
  1981.  * \fn     Decode_6(Word code)
  1982.  * \brief  handle loop instructions
  1983.  * \param  code machine code for 16 bit displacement
  1984.  * ------------------------------------------------------------------------ */
  1985.  
  1986. static void Decode_6(Word code)
  1987. {
  1988.   tAdrVals reg_adr_vals;
  1989.  
  1990.   /* allow no attribute at all since it would be unclear whether to check
  1991.      for register operand's size (32 bits) or displacement operand's size
  1992.      (16 bits): */
  1993.  
  1994.   if (ChkArgCnt(2, 2)
  1995.    && ChkNoAttrPart()
  1996.    && DecodeAdr(&ArgStr[1], &reg_adr_vals, MModReg))
  1997.   {
  1998.     Boolean ok;
  1999.     tSymbolFlags flags;
  2000.     LongWord addr = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt32, &ok, &flags);
  2001.  
  2002.     if (ok)
  2003.     {
  2004.       LongInt delta = addr - EProgCounter();
  2005.  
  2006.       if (!mFirstPassUnknownOrQuestionable(flags) && ((delta < -32768) || (delta > 32767))) WrError(ErrNum_JmpDistTooBig);
  2007.       else
  2008.       {
  2009.         BAsmCode[CodeLen++] = Lo(code);
  2010.         BAsmCode[CodeLen++] = (reg_adr_vals.vals[0] & 0x1f) | (Hi(code) << 5);
  2011.         BAsmCode[CodeLen++] = delta & 0xff;
  2012.         BAsmCode[CodeLen++] = (delta >> 8) & 0xff;
  2013.       }
  2014.     }
  2015.   }
  2016. }
  2017.  
  2018. /*!------------------------------------------------------------------------
  2019.  * \fn     DecodeCLRTLB(Word code)
  2020.  * \brief  handle CLRTLB instruction
  2021.  * \param  code machine code
  2022.  * ------------------------------------------------------------------------ */
  2023.  
  2024. static void DecodeCLRTLB(Word code)
  2025. {
  2026.   tAdrVals adr_vals;
  2027.  
  2028.   if (ChkArgCnt(1, 1)
  2029.    && ChkPtrOpSize(Lo(code) | 0x100)
  2030.    && chk_sup_mode(code)
  2031.    && DecodeAdr(&ArgStr[1], &adr_vals, MModMem | MModImm | MModReg))
  2032.   {
  2033.     EncodeFormat3(&adr_vals);
  2034.   }
  2035. }
  2036.  
  2037. /*!------------------------------------------------------------------------
  2038.  * \fn     DecodeGETPSW(Word code)
  2039.  * \brief  handle GETPSW instruction
  2040.  * \param  code machine code
  2041.  * ------------------------------------------------------------------------ */
  2042.  
  2043. static void DecodeGETPSW(Word code)
  2044. {
  2045.   tAdrVals adr_vals;
  2046.  
  2047.   if (ChkArgCnt(1, 1)
  2048.    && ChkOpSize(-1, -1, 0x100 | Lo(code), -1)
  2049.    && DecodeAdr(&ArgStr[1], &adr_vals, MModMem | MModReg))
  2050.   {
  2051.     EncodeFormat3(&adr_vals);
  2052.   }
  2053. }
  2054.  
  2055. /*!------------------------------------------------------------------------
  2056.  * \fn     DecodeUPDPSW(Word code)
  2057.  * \brief  handle UPDPSW instruction
  2058.  * ------------------------------------------------------------------------ */
  2059.  
  2060. static void DecodeUPDPSW(Word code)
  2061. {
  2062.   UNUSED(code);
  2063.  
  2064.   if (ChkArgCnt(2, 2)
  2065.    && ChkOpSize(-1, 0x14a, 0x13, -1)
  2066.    && chk_sup_mode((OpSize == eSymbolSize32Bit) ? CODE_FLAG_SUPMODE : 0))
  2067.   {
  2068.     tAdrVals new_psw_adr_vals, mask_adr_vals;
  2069.  
  2070.     OpSize = eSymbolSize32Bit;
  2071.  
  2072.     if (DecodeAdr(&ArgStr[1], &new_psw_adr_vals, MModImm | MModMem | MModReg)
  2073.      && DecodeAdr(&ArgStr[2], &mask_adr_vals, MModImm | MModMem | MModReg))
  2074.       EncodeFormat1Or2(0, &new_psw_adr_vals, &mask_adr_vals);
  2075.   }
  2076. }
  2077.  
  2078. /*!------------------------------------------------------------------------
  2079.  * \fn     DecodeFormat3_bhw(Word code)
  2080.  * \brief  handle Format 3 instructions with 8/16/32 bit operand size
  2081.  * \param  code machine code
  2082.  * ------------------------------------------------------------------------ */
  2083.  
  2084. static void DecodeFormat3_bhw(Word code)
  2085. {
  2086.   tAdrVals adr_vals;
  2087.  
  2088.   if (ChkArgCnt(1, 1)
  2089.    && ChkOpSize(Lo(code), Lo(code) + 2, 0x100 | (Lo(code) + 4), -1)
  2090.    && DecodeAdr(&ArgStr[1], &adr_vals, MModMem | MModReg | imm_mask_cond(code)))
  2091.   {
  2092.     EncodeFormat3(&adr_vals);
  2093.   }
  2094. }
  2095.  
  2096. /*!------------------------------------------------------------------------
  2097.  * \fn     DecodeJMP_JSR(Word code)
  2098.  * \brief  handle JMP/JSR instructions
  2099.  * \param  code machine code
  2100.  * ------------------------------------------------------------------------ */
  2101.  
  2102. static void DecodeJMP_JSR(Word code)
  2103. {
  2104.   tAdrVals adr_vals;
  2105.  
  2106.   if (ChkArgCnt(1, 1)
  2107.    && ChkNoAttrPart()
  2108.    && DecodeAdr(&ArgStr[1], &adr_vals, MModMem))
  2109.   {
  2110.     if (IsSPAutoIncDec(&adr_vals))
  2111.       WrStrErrorPos(ErrNum_Unpredictable, &ArgStr[1]);
  2112.     BAsmCode[CodeLen] = code;
  2113.     EncodeFormat3(&adr_vals);
  2114.   }
  2115. }
  2116.  
  2117. /*!------------------------------------------------------------------------
  2118.  * \fn     DecodeFormat3_W(Word code)
  2119.  * \brief  handle instructions with single argument and 32 bit operand size
  2120.  * \param  code machine code
  2121.  * ------------------------------------------------------------------------ */
  2122.  
  2123. static void DecodeFormat3_W(Word code)
  2124. {
  2125.   tAdrVals adr_vals;
  2126.  
  2127.   /* TODO: allow PUSHM/POPM immediate arg as register list similar to 68K? */
  2128.  
  2129.   if (ChkArgCnt(1, 1)
  2130.    && chk_sup_mode(code)
  2131.    && ChkOpSize(-1, -1, 0x100 | Lo(code), -1)
  2132.    && DecodeAdr(&ArgStr[1], &adr_vals, MModMem | MModReg | imm_mask_cond(code)))
  2133.   {
  2134.     EncodeFormat3(&adr_vals);
  2135.   }
  2136. }
  2137.  
  2138. /*!------------------------------------------------------------------------
  2139.  * \fn     DecodeFormat3_H(Word code)
  2140.  * \brief  handle instructions with single argument and 16 bit operand size
  2141.  * \param  code machine code
  2142.  * ------------------------------------------------------------------------ */
  2143.  
  2144. static void DecodeFormat3_H(Word code)
  2145. {
  2146.   tAdrVals adr_vals;
  2147.  
  2148.   if (ChkArgCnt(1, 1)
  2149.    && chk_sup_mode(code)
  2150.    && ChkOpSize(-1, 0x100 | Lo(code), -1, -1)
  2151.    && DecodeAdr(&ArgStr[1], &adr_vals, MModMem | MModReg | imm_mask_cond(code)))
  2152.   {
  2153.     EncodeFormat3(&adr_vals);
  2154.   }
  2155. }
  2156.  
  2157. /*!------------------------------------------------------------------------
  2158.  * \fn     DecodeFormat3_B(Word code)
  2159.  * \brief  handle instructions with single argument and 8 bit operand size
  2160.  * \param  code machine code
  2161.  * ------------------------------------------------------------------------ */
  2162.  
  2163. static void DecodeFormat3_B(Word code)
  2164. {
  2165.   tAdrVals adr_vals;
  2166.  
  2167.   if (ChkArgCnt(1, 1)
  2168.    && chk_sup_mode(code)
  2169.    && ChkOpSize(0x100 | Lo(code), -1, -1, -1)
  2170.    && DecodeAdr(&ArgStr[1], &adr_vals, MModMem | MModReg | imm_mask_cond(code)))
  2171.   {
  2172.     EncodeFormat3(&adr_vals);
  2173.   }
  2174. }
  2175.  
  2176. /*!------------------------------------------------------------------------
  2177.  * \fn     DecodeCALL(Word code)
  2178.  * \brief  handle CALL instructions
  2179.  * \param  code machine code
  2180.  * ------------------------------------------------------------------------ */
  2181.  
  2182. static void DecodeCALL(Word code)
  2183. {
  2184.   tAdrVals target_adr_vals, arg_adr_vals;
  2185.  
  2186.   /* TODO: If register direct mode is disallowed for both arguments,
  2187.      checking for instruction format I does not make sense? */
  2188.  
  2189.   if (ChkArgCnt(2, 2)
  2190.    && ChkNoAttrPart()
  2191.    && DecodeAdr(&ArgStr[1], &target_adr_vals, MModMem)
  2192.    && DecodeAdr(&ArgStr[2], &arg_adr_vals, MModMem))
  2193.   {
  2194.     if (IsSPAutoIncDec(&target_adr_vals))
  2195.       WrStrErrorPos(ErrNum_Unpredictable, &ArgStr[1]);
  2196.     if (IsSPAutoIncDec(&arg_adr_vals))
  2197.       WrStrErrorPos(ErrNum_Unpredictable, &ArgStr[2]);
  2198.     BAsmCode[CodeLen] = Lo(code);
  2199.     EncodeFormat1Or2(0x00, &target_adr_vals, &arg_adr_vals);
  2200.   }
  2201. }
  2202.  
  2203. /*!------------------------------------------------------------------------
  2204.  * \fn     DecodeCHKA(Word Code)
  2205.  * \brief  Decode CHKA instruction(s)
  2206.  * \param  code machine code
  2207.  * ------------------------------------------------------------------------ */
  2208.  
  2209. static void DecodeCHKA(Word code)
  2210. {
  2211.   tAdrVals va_adr_vals;
  2212.  
  2213.   /* TODO: va is an address operand, so Rn and #imm do not make sense for va? */
  2214.  
  2215.   if (ChkArgCnt(2, 2)
  2216.    && ChkNoAttrPart()
  2217.    && DecodeAdr(&ArgStr[1], &va_adr_vals, MModMem | MModReg | MModImm))
  2218.   {
  2219.     tAdrVals level_adr_vals;
  2220.  
  2221.     OpSize = eSymbolSize8Bit;
  2222.     if (DecodeAdr(&ArgStr[2], &level_adr_vals, MModMem | MModReg | MModImm))
  2223.     {
  2224.       chk_imm_level_range(&ArgStr[1], &level_adr_vals);
  2225.  
  2226.       BAsmCode[CodeLen] = Lo(code);
  2227.       EncodeFormat1Or2(0x00, &va_adr_vals, &level_adr_vals);
  2228.     }
  2229.   }
  2230. }
  2231.  
  2232. /*!------------------------------------------------------------------------
  2233.  * \fn     DecodeCAXI(Word Code)
  2234.  * \brief  Decode CAXI instruction
  2235.  * \param  code machine code
  2236.  * ------------------------------------------------------------------------ */
  2237.  
  2238. static void DecodeCAXI(Word code)
  2239. {
  2240.   tAdrVals reg_adr_vals, mem_adr_vals;
  2241.  
  2242.   if (ChkArgCnt(2, 2)
  2243.    && ChkOpSize(-1, -1, 0x100 | Lo(code), -1)
  2244.    && DecodeAdr(&ArgStr[1], &reg_adr_vals, MModReg)
  2245.    && DecodeAdr(&ArgStr[2], &mem_adr_vals, MModMem | MModReg))
  2246.     EncodeFormat1(reg_adr_vals.vals[0] & 0x1f, &mem_adr_vals);
  2247. }
  2248.  
  2249. /*!------------------------------------------------------------------------
  2250.  * \fn     DecodeCHLVL(Word Code)
  2251.  * \brief  Decode CHLVL instruction
  2252.  * \param  code machine code
  2253.  * ------------------------------------------------------------------------ */
  2254.  
  2255. static void DecodeCHLVL(Word code)
  2256. {
  2257.   tAdrVals level_adr_vals, arg_adr_vals;
  2258.  
  2259.   if (ChkArgCnt(2, 2)
  2260.    && ChkNoAttrPart())
  2261.   {
  2262.     OpSize = eSymbolSize8Bit;
  2263.  
  2264.     if (DecodeAdr(&ArgStr[1], &level_adr_vals, MModMem | MModReg | MModImm)
  2265.      && DecodeAdr(&ArgStr[2], &arg_adr_vals, MModMem | MModReg | MModImm))
  2266.     {
  2267.       chk_imm_level_range(&ArgStr[1], &level_adr_vals);
  2268.  
  2269.       BAsmCode[CodeLen] = Lo(code);
  2270.       EncodeFormat1Or2(0, &level_adr_vals, &arg_adr_vals);
  2271.     }
  2272.   }
  2273. }
  2274.  
  2275. /*!------------------------------------------------------------------------
  2276.  * \fn     DecodeGETXTE(Word Code)
  2277.  * \brief  Decode GETATE/GETPTE instructions
  2278.  * \param  code machine code
  2279.  * ------------------------------------------------------------------------ */
  2280.  
  2281. static void DecodeGETXTE(Word code)
  2282. {
  2283.   tAdrVals va_adr_vals, dst_adr_vals;
  2284.  
  2285.   if (ChkArgCnt(2, 2)
  2286.    && chk_sup_mode(code)
  2287.    && ChkNoAttrPart())
  2288.   {
  2289.     OpSize = eSymbolSize32Bit;
  2290.  
  2291.     if (DecodeAdr(&ArgStr[1], &va_adr_vals, MModMem | MModReg | MModImm)
  2292.      && DecodeAdr(&ArgStr[2], &dst_adr_vals, MModMem | MModReg | imm_mask_cond(code)))
  2293.     {
  2294.       BAsmCode[CodeLen] = Lo(code);
  2295.       EncodeFormat1Or2(0, &va_adr_vals, &dst_adr_vals);
  2296.     }
  2297.   }
  2298. }
  2299.  
  2300. /*!------------------------------------------------------------------------
  2301.  * \fn     DecodeCVT(Word code)
  2302.  * \brief  Handle CVT Instruction
  2303.  * \param  code machine code (abused as scratch)
  2304.  * ------------------------------------------------------------------------ */
  2305.  
  2306. static void DecodeCVT(Word code)
  2307. {
  2308.   tAdrVals src_adr_vals, dest_adr_vals;
  2309.  
  2310.   if (!ChkArgCnt(2, 2))
  2311.     return;
  2312.  
  2313.   if ((AttrPartOpSize[0] == eSymbolSizeFloat32Bit) && (AttrPartOpSize[1] == eSymbolSizeFloat64Bit))
  2314.     code = 0x105f;
  2315.   else if ((AttrPartOpSize[0] == eSymbolSizeFloat64Bit) && (AttrPartOpSize[1] == eSymbolSizeFloat32Bit))
  2316.     code = 0x085f;
  2317.   else if ((AttrPartOpSize[0] == eSymbolSize32Bit) && (AttrPartOpSize[1] == eSymbolSizeFloat32Bit))
  2318.     code = 0x005f;
  2319.   else if ((AttrPartOpSize[0] == eSymbolSize32Bit) && (AttrPartOpSize[1] == eSymbolSizeFloat64Bit))
  2320.     code = 0x115f;
  2321.   else if ((AttrPartOpSize[0] == eSymbolSizeFloat32Bit) && (AttrPartOpSize[1] == eSymbolSize32Bit))
  2322.     code = 0x015f;
  2323.   else if ((AttrPartOpSize[0] == eSymbolSizeFloat64Bit) && (AttrPartOpSize[1] == eSymbolSize32Bit))
  2324.     code = 0x095f;
  2325.   else
  2326.   {
  2327.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  2328.     return;
  2329.   }
  2330.  
  2331.   OpSize = AttrPartOpSize[0];
  2332.   if (!DecodeAdr(&ArgStr[1], &src_adr_vals, MModReg | MModMem))
  2333.     return;
  2334.   OpSize = AttrPartOpSize[1];
  2335.   if (!DecodeAdr(&ArgStr[2], &dest_adr_vals, MModReg | MModMem))
  2336.     return;
  2337.  
  2338.   BAsmCode[CodeLen] = Lo(code);
  2339.   EncodeFormat2(Hi(code), &src_adr_vals, &dest_adr_vals);
  2340. }
  2341.  
  2342. /*!------------------------------------------------------------------------
  2343.  * \fn     DecodeCVT(Word code)
  2344.  * \brief  Handle CVT Instruction
  2345.  * \param  code machine code (abused as scratch)
  2346.  * ------------------------------------------------------------------------ */
  2347.  
  2348. static void DecodeCVTD(Word code)
  2349. {
  2350.   tAdrVals src_adr_vals, dest_adr_vals;
  2351.   Byte mask;
  2352.   Boolean ok;
  2353.  
  2354.   if (!ChkArgCnt(3, 3))
  2355.     return;
  2356.  
  2357.   if ((AttrPartOpSize[0] == eSymbolSize24Bit) && (AttrPartOpSize[1] == eSymbolSizeFloatDec96Bit));
  2358.   else if ((AttrPartOpSize[0] == eSymbolSizeFloatDec96Bit) && (AttrPartOpSize[1] == eSymbolSize24Bit))
  2359.     code |= 0x0800;
  2360.   else
  2361.   {
  2362.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  2363.     return;
  2364.   }
  2365.  
  2366.   OpSize = (AttrPartOpSize[0] == eSymbolSize24Bit) ? eSymbolSize8Bit : eSymbolSize16Bit;
  2367.   if (!DecodeAdr(&ArgStr[1], &src_adr_vals, MModReg | MModMem | MModImm))
  2368.     return;
  2369.   OpSize = (AttrPartOpSize[1] == eSymbolSize24Bit) ? eSymbolSize8Bit : eSymbolSize16Bit;
  2370.   if (!DecodeAdr(&ArgStr[2], &dest_adr_vals, MModReg | MModMem))
  2371.     return;
  2372.   mask = EvalStrIntExpressionOffs(&ArgStr[3], ArgStr[3].str.p_str[0] == '#', Int8, &ok);
  2373.  
  2374.   BAsmCode[CodeLen] = Lo(code);
  2375.   EncodeFormat2(Hi(code), &src_adr_vals, &dest_adr_vals);
  2376.   BAsmCode[CodeLen++] = mask;
  2377. }
  2378.  
  2379. /*!------------------------------------------------------------------------
  2380.  * \fn     DecodeMOVS_MOVZ(Word code)
  2381.  * \brief  Handle MOVS/MOVZ Instructions
  2382.  * \param  code machine code for .bh
  2383.  * ------------------------------------------------------------------------ */
  2384.  
  2385. static void DecodeMOVS_MOVZ(Word code)
  2386. {
  2387.   tAdrVals src_adr_vals, dest_adr_vals;
  2388.  
  2389.   if (!ChkArgCnt(2, 2))
  2390.     return;
  2391.  
  2392.   if ((AttrPartOpSize[0] == eSymbolSize8Bit) && (AttrPartOpSize[1] == eSymbolSize16Bit))
  2393.     ;
  2394.   else if ((AttrPartOpSize[0] == eSymbolSize8Bit) && (AttrPartOpSize[1] == eSymbolSize32Bit))
  2395.     code += 0x02;
  2396.   else if ((AttrPartOpSize[0] == eSymbolSize16Bit) && (AttrPartOpSize[1] == eSymbolSize32Bit))
  2397.     code += 0x12;
  2398.   else
  2399.   {
  2400.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  2401.     return;
  2402.   }
  2403.  
  2404.   OpSize = AttrPartOpSize[0];
  2405.   if (!DecodeAdr(&ArgStr[1], &src_adr_vals, MModReg | MModMem | MModImm))
  2406.     return;
  2407.   OpSize = AttrPartOpSize[1];
  2408.   if (!DecodeAdr(&ArgStr[2], &dest_adr_vals, MModReg | MModMem))
  2409.     return;
  2410.  
  2411.   BAsmCode[CodeLen] = Lo(code);
  2412.   EncodeFormat1Or2(Lo(code), &src_adr_vals, &dest_adr_vals);
  2413. }
  2414.  
  2415. /*!------------------------------------------------------------------------
  2416.  * \fn     DecodeMOVT(Word code)
  2417.  * \brief  Handle MOVT Instructions
  2418.  * \param  code machine code for .hb
  2419.  * ------------------------------------------------------------------------ */
  2420.  
  2421. static void DecodeMOVT(Word code)
  2422. {
  2423.   tAdrVals src_adr_vals, dest_adr_vals;
  2424.  
  2425.   if (!ChkArgCnt(2, 2))
  2426.     return;
  2427.  
  2428.   if ((AttrPartOpSize[0] == eSymbolSize16Bit) && (AttrPartOpSize[1] == eSymbolSize8Bit))
  2429.     ;
  2430.   else if ((AttrPartOpSize[0] == eSymbolSize32Bit) && (AttrPartOpSize[1] == eSymbolSize8Bit))
  2431.     code += 0x10;
  2432.   else if ((AttrPartOpSize[0] == eSymbolSize32Bit) && (AttrPartOpSize[1] == eSymbolSize16Bit))
  2433.     code += 0x12;
  2434.   else
  2435.   {
  2436.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  2437.     return;
  2438.   }
  2439.  
  2440.   OpSize = AttrPartOpSize[0];
  2441.   if (!DecodeAdr(&ArgStr[1], &src_adr_vals, MModReg | MModMem | MModImm))
  2442.     return;
  2443.   OpSize = AttrPartOpSize[1];
  2444.   if (!DecodeAdr(&ArgStr[2], &dest_adr_vals, MModReg | MModMem))
  2445.     return;
  2446.  
  2447.   BAsmCode[CodeLen] = Lo(code);
  2448.   EncodeFormat1Or2(Lo(code), &src_adr_vals, &dest_adr_vals);
  2449. }
  2450.  
  2451. /*!------------------------------------------------------------------------
  2452.  * \fn     DecodeBit(Word code)
  2453.  * \brief  decode bit operations
  2454.  * \param  code machine code
  2455.  * ------------------------------------------------------------------------ */
  2456.  
  2457. static void DecodeBit(Word code)
  2458. {
  2459.   tAdrVals offset_adr_vals, base_adr_vals;
  2460.  
  2461.   if (ChkArgCnt(2, 2)
  2462.    && ChkNoAttrPart())
  2463.   {
  2464.     OpSize = eSymbolSize32Bit;
  2465.  
  2466.     if (DecodeAdr(&ArgStr[1], &offset_adr_vals, MModMem | MModReg | MModImm)
  2467.      && DecodeAdr(&ArgStr[2], &base_adr_vals, MModMem | MModReg))
  2468.     {
  2469.       chk_imm_value_range(&ArgStr[1], &offset_adr_vals, "offset", 31);
  2470.  
  2471.       BAsmCode[CodeLen] = Lo(code);
  2472.       EncodeFormat1Or2(0, &offset_adr_vals, &base_adr_vals);
  2473.     }
  2474.   }
  2475. }
  2476.  
  2477. /*!------------------------------------------------------------------------
  2478.  * \fn     DecodeIN_OUT(Word code)
  2479.  * \brief  handle IN & OUT instructions
  2480.  * \param  code machine code for 8 bit opsize; MSB -> is OUT
  2481.  * ------------------------------------------------------------------------ */
  2482.  
  2483. static void DecodeIN_OUT(Word code)
  2484. {
  2485.   tAdrVals src_adr_vals, dest_adr_vals;
  2486.   Boolean is_out = !!(Hi(code) & 1);
  2487.  
  2488.   if (ChkArgCnt(2, 2)
  2489.    && chk_sup_mode(code)
  2490.    && ChkOpSize(Lo(code), Lo(code) + 2, 0x100 | Lo(code + 4), -1)
  2491.    && DecodeAdr(&ArgStr[1], &src_adr_vals, is_out ? (MModImm | MModReg | MModMem) : (MModMem | MModIO))
  2492.    && DecodeAdr(&ArgStr[2], &dest_adr_vals, is_out ? (MModMem | MModIO) : (MModReg | MModMem)))
  2493.     EncodeFormat1Or2(0, &src_adr_vals, &dest_adr_vals);
  2494. }
  2495.  
  2496.  
  2497. /*!------------------------------------------------------------------------
  2498.  * \fn     DecodeArith_B(Word code)
  2499.  * \brief  handle format 1/2 instructions with fixed 8 bit size
  2500.  * \param  code machine code
  2501.  * ------------------------------------------------------------------------ */
  2502.  
  2503. static void DecodeArith_B(Word code)
  2504. {
  2505.   tAdrVals src_adr_vals, dest_adr_vals;
  2506.  
  2507.   if (ChkArgCnt(2, 2)
  2508.    && chk_sup_mode(code)
  2509.    && ChkOpSize(0x100 | Lo(code), -1, -1, -1)
  2510.    && DecodeAdr(&ArgStr[1], &src_adr_vals, MModImm | MModReg | MModMem)
  2511.    && DecodeAdr(&ArgStr[2], &dest_adr_vals, imm_mask_cond(code) | MModReg | MModMem))
  2512.     EncodeFormat1Or2(0, &src_adr_vals, &dest_adr_vals);
  2513. }
  2514.  
  2515. /*!------------------------------------------------------------------------
  2516.  * \fn     DecodeArith_W(Word code)
  2517.  * \brief  handle format 1/2 instructions with fixed 32 bit size
  2518.  * \param  code machine code
  2519.  * ------------------------------------------------------------------------ */
  2520.  
  2521. static void DecodeArith_W(Word code)
  2522. {
  2523.   tAdrVals src_adr_vals, dest_adr_vals;
  2524.  
  2525.   if (ChkArgCnt(2, 2)
  2526.    && chk_sup_mode(code)
  2527.    && ChkOpSize(-1, -1, 0x100 | Lo(code), -1)
  2528.    && DecodeAdr(&ArgStr[1], &src_adr_vals, MModImm | MModReg | MModMem)
  2529.    && DecodeAdr(&ArgStr[2], &dest_adr_vals, imm_mask_cond(code) | MModReg | MModMem))
  2530.     EncodeFormat1Or2(0, &src_adr_vals, &dest_adr_vals);
  2531. }
  2532.  
  2533. /*!------------------------------------------------------------------------
  2534.  * \fn     DecodeLDTASK(Word code)
  2535.  * \brief  Handle LDTASK Instruction
  2536.  * \param  code machine code
  2537.  * ------------------------------------------------------------------------ */
  2538.  
  2539. static void DecodeLDTASK(Word code)
  2540. {
  2541.   if (ChkArgCnt(2, 2)
  2542.    && chk_sup_mode(code)
  2543.    && ChkNoAttrPart())
  2544.   {
  2545.     tAdrVals list_adr_vals, tcb_ptr_adr_vals;
  2546.  
  2547.     OpSize = eSymbolSize32Bit;
  2548.     if (DecodeAdr(&ArgStr[1], &list_adr_vals, MModImm | MModReg | MModMem)
  2549.      && DecodeAdr(&ArgStr[2], &tcb_ptr_adr_vals, MModImm | MModReg | MModMem))
  2550.     {
  2551.       BAsmCode[CodeLen] = Lo(code);
  2552.       EncodeFormat1Or2(0, &list_adr_vals, &tcb_ptr_adr_vals);
  2553.     }
  2554.   }
  2555. }
  2556.  
  2557. /*!------------------------------------------------------------------------
  2558.  * \fn     DecodeMOVEA(Word code)
  2559.  * \brief  Handle MOVEA Instruction
  2560.  * \param  code machine code for 8 bit operand size
  2561.  * ------------------------------------------------------------------------ */
  2562.  
  2563. static void DecodeMOVEA(Word code)
  2564. {
  2565.   tAdrVals src_adr_vals, dest_adr_vals;
  2566.  
  2567.   if (ChkArgCnt(2, 2)
  2568.     && ChkOpSize(Lo(code), Lo(code) + 2, 0x100 | (Lo(code) + 4), -1)
  2569.     && DecodeAdr(&ArgStr[1], &src_adr_vals, MModMem))
  2570.   {
  2571.     OpSize = eSymbolSize32Bit;
  2572.     if (DecodeAdr(&ArgStr[2], &dest_adr_vals, MModReg | MModMem))
  2573.       EncodeFormat1Or2(0, &src_adr_vals, &dest_adr_vals);
  2574.   }
  2575. }
  2576.  
  2577. /*!------------------------------------------------------------------------
  2578.  * \fn     DecodeMOV(Word Code)
  2579.  * \brief  handle MOV instruction
  2580.  * ------------------------------------------------------------------------ */
  2581.  
  2582. static void DecodeMOV(Word Code)
  2583. {
  2584.   tAdrVals src_adr_vals, dest_adr_vals;
  2585.  
  2586.   UNUSED(Code);
  2587.  
  2588.   if (ChkArgCnt(2, 2)
  2589.    && ChkOpSize(0x09, 0x1b, 0x12d, 0x3f)
  2590.    && DecodeAdr(&ArgStr[1], &src_adr_vals, MModMem | MModImm | MModReg)
  2591.    && DecodeAdr(&ArgStr[2], &dest_adr_vals, MModMem | MModReg))
  2592.     EncodeFormat1Or2(0x00, &src_adr_vals, &dest_adr_vals);
  2593. }
  2594.  
  2595. /*!------------------------------------------------------------------------
  2596.  * \fn     CodePORT(Word code)
  2597.  * \brief  handle PORT statement
  2598.  * ------------------------------------------------------------------------ */
  2599.  
  2600. static void CodePORT(Word code)
  2601. {
  2602.   UNUSED(code);
  2603.   CodeEquate(SegIO, 0, SegLimits[SegIO]);
  2604. }
  2605.  
  2606. /*--------------------------------------------------------------------------*/
  2607. /* Instruction Lookup Table */
  2608.  
  2609. /*!------------------------------------------------------------------------
  2610.  * \fn     InitFields(void)
  2611.  * \brief  create lookup table
  2612.  * ------------------------------------------------------------------------ */
  2613.  
  2614. static void AddCondition(const char *p_name, Word code)
  2615. {
  2616.   char name[10];
  2617.  
  2618.   order_array_rsv_end(Conditions, tCondition);
  2619.   strmaxcpy(Conditions[InstrZ].name, p_name, sizeof(Conditions[InstrZ].name));
  2620.   Conditions[InstrZ].code = code;
  2621.   InstrZ++;
  2622.  
  2623.   if (*p_name)
  2624.   {
  2625.     as_snprintf(name, sizeof(name), "B%s", p_name);
  2626.     AddInstTable(InstTable, name, 0x70 | code, Decode_4);
  2627.     as_snprintf(name, sizeof(name), "DB%s", p_name);
  2628.     AddInstTable(InstTable, name, 0xc6 | (code & 1) | ((code << 7) & 0x0700), Decode_6);
  2629.   }
  2630. }
  2631.  
  2632. static void InitFields(void)
  2633. {
  2634.   InstTable = CreateInstTable(201);
  2635.   SetDynamicInstTable(InstTable);
  2636.  
  2637.   AddInstTable(InstTable, "ABSF"   , 0x0a5c, DecodeArithF);
  2638.   AddInstTable(InstTable, "ADDF"   , 0x185c, DecodeArithF);
  2639.   AddInstTable(InstTable, "CMPF"   , 0x005c, DecodeArithF);
  2640.   AddInstTable(InstTable, "DIVF"   , 0x1b5c, DecodeArithF);
  2641.   AddInstTable(InstTable, "MOVF"   , 0x085c, DecodeArithF);
  2642.   AddInstTable(InstTable, "MULF"   , 0x1a5c, DecodeArithF);
  2643.   AddInstTable(InstTable, "NEGF"   , 0x095c, DecodeArithF);
  2644.   AddInstTable(InstTable, "SUBF"   , 0x195c, DecodeArithF);
  2645.   AddInstTable(InstTable, "SCLF"   , 0x105c, DecodeSCLF);
  2646.  
  2647.   AddInstTable(InstTable, "ADD"    , 0x80, DecodeArith);
  2648.   AddInstTable(InstTable, "ADDC"   , 0x90, DecodeArith);
  2649.   AddInstTable(InstTable, "AND"    , 0xa0, DecodeArith);
  2650.   AddInstTable(InstTable, "CMP"    , CODE_FLAG_OP2_IMM | 0xb8, DecodeArith);
  2651.   AddInstTable(InstTable, "DIV"    , 0xa1, DecodeArith);
  2652.   AddInstTable(InstTable, "DIVU"   , 0xb1, DecodeArith);
  2653.   AddInstTable(InstTable, "MUL"    , 0x81, DecodeArith);
  2654.   AddInstTable(InstTable, "MULU"   , 0x91, DecodeArith);
  2655.   AddInstTable(InstTable, "NEG"    , 0x39, DecodeArith);
  2656.   AddInstTable(InstTable, "NOT"    , 0x38, DecodeArith);
  2657.   AddInstTable(InstTable, "OR"     , 0x88, DecodeArith);
  2658.   AddInstTable(InstTable, "REM"    , 0x50, DecodeArith);
  2659.   AddInstTable(InstTable, "REMU"   , 0x51, DecodeArith);
  2660.   AddInstTable(InstTable, "SUB"    , 0xa8, DecodeArith);
  2661.   AddInstTable(InstTable, "SUBC"   , 0x98, DecodeArith);
  2662.   AddInstTable(InstTable, "XOR"    , 0xb0, DecodeArith);
  2663.  
  2664.   AddInstTable(InstTable, "DIVX"   , 0x00a6, DecodeArithX);
  2665.   AddInstTable(InstTable, "DIVUX"  , 0x00b6, DecodeArithX);
  2666.   AddInstTable(InstTable, "MULX"   , 0x0086, DecodeArithX);
  2667.   AddInstTable(InstTable, "MULUX"  , 0x0096, DecodeArithX);
  2668.  
  2669.   AddInstTable(InstTable, "ADDDC"  , 0x0059, DecodeArith_7c);
  2670.   AddInstTable(InstTable, "SUBDC"  , 0x0159, DecodeArith_7c);
  2671.   AddInstTable(InstTable, "SUBRDC" , 0x0259, DecodeArith_7c);
  2672.  
  2673.   AddInstTable(InstTable, "ANDBSU" , 0x105b, DecodeBitString_7b);
  2674.   AddInstTable(InstTable, "ANDBSD" , 0x115b, DecodeBitString_7b);
  2675.   AddInstTable(InstTable, "ANDNBSU", 0x125b, DecodeBitString_7b);
  2676.   AddInstTable(InstTable, "ANDNBSD", 0x135b, DecodeBitString_7b);
  2677.   AddInstTable(InstTable, "NOTBSU" , 0x0a5b, DecodeBitString_7b);
  2678.   AddInstTable(InstTable, "NOTBSD" , 0x0b5b, DecodeBitString_7b);
  2679.   AddInstTable(InstTable, "MOVBSU" , 0x085b, DecodeBitString_7b);
  2680.   AddInstTable(InstTable, "MOVBSD" , 0x095b, DecodeBitString_7b);
  2681.   AddInstTable(InstTable, "ORBSU"  , 0x145b, DecodeBitString_7b);
  2682.   AddInstTable(InstTable, "ORBSD"  , 0x155b, DecodeBitString_7b);
  2683.   AddInstTable(InstTable, "ORNBSU" , 0x165b, DecodeBitString_7b);
  2684.   AddInstTable(InstTable, "ORNBSD" , 0x175b, DecodeBitString_7b);
  2685.   AddInstTable(InstTable, "XORBSU" , 0x185b, DecodeBitString_7b);
  2686.   AddInstTable(InstTable, "XORBSD" , 0x195b, DecodeBitString_7b);
  2687.   AddInstTable(InstTable, "XORNBSU", 0x1a5b, DecodeBitString_7b);
  2688.   AddInstTable(InstTable, "XORNBSD", 0x1b5b, DecodeBitString_7b);
  2689.  
  2690.   AddInstTable(InstTable, "CMPC",   0x0058, DecodeString_7a);
  2691.   AddInstTable(InstTable, "CMPCF",  0x0158, DecodeString_7a);
  2692.   AddInstTable(InstTable, "CMPCS",  0x0258, DecodeString_7a);
  2693.   AddInstTable(InstTable, "MOVCU",  0x0858, DecodeString_7a);
  2694.   AddInstTable(InstTable, "MOVCD",  0x0958, DecodeString_7a);
  2695.   AddInstTable(InstTable, "MOVCFU", 0x0a58, DecodeString_7a);
  2696.   AddInstTable(InstTable, "MOVCFD", 0x0b58, DecodeString_7a);
  2697.   AddInstTable(InstTable, "MOVCS",  0x0c58, DecodeString_7a);
  2698.   AddInstTable(InstTable, "SCHCU",  0x1858, DecodeString_7b);
  2699.   AddInstTable(InstTable, "SCHCD",  0x1958, DecodeString_7b);
  2700.   AddInstTable(InstTable, "SKPCU",  0x1a58, DecodeString_7b);
  2701.   AddInstTable(InstTable, "SKPCD",  0x1b58, DecodeString_7b);
  2702.  
  2703.   AddInstTable(InstTable, "CMPBFS", CODE_FLAG_OP2_IMM | 0x005d, DecodeBitField_7b);
  2704.   AddInstTable(InstTable, "CMPBFZ", CODE_FLAG_OP2_IMM | 0x015d, DecodeBitField_7b);
  2705.   AddInstTable(InstTable, "CMPBFL", CODE_FLAG_OP2_IMM | 0x025d, DecodeBitField_7b);
  2706.   AddInstTable(InstTable, "SCH0BSU", 0x005b, DecodeBitField_7b);
  2707.   AddInstTable(InstTable, "SCH0BSD", 0x015b, DecodeBitField_7b);
  2708.   AddInstTable(InstTable, "SCH1BSU", 0x025b, DecodeBitField_7b);
  2709.   AddInstTable(InstTable, "SCH1BSD", 0x035b, DecodeBitField_7b);
  2710.   AddInstTable(InstTable, "EXTBFS", CODE_FLAG_LIM32 | 0x085d, DecodeBitField_7b);
  2711.   AddInstTable(InstTable, "EXTBFZ", CODE_FLAG_LIM32 | 0x095d, DecodeBitField_7b);
  2712.   AddInstTable(InstTable, "EXTBFL", CODE_FLAG_LIM32 | 0x0a5d, DecodeBitField_7b);
  2713.   AddInstTable(InstTable, "INSBFR", CODE_FLAG_LIM32 | 0x185d, DecodeBitField_7c);
  2714.   AddInstTable(InstTable, "INSBFL", CODE_FLAG_LIM32 | 0x195d, DecodeBitField_7c);
  2715.  
  2716.   AddInstTable(InstTable, "BRK"    , 0xc8, DecodeFixed);
  2717.   AddInstTable(InstTable, "BRKV"   , 0xc9, DecodeFixed);
  2718.   AddInstTable(InstTable, "CLRTLBA", CODE_FLAG_SUPMODE | 0x10, DecodeFixed);
  2719.   AddInstTable(InstTable, "DISPOSE", 0xcc, DecodeFixed);
  2720.   AddInstTable(InstTable, "HALT"   , 0x00, DecodeFixed);
  2721.   AddInstTable(InstTable, "NOP"    , 0xcd, DecodeFixed);
  2722.   AddInstTable(InstTable, "RSR"    , 0xca, DecodeFixed);
  2723.   AddInstTable(InstTable, "TRAPFL" , 0xcb, DecodeFixed);
  2724.  
  2725.   AddInstTable(InstTable, "MOV"    , 0x00, DecodeMOV);
  2726.  
  2727.   InstrZ = 0;
  2728.   AddCondition("GT", 0xf);
  2729.   AddCondition("GE", 0xd);
  2730.   AddCondition("LT", 0xc);
  2731.   AddCondition("LE", 0xe);
  2732.   AddCondition("H" , 0x7);
  2733.   AddCondition("NL", 0x3);
  2734.   AddCondition("L" , 0x2);
  2735.   AddCondition("NH", 0x6);
  2736.   AddCondition("E" , 0x4);
  2737.   AddCondition("NE", 0x5);
  2738.   AddCondition("V" , 0x0);
  2739.   AddCondition("NV", 0x1);
  2740.   AddCondition("N" , 0x8);
  2741.   AddCondition("P" , 0x9);
  2742.   AddCondition("C" , 0x2);
  2743.   AddCondition("NC", 0x3);
  2744.   AddCondition("Z" , 0x4);
  2745.   AddCondition("NZ", 0x5);
  2746.   AddCondition(""  , 0);
  2747.   AddInstTable(InstTable, "BR", 0x7a, Decode_4);
  2748.   AddInstTable(InstTable, "DBR", 0x05c6, Decode_6);
  2749.   AddInstTable(InstTable, "TB", 0x05c7, Decode_6);
  2750.   AddInstTable(InstTable, "BSR", 0x48, Decode_4);
  2751.  
  2752.   AddInstTable(InstTable, "CLRTLB", CODE_FLAG_SUPMODE | 0xfe, DecodeCLRTLB);
  2753.   AddInstTable(InstTable, "GETPSW", 0xf6, DecodeGETPSW);
  2754.   AddInstTable(InstTable, "UPDPSW", 0x134a, DecodeUPDPSW);
  2755.   AddInstTable(InstTable, "DEC", 0xd0, DecodeFormat3_bhw);
  2756.   AddInstTable(InstTable, "INC", 0xd8, DecodeFormat3_bhw);
  2757.   AddInstTable(InstTable, "TEST", 0xf0 | CODE_FLAG_OP2_IMM, DecodeFormat3_bhw);
  2758.   AddInstTable(InstTable, "JMP", 0xd6, DecodeJMP_JSR);
  2759.   AddInstTable(InstTable, "JSR", 0xe8, DecodeJMP_JSR);
  2760.   AddInstTable(InstTable, "POP", 0xe6, DecodeFormat3_W);
  2761.   AddInstTable(InstTable, "PUSH", CODE_FLAG_OP2_IMM | 0xee, DecodeFormat3_W);
  2762.   AddInstTable(InstTable, "POPM", CODE_FLAG_OP2_IMM | 0xe4, DecodeFormat3_W);
  2763.   AddInstTable(InstTable, "PUSHM", CODE_FLAG_OP2_IMM | 0xec, DecodeFormat3_W);
  2764.   AddInstTable(InstTable, "PREPARE", CODE_FLAG_OP2_IMM | 0xde, DecodeFormat3_W);
  2765.   AddInstTable(InstTable, "STTASK", CODE_FLAG_OP2_IMM | CODE_FLAG_SUPMODE | 0xfc, DecodeFormat3_W);
  2766.   AddInstTable(InstTable, "RET", CODE_FLAG_OP2_IMM | 0xe2, DecodeFormat3_H);
  2767.   AddInstTable(InstTable, "RETIS", CODE_FLAG_OP2_IMM | CODE_FLAG_SUPMODE | 0xfa, DecodeFormat3_H);
  2768.   AddInstTable(InstTable, "RETIU", CODE_FLAG_OP2_IMM | CODE_FLAG_SUPMODE | 0xea, DecodeFormat3_H);
  2769.   AddInstTable(InstTable, "TASI", 0xe0, DecodeFormat3_B);
  2770.   AddInstTable(InstTable, "TRAP", CODE_FLAG_OP2_IMM | 0xf8, DecodeFormat3_B);
  2771.   AddInstTable(InstTable, "CALL", 0x49, DecodeCALL);
  2772.   AddInstTable(InstTable, "ROT",  0x89, DecodeShift);
  2773.   AddInstTable(InstTable, "ROTC", 0x99, DecodeShift);
  2774.   AddInstTable(InstTable, "SHA",  0xb9, DecodeShift);
  2775.   AddInstTable(InstTable, "SHL",  0xa9, DecodeShift);
  2776.   AddInstTable(InstTable, "CHKAR", 0x4d, DecodeCHKA);
  2777.   AddInstTable(InstTable, "CHKAW", 0x4e, DecodeCHKA);
  2778.   AddInstTable(InstTable, "CHKAE", 0x4f, DecodeCHKA);
  2779.   AddInstTable(InstTable, "CAXI", 0x4c, DecodeCAXI);
  2780.   AddInstTable(InstTable, "CHLVL", 0x4b, DecodeCHLVL);
  2781.   AddInstTable(InstTable, "GETATE", CODE_FLAG_SUPMODE | 0x05, DecodeGETXTE);
  2782.   AddInstTable(InstTable, "UPDATE", CODE_FLAG_SUPMODE | 0x15, DecodeGETXTE);
  2783.   AddInstTable(InstTable, "GETPTE", CODE_FLAG_SUPMODE | 0x04, DecodeGETXTE);
  2784.   AddInstTable(InstTable, "UPDPTE", CODE_FLAG_OP2_IMM | CODE_FLAG_SUPMODE | 0x14, DecodeGETXTE);
  2785.   AddInstTable(InstTable, "GETRA", CODE_FLAG_SUPMODE | 0x03, DecodeGETXTE);
  2786.   AddInstTable(InstTable, "CLR1", 0xa7, DecodeBit);
  2787.   AddInstTable(InstTable, "NOT1", 0xb7, DecodeBit);
  2788.   AddInstTable(InstTable, "SET1", 0x97, DecodeBit);
  2789.   AddInstTable(InstTable, "TEST1", 0x87, DecodeBit);
  2790.   AddInstTable(InstTable, "CVT", 0, DecodeCVT);
  2791.   AddInstTable(InstTable, "CVTD", 0x1059, DecodeCVTD);
  2792.   AddInstTable(InstTable, "MOVS", 0x0a, DecodeMOVS_MOVZ);
  2793.   AddInstTable(InstTable, "MOVT", 0x19, DecodeMOVT);
  2794.   AddInstTable(InstTable, "MOVZ", 0x0b, DecodeMOVS_MOVZ);
  2795.   /* TODO: 0x31 for IN is guessed, same opcode for IN & OUT in manual? */
  2796.   AddInstTable(InstTable, "IN" , CODE_FLAG_SUPMODE | 0x0031, DecodeIN_OUT);
  2797.   AddInstTable(InstTable, "OUT", CODE_FLAG_SUPMODE | 0x0121, DecodeIN_OUT);
  2798.   AddInstTable(InstTable, "RVBIT", 0x08, DecodeArith_B);
  2799.   AddInstTable(InstTable, "RVBYTE", 0x2c, DecodeArith_W);
  2800.   AddInstTable(InstTable, "LDPR", CODE_FLAG_SUPMODE | CODE_FLAG_OP2_IMM | 0x12, DecodeArith_W);
  2801.   AddInstTable(InstTable, "STPR", CODE_FLAG_SUPMODE | 0x02, DecodeArith_W);
  2802.   AddInstTable(InstTable, "LDTASK", CODE_FLAG_SUPMODE  | 0x01, DecodeLDTASK);
  2803.   AddInstTable(InstTable, "MOVEA", 0x40, DecodeMOVEA);
  2804.   AddInstTable(InstTable, "XCH", 0x41, DecodeXCH);
  2805.   AddInstTable(InstTable, "SETF", 0x47, DecodeSETF);
  2806.  
  2807.   AddInstTable(InstTable, "REG", 0, CodeREG);
  2808.   AddInstTable(InstTable, "PORT", 0, CodePORT);
  2809. }
  2810.  
  2811. /*!------------------------------------------------------------------------
  2812.  * \fn     DeinitFields(void)
  2813.  * \brief  destroy/cleanup lookup table
  2814.  * ------------------------------------------------------------------------ */
  2815.  
  2816. static void DeinitFields(void)
  2817. {
  2818.   order_array_free(Conditions);
  2819.   DestroyInstTable(InstTable);
  2820. }
  2821.  
  2822. /*--------------------------------------------------------------------------*/
  2823. /* Interface Functions */
  2824.  
  2825. /*!------------------------------------------------------------------------
  2826.  * \fn     InternSymbol_V60(char *pArg, TempResult *pResult)
  2827.  * \brief  handle built-in (register) symbols for V60
  2828.  * \param  pArg source argument
  2829.  * \param  pResult result buffer
  2830.  * ------------------------------------------------------------------------ */
  2831.  
  2832. static void InternSymbol_V60(char *pArg, TempResult *pResult)
  2833. {
  2834.   Byte RegNum;
  2835.  
  2836.   if (DecodeRegCore(pArg, &RegNum))
  2837.   {
  2838.     pResult->Typ = TempReg;
  2839.     pResult->DataSize = eSymbolSize32Bit;
  2840.     pResult->Contents.RegDescr.Reg = RegNum;
  2841.     pResult->Contents.RegDescr.Dissect = DissectReg_V60;
  2842.     pResult->Contents.RegDescr.compare = NULL;
  2843.   }
  2844. }
  2845.  
  2846. /*!------------------------------------------------------------------------
  2847.  * \fn     DecodeAttrPart_V60(void)
  2848.  * \brief  handle/decode attribute
  2849.  * \return True if success
  2850.  * ------------------------------------------------------------------------ */
  2851.  
  2852. static Boolean DecodeAttrPart_V60(void)
  2853. {
  2854.   int l = strlen(AttrPart.str.p_str), z;
  2855.  
  2856.   if (l > 2)
  2857.   {
  2858. badattr:
  2859.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  2860.     return False;
  2861.   }
  2862.  
  2863.   for (z = 0; z < l; z++)
  2864.     switch (as_toupper(AttrPart.str.p_str[z]))
  2865.     {
  2866.       case 'B': AttrPartOpSize[z] = eSymbolSize8Bit; break;
  2867.       case 'H': AttrPartOpSize[z] = eSymbolSize16Bit; break;
  2868.       case 'W': AttrPartOpSize[z] = eSymbolSize32Bit; break;
  2869.       case 'D': AttrPartOpSize[z] = eSymbolSize64Bit; break;
  2870.       case 'P': AttrPartOpSize[z] = eSymbolSize24Bit; break;
  2871.       case 'S': AttrPartOpSize[z] = eSymbolSizeFloat32Bit; break;
  2872.       case 'L': AttrPartOpSize[z] = eSymbolSizeFloat64Bit; break;
  2873.       case 'Z': AttrPartOpSize[z] = eSymbolSizeFloatDec96Bit; break; /* just for cvtd.pz/zp */
  2874.       case '\0': break;
  2875.       default:
  2876.         goto badattr;
  2877.     }
  2878.   return True;
  2879. }
  2880.  
  2881. /*!------------------------------------------------------------------------
  2882.  * \fn     MakeCode_V60(void)
  2883.  * \brief  encode machine instruction
  2884.  * ------------------------------------------------------------------------ */
  2885.  
  2886. static void MakeCode_V60(void)
  2887. {
  2888.   CodeLen = 0; DontPrint = False;
  2889.   OpSize = eSymbolSizeUnknown;
  2890.  
  2891.   /* to be ignored */
  2892.  
  2893.   if (Memo("")) return;
  2894.  
  2895.   /* Pseudo Instructions */
  2896.  
  2897.   if (DecodeMoto16Pseudo(AttrPartOpSize[0], False))
  2898.     return;
  2899.  
  2900.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  2901.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  2902. }
  2903.  
  2904. /*!------------------------------------------------------------------------
  2905.  * \fn     IsDef_V60(void)
  2906.  * \brief  check whether insn makes own use of label
  2907.  * \return True if yes
  2908.  * ------------------------------------------------------------------------ */
  2909.  
  2910. static Boolean IsDef_V60(void)
  2911. {
  2912.   return Memo("REG")
  2913.       || Memo("PORT");
  2914. }
  2915.  
  2916. /*!------------------------------------------------------------------------
  2917.  * \fn     SwitchFrom_V60(void)
  2918.  * \brief  deinitialize as target
  2919.  * ------------------------------------------------------------------------ */
  2920.  
  2921. static void SwitchFrom_V60(void)
  2922. {
  2923.   DeinitFields();
  2924. }
  2925.  
  2926. /*!------------------------------------------------------------------------
  2927.  * \fn     SwitchTo_V60(void *pUser)
  2928.  * \brief  prepare to assemble code for this target
  2929.  * \param  pUser CPU properties
  2930.  * ------------------------------------------------------------------------ */
  2931.  
  2932. static void SwitchTo_V60(void)
  2933. {
  2934.   const TFamilyDescr *pDescr = FindFamilyByName("V60");
  2935.  
  2936.   TurnWords = True;
  2937.   SetIntConstMode(eIntConstModeIntel);
  2938.  
  2939.   PCSymbol = "$"; HeaderID = pDescr->Id;
  2940.   NOPCode = 0x00;
  2941.   DivideChars = ",";
  2942.   HasAttrs = True;
  2943.   AttrChars = ".";
  2944.  
  2945.   ValidSegs = (1 << SegCode) | (1 << SegIO);
  2946.   Grans[SegCode] = Grans[SegIO] = 1;
  2947.   ListGrans[SegCode] = ListGrans[SegIO] = 1;
  2948.   SegInits[SegCode] = SegInits[SegIO] = 0;
  2949.   SegLimits[SegCode] = 0xfffffffful;
  2950.   SegLimits[SegIO] = 0xfffffful;
  2951.  
  2952.   DecodeAttrPart = DecodeAttrPart_V60;
  2953.   MakeCode = MakeCode_V60;
  2954.   IsDef = IsDef_V60;
  2955.   SwitchFrom = SwitchFrom_V60;
  2956.   InternSymbol = InternSymbol_V60;
  2957.   DissectReg = DissectReg_V60;
  2958.   AddMoto16PseudoONOFF(False);
  2959.  
  2960.   onoff_supmode_add();
  2961.  
  2962.   InitFields();
  2963. }
  2964.  
  2965. /*!------------------------------------------------------------------------
  2966.  * \fn     codev60_init(void)
  2967.  * \brief  register target to AS
  2968.  * ------------------------------------------------------------------------ */
  2969.  
  2970. void codev60_init(void)
  2971. {
  2972.   (void)AddCPU("70616", SwitchTo_V60);
  2973. }
  2974.