Subversion Repositories pentevo

Rev

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

  1. /* codez8000.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator Zilog Z8000                                                 */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <stdarg.h>
  14. #include <ctype.h>
  15.  
  16. #include "cpulist.h"
  17. #include "headids.h"
  18. #include "strutil.h"
  19. #include "intformat.h"
  20. #include "bpemu.h"
  21. #include "asmdef.h"
  22. #include "asmsub.h"
  23. #include "asmpars.h"
  24. #include "asmallg.h"
  25. #include "onoff_common.h"
  26. #include "asmitree.h"
  27. #include "asmstructs.h"
  28. #include "codepseudo.h"
  29. #include "codevars.h"
  30. #include "intpseudo.h"
  31. #include "operator.h"
  32.  
  33. #include "codez8000.h"
  34.  
  35. typedef enum
  36. {
  37.   eCoreNone = 0,
  38.   eCoreZ8001 = 1,
  39.   eCoreZ8003 = 2
  40. } tCore;
  41.  
  42. typedef struct
  43. {
  44.   const char *pName;
  45.   tCore Core;
  46.   Boolean SuppSegmented;
  47. } tCPUProps;
  48.  
  49. typedef enum eAdrMode
  50. {
  51.   eModNone = 0,
  52.   eModReg = 1,
  53.   eModIReg = 2,
  54.   eModDirect = 3,
  55.   eModIndexed = 4,
  56.   eModBaseAddress = 5,
  57.   eModBaseIndexed = 6,
  58.   eModImm = 7,
  59.   eModCtl = 8
  60. } tAdrMode;
  61.  
  62. #define MModReg (1 << eModReg)
  63. #define MModIReg (1 << eModIReg)
  64. #define MModDirect (1 << eModDirect)
  65. #define MModIndexed (1 << eModIndexed)
  66. #define MModBaseAddress (1 << eModBaseAddress)
  67. #define MModBaseIndexed (1 << eModBaseIndexed)
  68. #define MModImm (1 << eModImm)
  69. #define MModCtl (1 << eModCtl)
  70.  
  71. #define MModIO (1 << 15)
  72.  
  73. #define MModNoImm (MModReg | MModIReg | MModDirect | MModIndexed | MModBaseAddress | MModBaseIndexed)
  74. #define MModAll (MModNoImm | MModImm)
  75.  
  76. #define eSymbolSize4Bit ((tSymbolSize)-2)
  77. #define eSymbolSize3Bit ((tSymbolSize)-3)
  78.  
  79. typedef struct
  80. {
  81.   tAdrMode Mode;
  82.   unsigned Cnt;
  83.   Word Val, Vals[3];
  84. } tAdrVals;
  85.  
  86. typedef struct
  87. {
  88.   Word Code;
  89.   Boolean Privileged;
  90. } FixedOrder;
  91.  
  92. typedef enum
  93. {
  94.   ePrivileged = 1 << 0,
  95.   eSegMode = 1 << 1,
  96.   eNonSegMode = 1 << 2
  97. } tCtlFlags;
  98.  
  99. typedef struct
  100. {
  101.   const char *pName;
  102.   Word Code;
  103.   tCtlFlags Flags;
  104.   tSymbolSize Size;
  105. } tCtlReg;
  106.  
  107. typedef struct
  108. {
  109.   const char *pName;
  110.   Word Code;
  111. } tCondition;
  112.  
  113. /* Auto-optimization of LD #imm4,Rn -> LDK disabled for the moment,
  114.    until we find a syntax to control it: */
  115.  
  116. #define OPT_LD_LDK 0
  117.  
  118. static const tCPUProps *pCurrCPUProps;
  119.  
  120. static FixedOrder *FixedOrders;
  121. static tCtlReg *CtlRegs;
  122. static tCondition *Conditions;
  123. static int CtlRegCnt;
  124.  
  125. static tSymbolSize OpSize;
  126. static ShortInt ImmOpSize;
  127. static IntType MemIntType;
  128.  
  129. static LongInt AMDSyntax;
  130.  
  131. #ifdef __cplusplus
  132. #include "codez8000.hpp"
  133. #endif
  134.  
  135. /*--------------------------------------------------------------------------*/
  136. /* Helper Functions */
  137.  
  138. /*!------------------------------------------------------------------------
  139.  * \fn     CheckSup(Boolean Required)
  140.  * \brief  check whether supervisor mode requirement and complain if violated
  141.  * \param  Required is supervisor mode required?
  142.  * \return False if violated
  143.  * ------------------------------------------------------------------------ */
  144.  
  145. static Boolean CheckSup(Boolean Required)
  146. {
  147.   if (!SupAllowed && Required)
  148.   {
  149.     WrStrErrorPos(ErrNum_PrivOrder, &OpPart);
  150.     return False;
  151.   }
  152.   return True;
  153. }
  154.  
  155. /*!------------------------------------------------------------------------
  156.  * \fn     Segmented(void)
  157.  * \brief  operating in segmented mode?
  158.  * \return True if yes
  159.  * ------------------------------------------------------------------------ */
  160.  
  161. static Boolean Segmented(void)
  162. {
  163.   return pCurrCPUProps->SuppSegmented;
  164. }
  165.  
  166. /*!------------------------------------------------------------------------
  167.  * \fn     AddrRegSize(void)
  168.  * \brief  return size of address register
  169.  * \return 16 or 32 bit
  170.  * ------------------------------------------------------------------------ */
  171.  
  172. static tSymbolSize AddrRegSize(void)
  173. {
  174.   return Segmented() ? eSymbolSize32Bit : eSymbolSize16Bit;
  175. }
  176.  
  177. /*!------------------------------------------------------------------------
  178.  * \fn     GetSegment(LongWord Address)
  179.  * \brief  extract segment from (linear) address
  180.  * \param  Address (linear) address
  181.  * \return segment
  182.  * ------------------------------------------------------------------------ */
  183.  
  184. static Word GetSegment(LongWord Address)
  185. {
  186.  return (Address >> 16) & 0x7f;
  187. }
  188.  
  189. /*--------------------------------------------------------------------------*/
  190. /* Register Handling */
  191.  
  192. /*!------------------------------------------------------------------------
  193.  * \fn     DecodeRegCore(const char *pArg, Word *pValue, tSymbolSize *pSize)
  194.  * \brief  check whether argument describes a CPU (general purpose) register
  195.  * \param  pArg source argument
  196.  * \param  pValue register number if yes
  197.  * \param  pSize register size if yes
  198.  * \return True if it is
  199.  * ------------------------------------------------------------------------ */
  200.  
  201. static Boolean DecodeRegCore(const char *pArg, Word *pValue, tSymbolSize *pSize)
  202. {
  203.   Word Offset = 0, MaskVal, MaxVal;
  204.  
  205.   if (as_toupper(*pArg) != 'R')
  206.     return False;
  207.   pArg++;
  208.  
  209.   switch (as_toupper(*pArg))
  210.   {
  211.     case 'H':
  212.       *pSize = eSymbolSize8Bit;
  213.       MaskVal = 0; MaxVal = 7;
  214.       pArg++;
  215.       goto Num;
  216.     case 'L':
  217.       *pSize = eSymbolSize8Bit;
  218.       Offset = 8;
  219.       MaskVal = 0; MaxVal = 15;
  220.       pArg++;
  221.       goto Num;
  222.     case 'R':
  223.       *pSize = eSymbolSize32Bit;
  224.       MaskVal = 1; MaxVal = 15;
  225.       pArg++;
  226.       goto Num;
  227.     case 'Q':
  228.       *pSize = eSymbolSize64Bit;
  229.       MaskVal = 3; MaxVal = 15;
  230.       pArg++;
  231.       goto Num;
  232.     default:
  233.       *pSize = eSymbolSize16Bit;
  234.       MaskVal = 0; MaxVal = 15;
  235.       /* fall-thru */
  236.     Num:
  237.     {
  238.       char *pEnd;
  239.  
  240.       *pValue = strtoul(pArg, &pEnd, 10) + Offset;
  241.       return !*pEnd && (*pValue <= MaxVal) && !(*pValue & MaskVal);
  242.     }
  243.   }
  244. }
  245.  
  246. /*!------------------------------------------------------------------------
  247.  * \fn     DissectReg_Z8000(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  248.  * \brief  dissect register symbols - Z8000 variant
  249.  * \param  pDest destination buffer
  250.  * \param  DestSize destination buffer size
  251.  * \param  Value numeric register value
  252.  * \param  InpSize register size
  253.  * ------------------------------------------------------------------------ */
  254.  
  255. static void DissectReg_Z8000(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  256. {
  257.   switch (InpSize)
  258.   {
  259.     case eSymbolSize8Bit:
  260.       as_snprintf(pDest, DestSize, "R%c%u", "HL"[(Value >> 3) & 1], (unsigned)(Value & 7));
  261.       break;
  262.     case eSymbolSize16Bit:
  263.       as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
  264.       break;
  265.     case eSymbolSize32Bit:
  266.       as_snprintf(pDest, DestSize, "RR%u", (unsigned)Value);
  267.       break;
  268.     case eSymbolSize64Bit:
  269.       as_snprintf(pDest, DestSize, "RQ%u", (unsigned)Value);
  270.       break;
  271.     default:
  272.       as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
  273.   }
  274. }
  275.  
  276. /*!------------------------------------------------------------------------
  277.  * \fn     ChkRegOverlap(Word FirstReg, int FirstSize, ...)
  278.  * \brief  check for register overlap
  279.  * \param  FirstReg first register #
  280.  * \param  FirstSize first register size
  281.  * \param  ... further num/size pairs
  282.  * \return -1 if no overlap, otherwise index of first conflicting register
  283.  * ------------------------------------------------------------------------ */
  284.  
  285. static int ChkRegOverlap(Word FirstReg, int FirstSize, ...)
  286. {
  287.   LongWord RegUse = 0, ThisUse;
  288.   int Index = 0;
  289.   va_list ap;
  290.  
  291.   va_start(ap, FirstSize);
  292.   while (True)
  293.   {
  294.     switch (FirstSize)
  295.     {
  296.       case eSymbolSize8Bit:
  297.         ThisUse = ((FirstReg & 8) ? 2ul : 1ul) << ((FirstReg & 7) * 2);
  298.         break;
  299.       case eSymbolSize16Bit:
  300.         ThisUse = 3ul << (FirstReg * 2);
  301.         break;
  302.       case eSymbolSize32Bit:
  303.         ThisUse = 15ul << (FirstReg * 2);
  304.         break;
  305.       default:
  306.         va_end(ap);
  307.         return Index;
  308.     }
  309.     if (RegUse & ThisUse)
  310.     {
  311.       va_end(ap);
  312.       return Index;
  313.     }
  314.     RegUse |= ThisUse;
  315.     Index++;
  316.     FirstReg = va_arg(ap, unsigned);
  317.     FirstSize = va_arg(ap, int);
  318.     if (FirstSize == eSymbolSizeUnknown)
  319.       break;
  320.   }
  321.   va_end(ap);
  322.   return -1;
  323. }
  324.  
  325. /*--------------------------------------------------------------------------*/
  326. /* Address Parsing */
  327.  
  328. /*!------------------------------------------------------------------------
  329.  * \fn     DecodeReg(const tStrComp *pArg, Word *pValue, tSymbolSize *pSize, tChkRegSize ChkRegSize, Boolean MustBeReg)
  330.  * \brief  check whether argument is a CPU register or user-defined register alias
  331.  * \param  pArg argument
  332.  * \param  pValue resulting register # if yes
  333.  * \param  pSize resulting register size if yes
  334.  * \param  ChkReqSize optional check callback for register size
  335.  * \param  MustBeReg expecting register or maybe not?
  336.  * \return reg eval result
  337.  * ------------------------------------------------------------------------ */
  338.  
  339. typedef Boolean (*tChkRegSize)(const tStrComp *pArg, tSymbolSize ActSize);
  340.  
  341. static Boolean ChkRegSize_Idx(const tStrComp *pArg, tSymbolSize ActSize)
  342. {
  343.   if (ActSize != eSymbolSize16Bit)
  344.   {
  345.     WrStrErrorPos(ErrNum_IndexRegMustBe16Bit, pArg);
  346.     return False;
  347.   }
  348.   return True;
  349. }
  350.  
  351. static Boolean ChkRegSize_8To32(const tStrComp *pArg, tSymbolSize ActSize)
  352. {
  353.   if (ActSize > eSymbolSize32Bit)
  354.   {
  355.     WrStrErrorPos(ErrNum_InvOpSize, pArg);
  356.     return False;
  357.   }
  358.   return True;
  359. }
  360.  
  361. static Boolean ChkRegSize_IOAddr(const tStrComp *pArg, tSymbolSize ActSize)
  362. {
  363.   if (ActSize != eSymbolSize16Bit)
  364.   {
  365.     WrStrErrorPos(ErrNum_IOAddrRegMustBe16Bit, pArg);
  366.     return False;
  367.   }
  368.   return True;
  369. }
  370.  
  371. static Boolean ChkRegSize_MemAddr(const tStrComp *pArg, tSymbolSize ActSize)
  372. {
  373.   if (Segmented())
  374.   {
  375.     if (ActSize != eSymbolSize32Bit)
  376.     {
  377.       WrStrErrorPos(ErrNum_SegAddrRegMustBe32Bit, pArg);
  378.       return False;
  379.     }
  380.   }
  381.   else
  382.   {
  383.     if (ActSize != eSymbolSize16Bit)
  384.     {
  385.       WrStrErrorPos(ErrNum_NonSegAddrRegMustBe16Bit, pArg);
  386.       return False;
  387.     }
  388.   }
  389.   return True;
  390. }
  391.  
  392. static tRegEvalResult DecodeReg(const tStrComp *pArg, Word *pValue, tSymbolSize *pSize, tChkRegSize ChkRegSize, Boolean MustBeReg)
  393. {
  394.   tEvalResult EvalResult;
  395.   tRegEvalResult RegEvalResult;
  396.  
  397.   if (DecodeRegCore(pArg->str.p_str, pValue, &EvalResult.DataSize))
  398.     RegEvalResult = eIsReg;
  399.   else
  400.   {
  401.     tRegDescr RegDescr;
  402.  
  403.     RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
  404.     if (eIsReg == RegEvalResult)
  405.       *pValue = RegDescr.Reg;
  406.   }
  407.  
  408.   if ((RegEvalResult == eIsReg)
  409.    && ChkRegSize
  410.    && !ChkRegSize(pArg, EvalResult.DataSize))
  411.     RegEvalResult = MustBeReg ? eIsNoReg : eRegAbort;
  412.  
  413.   if (pSize) *pSize = EvalResult.DataSize;
  414.   return RegEvalResult;
  415. }
  416.  
  417. /*!------------------------------------------------------------------------
  418.  * \fn     ClearAdrVals(tAdrVals *pAdrVals)
  419.  * \brief  clear address expression result buffer
  420.  * \param  pAdrVals buffer to clear
  421.  * ------------------------------------------------------------------------ */
  422.  
  423. static void ClearAdrVals(tAdrVals *pAdrVals)
  424. {
  425.   pAdrVals->Mode = eModNone;
  426.   pAdrVals->Cnt = 0;
  427.   pAdrVals->Val = 0;
  428. }
  429.  
  430. /*!------------------------------------------------------------------------
  431.  * \fn     SetOpSize(tSymbolSize Size, const tStrComp *pArg)
  432.  * \brief  set (new) operand size of instruction
  433.  * \param  Size size to set
  434.  * \param  pArg source argument size was deduced from
  435.  * \return True if no conflict
  436.  * ------------------------------------------------------------------------ */
  437.  
  438. static Boolean SetOpSize(tSymbolSize Size, const tStrComp *pArg)
  439. {
  440.   if (OpSize == eSymbolSizeUnknown)
  441.     OpSize = Size;
  442.   else if ((Size != eSymbolSizeUnknown) && (Size != OpSize))
  443.   {
  444.     WrStrErrorPos(ErrNum_ConfOpSizes, pArg);
  445.     return False;
  446.   }
  447.   return True;
  448. }
  449.  
  450. /*!------------------------------------------------------------------------
  451.  * \fn     GetImmIntType(tSymbolSize Size)
  452.  * \brief  retrieve immediate int type fitting to operand size
  453.  * \param  Size operand size
  454.  * \return int type
  455.  * ------------------------------------------------------------------------ */
  456.  
  457. static IntType GetImmIntType(tSymbolSize Size)
  458. {
  459.   switch ((int)Size)
  460.   {
  461.     case eSymbolSize3Bit:
  462.       return UInt3;
  463.     case eSymbolSize4Bit:
  464.       return UInt4;
  465.     case eSymbolSize8Bit:
  466.       return Int8;
  467.     case eSymbolSize16Bit:
  468.       return Int16;
  469.     case eSymbolSize32Bit:
  470.       return Int32;
  471.     default:
  472.       return IntTypeCnt;
  473.   }
  474. }
  475.  
  476. /*!------------------------------------------------------------------------
  477.  * \fn     DecodeAddrPartNum(const tStrComp *pArg, LongInt Disp, tEvalResult *pEvalResult, Boolean IsDirect, Boolean IsIO, Boolean *pForceShortt, Boolean *pIsDirect)
  478.  * \brief  decode address part, for direct/immediate or indexed mode
  479.  * \param  pArg source argument
  480.  * \param  Disp displacement to add to value
  481.  * \param  pAdrVals binary coding of addressing mode
  482.  * \param  IsDirect force treatment as direct address mode
  483.  * \param  IsIO I/O space instead of memory space
  484.  * \param  pForceShort short coding required?
  485.  * \param  pIsDirect classified as direct addressing?
  486.  * \return True if success
  487.  * ------------------------------------------------------------------------ */
  488.  
  489. static LongWord DecodeAddrPartNum(const tStrComp *pArg, LongInt Disp, tEvalResult *pEvalResult, Boolean IsDirect, Boolean IsIO, Boolean *pForceShort, Boolean *pIsDirect)
  490. {
  491.   tStrComp CopyComp;
  492.   String Copy;
  493.   Boolean HasSeg = False;
  494.   LongWord Result, SegNum = 0;
  495.   IntType ThisIntType;
  496.  
  497.   StrCompMkTemp(&CopyComp, Copy, sizeof(Copy));
  498.   StrCompCopy(&CopyComp, pArg);
  499.   *pForceShort = False;
  500.  
  501.   /* deal with |....| and <<seg>>offs only in segmented mode: */
  502.  
  503.   if (!IsIO && Segmented())
  504.   {
  505.     int Len = strlen(CopyComp.str.p_str);
  506.  
  507.     if ((Len >= 2) && (CopyComp.str.p_str[0] == '|') && (CopyComp.str.p_str[Len - 1] == '|'))
  508.     {
  509.       StrCompShorten(&CopyComp, 1);
  510.       StrCompCutLeft(&CopyComp, 1);
  511.       KillPrefBlanksStrComp(&CopyComp);
  512.       KillPostBlanksStrComp(&CopyComp);
  513.       *pForceShort = True;
  514.       IsDirect = True;
  515.       Len -= 2;
  516.     }
  517.     if (!strncmp(CopyComp.str.p_str, "<<", 2))
  518.     {
  519.       char *pRun, *pSplitPos = NULL;
  520.       int Nest = 0;
  521.       Boolean InSgl = False, InDbl = False, Found = False;
  522.  
  523.       for (pRun = CopyComp.str.p_str + 2; *pRun && !Found; pRun++)
  524.       {
  525.         switch (*pRun)
  526.         {
  527.           case '\'':
  528.             if (!InDbl) InSgl = !InSgl;
  529.             break;
  530.           case '"':
  531.             if (!InSgl) InDbl = !InDbl;
  532.             break;
  533.           case '(':
  534.             if (!InSgl && !InDbl) Nest++;
  535.             break;
  536.           case ')':
  537.             if (!InSgl && !InDbl) Nest--;
  538.             break;
  539.           case '>':
  540.             if (!InSgl && !InDbl && !Nest && (pRun[1] == '>'))
  541.               pSplitPos = pRun;
  542.             break;
  543.           default:
  544.             if (pSplitPos)
  545.             {
  546.               if (as_isspace(*pRun)); /* delay decision to to next non-blank */
  547.               else if (as_isalnum(*pRun) || (*pRun == '('))
  548.                 Found = True;
  549.               else
  550.                 pSplitPos = NULL;
  551.             }
  552.         }
  553.       }
  554.       if (pSplitPos)
  555.       {
  556.         tStrComp SegArg;
  557.  
  558.         StrCompSplitRef(&SegArg, &CopyComp, &CopyComp, pSplitPos);
  559.         StrCompIncRefLeft(&CopyComp, 1);
  560.         SegNum = EvalStrIntExpressionOffsWithResult(&SegArg, 2, UInt7, pEvalResult);
  561.         if (!pEvalResult->OK)
  562.           return 0;
  563.         HasSeg = True;
  564.         IsDirect = True;
  565.       }
  566.     }
  567.   }
  568.  
  569.   /* If we know it's direct, right away limit to the correct address range.  Otherwise, it might
  570.      be immediate up to 32 bits: */
  571.  
  572.   if (IsDirect)
  573.     ThisIntType = (IsIO || HasSeg) ? UInt16 : MemIntType;
  574.   else
  575.     ThisIntType = Int32;
  576.   Result = EvalStrIntExpressionWithResult(&CopyComp, ThisIntType, pEvalResult) + Disp;
  577.  
  578.   /* For AMD syntax, treat as direct if no untyped constant */
  579.  
  580.   if (AMDSyntax && !IsDirect && pEvalResult->AddrSpaceMask)
  581.     IsDirect = True;
  582.  
  583.   /* for forwards, truncate to allowed range */
  584.  
  585.   if (IsDirect)
  586.     ThisIntType = (IsIO || HasSeg) ? UInt16 : MemIntType;
  587.   else
  588.     ThisIntType = GetImmIntType(OpSize);
  589.   if (mFirstPassUnknown(pEvalResult->Flags))
  590.     Result &= IntTypeDefs[(int)ThisIntType].Mask;
  591.  
  592.   if (IsDirect)
  593.   {
  594.     Result |= (SegNum << 16);
  595.     if (pEvalResult->OK
  596.      && !mFirstPassUnknownOrQuestionable(pEvalResult->Flags)
  597.      && *pForceShort
  598.      && (Result & 0x00ff00ul))
  599.     {
  600.       WrStrErrorPos(ErrNum_NoShortAddr, pArg);
  601.       pEvalResult->OK = False;
  602.     }
  603.   }
  604.   if (pIsDirect)
  605.     *pIsDirect = IsDirect;
  606.   return Result;
  607. }
  608.  
  609. /*!------------------------------------------------------------------------
  610.  * \fn     FillAbsAddr(tAdrVals *pAdrVals, LongWord Address, Boolean IsDirect, Boolean IsIO, Boolean ForceShort, Boolean *pIsDirect)
  611.  * \brief  pack absolute addess into instruction extension word(s)
  612.  * \param  pAdrVals destination buffer
  613.  * \param  Address address to pack
  614.  * \param  IsDirect force treatment as direct address mode
  615.  * \param  IsIO I/O (16b) or memory (23/16b) address?
  616.  * \param  ForceShort force short encoding
  617.  * \param  pIsDirect classified as direct addressing?
  618.  * ------------------------------------------------------------------------ */
  619.  
  620. static void FillAbsAddr(tAdrVals *pAdrVals, LongWord Address, Boolean IsIO, Boolean ForceShort)
  621. {
  622.   Word Offset = Address & 0xffff;
  623.  
  624.   if (Segmented() && !IsIO)
  625.   {
  626.     pAdrVals->Vals[pAdrVals->Cnt++] = (Address >> 8) & 0x7f00;
  627.     if ((Offset <= 0xff) && ForceShort)
  628.       pAdrVals->Vals[pAdrVals->Cnt - 1] |= Offset;
  629.     else
  630.     {
  631.       pAdrVals->Vals[pAdrVals->Cnt - 1] |= 0x8000;
  632.       pAdrVals->Vals[pAdrVals->Cnt++] = Offset;
  633.     }
  634.   }
  635.   else
  636.     pAdrVals->Vals[pAdrVals->Cnt++] = Offset;
  637. }
  638.  
  639. /*!------------------------------------------------------------------------
  640.  * \fn     FillImmVal(tAdrVals *pAdrVals, LongWord Value, tSymbolSize OpSize)
  641.  * \brief  fill address values from immediate value
  642.  * \param  pAdrVals dest buffer
  643.  * \param  Value value to fill in
  644.  * \param  OpSize used operand size
  645.  * ------------------------------------------------------------------------ */
  646.  
  647. static void FillImmVal(tAdrVals *pAdrVals, LongWord Value, tSymbolSize OpSize)
  648. {
  649.   switch ((int)OpSize)
  650.   {
  651.     case eSymbolSize3Bit:
  652.       pAdrVals->Val = Value & 7;
  653.       break;
  654.     case eSymbolSize4Bit:
  655.       pAdrVals->Val = Value & 15;
  656.       break;
  657.     case eSymbolSize8Bit:
  658.       pAdrVals->Vals[pAdrVals->Cnt++] = (Value & 0xff) | ((Value & 0xff) << 8);
  659.       break;
  660.     case eSymbolSize16Bit:
  661.       pAdrVals->Vals[pAdrVals->Cnt++] = Value & 0xffff;
  662.       break;
  663.     case eSymbolSize32Bit:
  664.       pAdrVals->Vals[pAdrVals->Cnt++] = (Value >> 16) & 0xffff;
  665.       pAdrVals->Vals[pAdrVals->Cnt++] = Value & 0xffff;
  666.       break;
  667.     default:
  668.       break;
  669.   }
  670. }
  671.  
  672. /*!------------------------------------------------------------------------
  673.  * \fn     DecodeAddrPart(const tStrComp *pArg, LongInt Disp, tAdrVals *pAdrVals, Boolean IsDirect, Boolean IsIO, Boolean *pIsDirect)
  674.  * \brief  decode address part, for direct/immediate or indexed mode
  675.  * \param  pArg source argument
  676.  * \param  Disp displacement to add to value
  677.  * \param  pAdrVals binary coding of addressing mode
  678.  * \param  IsDirect force treatment as direct address mode
  679.  * \param  IsIO I/O space instead of memory space
  680.  * \param  pIsDirect classified as direct addressing?
  681.  * \return True if success
  682.  * ------------------------------------------------------------------------ */
  683.  
  684. static Boolean DecodeAddrPart(const tStrComp *pArg, LongInt Disp, tAdrVals *pAdrVals, Boolean IsDirect, Boolean IsIO, Boolean *pIsDirect)
  685. {
  686.   LongWord Address;
  687.   tEvalResult EvalResult;
  688.   Boolean ForceLong;
  689.  
  690.   Address = DecodeAddrPartNum(pArg, Disp, &EvalResult, IsDirect, IsIO, &ForceLong, pIsDirect);
  691.   if (EvalResult.OK)
  692.   {
  693.     ChkSpace(IsIO ? SegIO : SegCode, EvalResult.AddrSpaceMask);
  694.     if (!pIsDirect || *pIsDirect)
  695.       FillAbsAddr(pAdrVals, Address, IsIO, ForceLong);
  696.     else
  697.       FillImmVal(pAdrVals, Address, OpSize);
  698.     return True;
  699.   }
  700.   else
  701.     return False;
  702. }
  703.  
  704. /*!------------------------------------------------------------------------
  705.  * \fn     DecodeAdr(const tStrComp *pArg, unsigned ModeMask, tAdrVals *pAdrVals)
  706.  * \brief  decode address expression
  707.  * \param  pArg source argument
  708.  * \param  ModeMask bit mask of allowed addressing modes
  709.  * \param  pAdrVals binary coding of addressing mode
  710.  * \return decoded mode
  711.  * ------------------------------------------------------------------------ */
  712.  
  713. /* This is necessary to find the split position when a short address is used as
  714.    base, i.e. |addr|(rn).  | is also the OR operator, and I don't want to get
  715.    false positives on other targets on stuff like (...)|(...): */
  716.  
  717. static int ShortQualifier(const char *pArg, int NextNonBlankPos, int SplitPos)
  718. {
  719.   int FirstNonBlankPos;
  720.  
  721.   for (FirstNonBlankPos = 0; FirstNonBlankPos < NextNonBlankPos; FirstNonBlankPos++)
  722.     if (!as_isspace(pArg[FirstNonBlankPos]))
  723.       break;
  724.   return ((FirstNonBlankPos < NextNonBlankPos) && (pArg[FirstNonBlankPos] == '|') && (pArg[NextNonBlankPos] == '|')) ? SplitPos : -1;
  725. }
  726.  
  727. static tAdrMode DecodeAdr(const tStrComp *pArg, unsigned ModeMask, tAdrVals *pAdrVals)
  728. {
  729.   tSymbolSize ArgSize;
  730.   int ArgLen, SplitPos, z;
  731.   Boolean IsIO = !!(ModeMask & MModIO);
  732.   tChkRegSize ChkRegSize_Addr = IsIO ? ChkRegSize_IOAddr : ChkRegSize_MemAddr, ChkRegSizeForIOIndir;
  733.   Boolean IsDirect;
  734.  
  735.   ClearAdrVals(pAdrVals);
  736.  
  737.   /* immediate */
  738.  
  739.   if (*pArg->str.p_str == '#')
  740.   {
  741.     LongWord Result;
  742.     Boolean OK;
  743.  
  744.     if (ImmOpSize == eSymbolSizeUnknown)
  745.       ImmOpSize = OpSize;
  746.     switch (ImmOpSize)
  747.     {
  748.       case eSymbolSize3Bit:
  749.         pAdrVals->Val = EvalStrIntExpressionOffs(pArg, 1, UInt3, &OK);
  750.         break;
  751.       case eSymbolSize4Bit:
  752.         pAdrVals->Val = EvalStrIntExpressionOffs(pArg, 1, UInt4, &OK);
  753.         break;
  754.       case eSymbolSize8Bit:
  755.         Result = EvalStrIntExpressionOffs(pArg, 1, Int8, &OK);
  756.         if (OK)
  757.           pAdrVals->Vals[pAdrVals->Cnt++] = (Result & 0xff) | ((Result & 0xff) << 8);
  758.         break;
  759.       case eSymbolSize16Bit:
  760.         Result = EvalStrIntExpressionOffs(pArg, 1, Int16, &OK);
  761.         if (OK)
  762.           pAdrVals->Vals[pAdrVals->Cnt++] = Result & 0xffff;
  763.         break;
  764.       case eSymbolSize32Bit:
  765.         Result = EvalStrIntExpressionOffs(pArg, 1, Int32, &OK);
  766.         if (OK)
  767.         {
  768.           pAdrVals->Vals[pAdrVals->Cnt++] = (Result >> 16) & 0xffff;
  769.           pAdrVals->Vals[pAdrVals->Cnt++] = Result & 0xffff;
  770.         }
  771.         break;
  772.       default:
  773.         WrStrErrorPos(ErrNum_UndefOpSizes, pArg);
  774.         return pAdrVals->Mode;
  775.     }
  776.     if (OK)
  777.     {
  778.       /* Immediate: is the same coding as indirect, however with register field = 0.
  779.          This why register 0 is not allowed for indirect mode.
  780.          As an exception, immediate value is placed in pAdrVals->Val for bit number: */
  781.  
  782.       pAdrVals->Mode = eModImm;
  783.       if (OpSize == eSymbolSizeUnknown)
  784.         OpSize = (tSymbolSize)ImmOpSize;
  785.     }
  786.     goto chk;
  787.   }
  788.  
  789.   /* Register (R): For AMD syntax, Rn is equivalent to Rn^ resp. @Rn, if I/O ports
  790.      are addressed indirectly: */
  791.  
  792.   ChkRegSizeForIOIndir = (AMDSyntax && !(ModeMask & MModReg) && (ModeMask & MModIReg) && IsIO) ? ChkRegSize_Addr : NULL;
  793.   switch (DecodeReg(pArg, &pAdrVals->Val, &ArgSize, ChkRegSizeForIOIndir, False))
  794.   {
  795.     case eRegAbort:
  796.       return pAdrVals->Mode;
  797.     case eIsReg:
  798.     {
  799.       if (ChkRegSizeForIOIndir)
  800.         pAdrVals->Mode = eModIReg;
  801.       else
  802.       {
  803.         if (!SetOpSize(ArgSize, pArg))
  804.           return pAdrVals->Mode;
  805.         pAdrVals->Mode = eModReg;
  806.       }
  807.       goto chk;
  808.     }
  809.     default:
  810.       break;
  811.   }
  812.  
  813.   /* control register */
  814.  
  815.   for (z = 0; z < CtlRegCnt; z++)
  816.     if (!as_strcasecmp(pArg->str.p_str, CtlRegs[z].pName))
  817.     {
  818.       if (!(CtlRegs[z].Flags & (Segmented() ? eSegMode : eNonSegMode)))
  819.       {
  820.         WrStrErrorPos(ErrNum_InvCtrlReg, pArg);
  821.         return pAdrVals->Mode;
  822.       }
  823.       if (!SetOpSize(CtlRegs[z].Size, pArg))
  824.         return pAdrVals->Mode;
  825.       if (!CheckSup(!!(CtlRegs[z].Flags & ePrivileged)))
  826.         return pAdrVals->Mode;
  827.       pAdrVals->Val = CtlRegs[z].Code;
  828.       pAdrVals->Mode = eModCtl;
  829.       goto chk;
  830.     }
  831.  
  832.   /* Register indirect (IR): */
  833.  
  834.   if (*pArg->str.p_str == '@')
  835.   {
  836.     tStrComp RegComp;
  837.  
  838.     StrCompRefRight(&RegComp, pArg, 1);
  839.     if (eIsReg == DecodeReg(&RegComp, &pAdrVals->Val, &ArgSize, ChkRegSize_Addr, True))
  840.     {
  841.       if (!pAdrVals->Val) WrStrErrorPos(ErrNum_InvAddrMode, &RegComp);
  842.       else
  843.         pAdrVals->Mode = eModIReg;
  844.     }
  845.     goto chk;
  846.   }
  847.   if (AMDSyntax
  848.    && ((ArgLen = strlen(pArg->str.p_str))> 1)
  849.    && (pArg->str.p_str[ArgLen - 1] == '^'))
  850.   {
  851.     String Reg;
  852.     tStrComp RegComp;
  853.  
  854.     StrCompMkTemp(&RegComp, Reg, sizeof(Reg));
  855.     StrCompCopySub(&RegComp, pArg, 0, ArgLen - 1);
  856.     switch (DecodeReg(&RegComp, &pAdrVals->Val, &ArgSize, ChkRegSize_Addr, False))
  857.     {
  858.       case eRegAbort:
  859.         return pAdrVals->Mode;
  860.       case eIsReg:
  861.         if (!pAdrVals->Val) WrStrErrorPos(ErrNum_InvAddrMode, &RegComp);
  862.         else
  863.           pAdrVals->Mode = eModIReg;
  864.         goto chk;
  865.       default:
  866.         break;
  867.     }
  868.   }
  869.  
  870.   /* Indexed, base... */
  871.  
  872.   SplitPos = FindDispBaseSplitWithQualifier(pArg->str.p_str, &ArgLen, ShortQualifier, "()");
  873.   if (SplitPos > 0)
  874.   {
  875.     String OutStr, InStr;
  876.     tStrComp OutArg, InArg;
  877.  
  878.     /* copy out base + index components */
  879.  
  880.     StrCompMkTemp(&OutArg, OutStr, sizeof(OutStr));
  881.     StrCompMkTemp(&InArg, InStr, sizeof(InStr));
  882.     StrCompCopySub(&OutArg, pArg, 0, SplitPos);
  883.     KillPostBlanksStrComp(&OutArg);
  884.     StrCompCopySub(&InArg, pArg, SplitPos + 1, ArgLen - SplitPos - 2);
  885.     switch (DecodeReg(&OutArg, &pAdrVals->Val, &ArgSize, ChkRegSize_Addr, False))
  886.     {
  887.       case eIsReg: /* [R]Rx(...) */
  888.         if (!pAdrVals->Val) WrStrErrorPos(ErrNum_InvAddrMode, &OutArg);
  889.         else if (*InArg.str.p_str == '#')
  890.         {
  891.           Boolean OK;
  892.  
  893.           pAdrVals->Vals[pAdrVals->Cnt++] = EvalStrIntExpressionOffs(&InArg, 1, Int16, &OK);
  894.           if (OK)
  895.             pAdrVals->Mode = eModBaseAddress;
  896.         }
  897.         else if (DecodeReg(&InArg, &pAdrVals->Vals[pAdrVals->Cnt], &ArgSize, ChkRegSize_Idx, True) == eIsReg)
  898.         {
  899.           pAdrVals->Vals[pAdrVals->Cnt] <<= 8;
  900.           pAdrVals->Cnt++;
  901.           pAdrVals->Mode = eModBaseIndexed;
  902.         }
  903.         goto chk;
  904.       case eIsNoReg: /* abs(...) */
  905.       {
  906.         switch (DecodeReg(&InArg, &pAdrVals->Val, &ArgSize, ChkRegSize_Idx, False))
  907.         {
  908.           case eIsReg: /* abs(Rx) */
  909.             if (DecodeAddrPart(&OutArg, 0, pAdrVals, True, IsIO, NULL))
  910.               pAdrVals->Mode = eModIndexed;
  911.             break;
  912.           case eIsNoReg: /* abs/imm(delta) -> direct/imm*/
  913.           {
  914.             Boolean OK;
  915.             LongInt Disp = EvalStrIntExpression(&InArg, Int16, &OK);
  916.  
  917.             if (OK && DecodeAddrPart(&OutArg, Disp, pAdrVals, !AMDSyntax || !(ModeMask & MModImm), IsIO, &IsDirect))
  918.               goto DirectOrImmediate;
  919.             break;
  920.           }
  921.           default:
  922.             return pAdrVals->Mode;
  923.         }
  924.         goto chk;
  925.       }
  926.       case eRegAbort:
  927.         return pAdrVals->Mode;
  928.     }
  929.   }
  930.  
  931.   /* Absolute: is the same coding as indexed, however with index register field = 0.
  932.      This is why register 0 is not allowed for indexed mode. */
  933.  
  934.   if (DecodeAddrPart(pArg, 0, pAdrVals, !AMDSyntax || !(ModeMask & MModImm), IsIO, &IsDirect))
  935.   {
  936. DirectOrImmediate:
  937.     if (IsDirect)
  938.     {
  939.       pAdrVals->Val = 0;
  940.       pAdrVals->Mode = eModDirect;
  941.     }
  942.     else
  943.       pAdrVals->Mode = eModImm;
  944.   }
  945.  
  946. chk:
  947.   if ((pAdrVals->Mode != eModNone) & !((ModeMask >> pAdrVals->Mode) & 1))
  948.   {
  949.     WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  950.     ClearAdrVals(pAdrVals);
  951.   }
  952.   return pAdrVals->Mode;
  953. }
  954.  
  955. /*--------------------------------------------------------------------------*/
  956. /* Bit Symbol Handling */
  957.  
  958. /*
  959.  * Compact representation of bits in symbol table:
  960.  * bits 0...2/3: bit position
  961.  * bits 3/4...25/26: address in memory space (7+16 bits)
  962.  * bit  28: operand size (0/1 for 8/16 bits)
  963.  * bit  29: force short address in segmented mode
  964.  */
  965.  
  966. /*!------------------------------------------------------------------------
  967.  * \fn     AssembleBitSymbol(Byte BitPos, tSymbolSize OpSize, LongWord Address, Boolean ForceShort)
  968.  * \brief  build the compact internal representation of a bit symbol
  969.  * \param  BitPos bit position in word
  970.  * \param  OpSize operand size (8/16)
  971.  * \param  Address memory address
  972.  * \param  ForceShort force short address in segmented mode
  973.  * \return compact representation
  974.  * ------------------------------------------------------------------------ */
  975.  
  976. static LongWord AssembleBitSymbol(Byte BitPos, tSymbolSize OpSize, LongWord Address, Boolean ForceShort)
  977. {
  978.   LongWord CodeOpSize = (OpSize == eSymbolSize16Bit) ? 1 : 0;
  979.   int AddrShift = CodeOpSize + 3;
  980.  
  981.   return BitPos
  982.        | ((Address & 0x7fffff) << AddrShift)
  983.        | (CodeOpSize << 28)
  984.        | ((!!ForceShort) << 29);
  985. }
  986.  
  987. /*!------------------------------------------------------------------------
  988.  * \fn     EvalBitPosition(const char *pBitArg, Boolean *pOK, ShortInt OpSize)
  989.  * \brief  evaluate constant bit position, with bit range depending on operand size
  990.  * \param  pBitArg bit position argument
  991.  * \param  pOK returns True if OK
  992.  * \param  OpSize operand size (0,1,2 -> 8,16,32 bits)
  993.  * \return bit position as number
  994.  * ------------------------------------------------------------------------ */
  995.  
  996. static Byte EvalBitPosition(const tStrComp *pBitArg, Boolean *pOK, tSymbolSize OpSize)
  997. {
  998.   IntType Type;
  999.  
  1000.   switch (OpSize)
  1001.   {
  1002.     case eSymbolSize8Bit:
  1003.       Type = UInt3;
  1004.       goto common;
  1005.     case eSymbolSize16Bit:
  1006.       Type = UInt4;
  1007.       goto common;
  1008.     default:
  1009.       WrStrErrorPos(ErrNum_InvOpSize, pBitArg);
  1010.       *pOK = False;
  1011.       return 0;
  1012.     common:
  1013.       return EvalStrIntExpressionOffs(pBitArg, !!(*pBitArg->str.p_str == '#'), Type, pOK);
  1014.   }
  1015. }
  1016.  
  1017. /*!------------------------------------------------------------------------
  1018.  * \fn     DecodeBitArg2(LongWord *pResult, const tStrComp *pMemArg, const tStrComp *pBitArg, tSymbolSize OpSize)
  1019.  * \brief  encode a bit symbol, address & bit position separated
  1020.  * \param  pResult resulting encoded bit
  1021.  * \param  pMemArg register argument
  1022.  * \param  pBitArg bit argument
  1023.  * \param  OpSize register size (0/1 = 8/16 bit)
  1024.  * \return True if success
  1025.  * ------------------------------------------------------------------------ */
  1026.  
  1027. static Boolean DecodeBitArg2(LongWord *pResult, const tStrComp *pMemArg, const tStrComp *pBitArg, tSymbolSize OpSize)
  1028. {
  1029.   tEvalResult EvalResult;
  1030.   LongWord Addr;
  1031.   Byte BitPos;
  1032.   Boolean ForceShort;
  1033.  
  1034.   BitPos = EvalBitPosition(pBitArg, &EvalResult.OK, OpSize);
  1035.   if (!EvalResult.OK)
  1036.     return False;
  1037.  
  1038.   Addr = DecodeAddrPartNum(pMemArg, 0, &EvalResult, True, False, &ForceShort, NULL);
  1039.   if (!EvalResult.OK)
  1040.     return False;
  1041.  
  1042.   *pResult = AssembleBitSymbol(BitPos, OpSize, Addr, ForceShort);
  1043.  
  1044.   return True;
  1045. }
  1046.  
  1047. /*!------------------------------------------------------------------------
  1048.  * \fn     DecodeBitArg(LongWord *pResult, int Start, int Stop, tSymbolSize OpSize)
  1049.  * \brief  encode a bit symbol from instruction argument(s)
  1050.  * \param  pResult resulting encoded bit
  1051.  * \param  Start first argument
  1052.  * \param  Stop last argument
  1053.  * \param  OpSize register size (0/1 = 8/16 bit)
  1054.  * \return True if success
  1055.  * ------------------------------------------------------------------------ */
  1056.  
  1057. static Boolean DecodeBitArg(LongWord *pResult, int Start, int Stop, tSymbolSize OpSize)
  1058. {
  1059.   *pResult = 0;
  1060.  
  1061.   /* Just one argument -> parse as bit argument */
  1062.  
  1063.   if (Start == Stop)
  1064.   {
  1065.     tEvalResult EvalResult;
  1066.  
  1067.     *pResult = EvalStrIntExpressionWithResult(&ArgStr[Start], UInt32, &EvalResult);
  1068.     if (EvalResult.OK)
  1069.       ChkSpace(SegBData, EvalResult.AddrSpaceMask);
  1070.     return EvalResult.OK;
  1071.   }
  1072.  
  1073.   /* register & bit position are given as separate arguments */
  1074.  
  1075.   else if (Stop == Start + 1)
  1076.     return DecodeBitArg2(pResult, &ArgStr[Start], &ArgStr[Stop], OpSize);
  1077.  
  1078.   /* other # of arguments not allowed */
  1079.  
  1080.   else
  1081.   {
  1082.     WrError(ErrNum_WrongArgCnt);
  1083.     return False;
  1084.   }
  1085. }
  1086.  
  1087. /*!------------------------------------------------------------------------
  1088.  * \fn     DissectBitSymbol(LongWord BitSymbol, LongWord *pAddress, Byte *pBitPos, tSymbolSize *pOpSize, Boolean *pForceShort)
  1089.  * \brief  transform compact represenation of bit symbol into components
  1090.  * \param  BitSymbol compact storage
  1091.  * \param  pAddress (I/O) register address
  1092.  * \param  pBitPos (start) bit position
  1093.  * \param  pOpSize returns register size (0/1 for 8/16 bits)
  1094.  * \param  pForceShort returns force of short address in segmented mode
  1095.  * \return constant True
  1096.  * ------------------------------------------------------------------------ */
  1097.  
  1098. static Boolean DissectBitSymbol(LongWord BitSymbol, LongWord *pAddress, Byte *pBitPos, tSymbolSize *pOpSize, Boolean *pForceShort)
  1099. {
  1100.   *pForceShort = ((BitSymbol >> 29) & 1);
  1101.   *pOpSize = (tSymbolSize)((BitSymbol >> 28) & 1);
  1102.   switch (*pOpSize)
  1103.   {
  1104.     case eSymbolSize8Bit:
  1105.       *pAddress = (BitSymbol >> 3) & 0x7ffffful;
  1106.       *pBitPos = BitSymbol & 7;
  1107.       break;
  1108.     case eSymbolSize16Bit:
  1109.       *pAddress = (BitSymbol >> 4) & 0x7ffffful;
  1110.       *pBitPos = BitSymbol & 15;
  1111.       break;
  1112.     default:
  1113.       break;
  1114.   }
  1115.   return True;
  1116. }
  1117.  
  1118. /*!------------------------------------------------------------------------
  1119.  * \fn     DissectBit_Z8000(char *pDest, size_t DestSize, LargeWord Inp)
  1120.  * \brief  dissect compact storage of bit into readable form for listing
  1121.  * \param  pDest destination for ASCII representation
  1122.  * \param  DestSize destination buffer size
  1123.  * \param  Inp compact storage
  1124.  * ------------------------------------------------------------------------ */
  1125.  
  1126. static void DissectBit_Z8000(char *pDest, size_t DestSize, LargeWord Inp)
  1127. {
  1128.   Byte BitPos;
  1129.   LongWord Address;
  1130.   tSymbolSize OpSize;
  1131.   Boolean ForceShort;
  1132.   char Attribute;
  1133.  
  1134.   DissectBitSymbol(Inp, &Address, &BitPos, &OpSize, &ForceShort);
  1135.   Attribute = "bw"[OpSize];
  1136.   if (HexStartCharacter == 'A')
  1137.     Attribute = as_toupper(Attribute);
  1138.   as_snprintf(pDest, DestSize, "%s%~.*u%s%s(%c).%u",
  1139.               ForceShort ? "|" : "",
  1140.               ListRadixBase, (unsigned)Address, GetIntConstIntelSuffix(ListRadixBase),
  1141.               ForceShort ? "|" : "",
  1142.               Attribute, (unsigned)BitPos);
  1143. }
  1144.  
  1145. /*!------------------------------------------------------------------------
  1146.  * \fn     ExpandZ8000Bit(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
  1147.  * \brief  expands bit definition when a structure is instantiated
  1148.  * \param  pVarName desired symbol name
  1149.  * \param  pStructElem element definition
  1150.  * \param  Base base address of instantiated structure
  1151.  * ------------------------------------------------------------------------ */
  1152.  
  1153. static void ExpandZ8000Bit(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
  1154. {
  1155.   LongWord Address = Base + pStructElem->Offset;
  1156.  
  1157.   if (pInnermostNamedStruct)
  1158.   {
  1159.     PStructElem pElem = CloneStructElem(pVarName, pStructElem);
  1160.  
  1161.     if (!pElem)
  1162.       return;
  1163.     pElem->Offset = Address;
  1164.     AddStructElem(pInnermostNamedStruct->StructRec, pElem);
  1165.   }
  1166.   else
  1167.   {
  1168.     tSymbolSize OpSize = (pStructElem->OpSize == eSymbolSizeUnknown) ? eSymbolSize8Bit : pStructElem->OpSize;
  1169.  
  1170.     if (!ChkRange(Address, 0, 0x7fffff)
  1171.      || !ChkRange(pStructElem->BitPos, 0, (8 << OpSize) - 1))
  1172.       return;
  1173.  
  1174.     PushLocHandle(-1);
  1175.     EnterIntSymbol(pVarName, AssembleBitSymbol(pStructElem->BitPos, OpSize, Address, False), SegBData, False);
  1176.     PopLocHandle();
  1177.     /* TODO: MakeUseList? */
  1178.   }
  1179. }
  1180.  
  1181. /*!------------------------------------------------------------------------
  1182.  * \fn     SetOpSizeFromCode(Word Code)
  1183.  * \brief  set operand size of instruction from insn name
  1184.  * \param  Code contains size in MSB
  1185.  * ------------------------------------------------------------------------ */
  1186.  
  1187. static Boolean SetOpSizeFromCode(Word Code)
  1188. {
  1189.   Byte Size = Hi(Code);
  1190.  
  1191.   return SetOpSize((Size == 0xff) ? eSymbolSizeUnknown : (tSymbolSize)Size, &OpPart);
  1192. }
  1193.  
  1194. /*!------------------------------------------------------------------------
  1195.  * \fn     AppendCode(Word Code)
  1196.  * \brief  append instruction word
  1197.  * \param  pVals code word to append
  1198.  * ------------------------------------------------------------------------ */
  1199.  
  1200. static void AppendCode(Word Code)
  1201. {
  1202.   WAsmCode[CodeLen >> 1] = Code;
  1203.   CodeLen += 2;
  1204. }
  1205.  
  1206. /*!------------------------------------------------------------------------
  1207.  * \fn     AppendAdrVals(const tAdrVals *pVals)
  1208.  * \brief  append address argument(s)
  1209.  * \param  pVals values to append
  1210.  * ------------------------------------------------------------------------ */
  1211.  
  1212. static void AppendAdrVals(const tAdrVals *pVals)
  1213. {
  1214.   memcpy(&WAsmCode[CodeLen >> 1], pVals->Vals, pVals->Cnt << 1);
  1215.   CodeLen += pVals->Cnt << 1;
  1216. }
  1217.  
  1218. /*!------------------------------------------------------------------------
  1219.  * \fn     DecodeCondition(const tStrComp *pArg, Word *pCondition)
  1220.  * \brief  decode condition argument
  1221.  * \param  pArg source argument (NULL for non-present condition)
  1222.  * \param  pCondition result buffer
  1223.  * \return True if found
  1224.  * ------------------------------------------------------------------------ */
  1225.  
  1226. static Boolean DecodeCondition(const tStrComp *pArg, Word *pCondition)
  1227. {
  1228.   int z;
  1229.  
  1230.   for (z = 0; Conditions[z].pName; z++)
  1231.     if (!as_strcasecmp(pArg ? pArg->str.p_str : "", Conditions[z].pName))
  1232.     {
  1233.       *pCondition = Conditions[z].Code;
  1234.       return True;
  1235.     }
  1236.   WrStrErrorPos(ErrNum_UndefCond, pArg);
  1237.   return False;
  1238. }
  1239.  
  1240. /*!------------------------------------------------------------------------
  1241.  * \fn     DecodeImm1_16(const tStrComp *pArg, tEvalResult *pEvalResult)
  1242.  * \brief  decode immediate argument from 1..16 and return as 0..15
  1243.  * \param  pArg source argument
  1244.  * \param  pEvalResult evaluation result
  1245.  * \return value
  1246.  * ------------------------------------------------------------------------ */
  1247.  
  1248. static Word DecodeImm1_16(const tStrComp *pArg, tEvalResult *pEvalResult)
  1249. {
  1250.   Word Result;
  1251.  
  1252.   Result = EvalStrIntExpressionOffsWithResult(pArg, !!(*pArg->str.p_str == '#'), UInt5, pEvalResult);
  1253.   if (pEvalResult->OK)
  1254.   {
  1255.     if (mFirstPassUnknownOrQuestionable(pEvalResult->Flags))
  1256.       Result = 1;
  1257.     else
  1258.       pEvalResult->OK = ChkRange(Result, 1, 16);
  1259.     Result--;
  1260.   }
  1261.   return Result;
  1262. }
  1263.  
  1264. /*--------------------------------------------------------------------------*/
  1265. /* Instruction Decoders */
  1266.  
  1267. /*!------------------------------------------------------------------------
  1268.  * \fn     DecodeFixed(Word Index)
  1269.  * \brief  decode instruction without arguments
  1270.  * \param  Index machine code of instruction
  1271.  * ------------------------------------------------------------------------ */
  1272.  
  1273. static void DecodeFixed(Word Index)
  1274. {
  1275.   const FixedOrder *pOrder = FixedOrders + Index;
  1276.  
  1277.   if (ChkArgCnt(0, 0)
  1278.    && CheckSup(pOrder->Privileged))
  1279.   {
  1280.     CodeLen = 2;
  1281.     WAsmCode[0] = pOrder->Code;
  1282.   }
  1283. }
  1284.  
  1285. /*!------------------------------------------------------------------------
  1286.  * \fn     DecodeLD(Word Code)
  1287.  * \brief  decode LD/LDB/LDL instruction
  1288.  * \param  Code instruction type
  1289.  * ------------------------------------------------------------------------ */
  1290.  
  1291. static void DecodeLD(Word Code)
  1292. {
  1293.   tAdrVals DestAdrVals;
  1294.  
  1295.   if (!SetOpSizeFromCode(Code)
  1296.    || !ChkArgCnt(2, 2))
  1297.     return;
  1298.  
  1299.   switch (DecodeAdr(&ArgStr[1], MModNoImm, &DestAdrVals))
  1300.   {
  1301.     case eModReg:
  1302.     {
  1303.       tAdrVals SrcAdrVals;
  1304.  
  1305.       switch (DecodeAdr(&ArgStr[2], MModAll, &SrcAdrVals))
  1306.       {
  1307.         case eModReg:
  1308.           AppendCode(((OpSize == eSymbolSize32Bit) ? 0x9400 : (0xa000 | (OpSize << 8)))
  1309.                    | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1310.           break;
  1311.         case eModIReg:
  1312.           AppendCode(((OpSize == eSymbolSize32Bit) ? 0x1400 : (0x2000 | (OpSize << 8)))
  1313.                    | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1314.           break;
  1315.         case eModDirect:
  1316.         case eModIndexed:
  1317.           AppendCode(((OpSize == eSymbolSize32Bit) ? 0x5400 : (0x6000 | (OpSize << 8)))
  1318.                    | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1319.           AppendAdrVals(&SrcAdrVals);
  1320.           break;
  1321.         case eModBaseAddress:
  1322.           AppendCode(((OpSize == eSymbolSize32Bit) ? 0x3500 : (0x3000 | (OpSize << 8)))
  1323.                    | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1324.           AppendAdrVals(&SrcAdrVals);
  1325.           break;
  1326.         case eModBaseIndexed:
  1327.           AppendCode(((OpSize == eSymbolSize32Bit) ? 0x7500 : (0x7000 | (OpSize << 8)))
  1328.                    | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1329.           AppendAdrVals(&SrcAdrVals);
  1330.           break;
  1331.         case eModImm:
  1332.           if (OpSize == eSymbolSize8Bit)
  1333.             AppendCode(0xc000 | (DestAdrVals.Val << 8) | (SrcAdrVals.Vals[0] & 0xff));
  1334. #if OPT_LD_LDK
  1335.           else if ((OpSize == eSymbolSize16Bit) && (SrcAdrVals.Vals[0] < 16))
  1336.             AppendCode(0xbd00 | (DestAdrVals.Val << 4) | (SrcAdrVals.Vals[0] & 0x0f));
  1337. #endif
  1338.           else
  1339.           {
  1340.             AppendCode(((OpSize == eSymbolSize32Bit) ? 0x1400 : (0x2000 | (OpSize << 8)))
  1341.                      | DestAdrVals.Val);
  1342.             AppendAdrVals(&SrcAdrVals);
  1343.           }
  1344.           break;
  1345.         default:
  1346.           break;
  1347.       }
  1348.       break;
  1349.     }
  1350.     case eModIReg:
  1351.     {
  1352.       tAdrVals SrcAdrVals;
  1353.  
  1354.       ImmOpSize = (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize;
  1355.       switch (DecodeAdr(&ArgStr[2], MModReg | MModImm, &SrcAdrVals))
  1356.       {
  1357.         case eModReg:
  1358.           AppendCode(((OpSize == eSymbolSize32Bit) ? 0x1d00 : (0x2e00 | (OpSize << 8)))
  1359.                    | (DestAdrVals.Val << 4) | SrcAdrVals.Val);
  1360.           break;
  1361.         case eModImm:
  1362.           if (OpSize > eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &OpPart);
  1363.           else
  1364.           {
  1365.             AppendCode(0x0c05 | (OpSize << 8) | (DestAdrVals.Val << 4));
  1366.             AppendAdrVals(&SrcAdrVals);
  1367.           }
  1368.           break;
  1369.         default:
  1370.           break;
  1371.       }
  1372.       break;
  1373.     }
  1374.     case eModDirect:
  1375.     case eModIndexed:
  1376.     {
  1377.       tAdrVals SrcAdrVals;
  1378.  
  1379.       ImmOpSize = (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize;
  1380.       switch (DecodeAdr(&ArgStr[2], MModReg | MModImm, &SrcAdrVals))
  1381.       {
  1382.         case eModReg:
  1383.           AppendCode(((OpSize == eSymbolSize32Bit) ? 0x5d00 : (0x6e00 | (OpSize << 8)))
  1384.                    | (DestAdrVals.Val << 4) | SrcAdrVals.Val);
  1385.           AppendAdrVals(&DestAdrVals);
  1386.           break;
  1387.         case eModImm:
  1388.           if (OpSize > eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &OpPart);
  1389.           else
  1390.           {
  1391.             AppendCode(0x4c05 | (OpSize << 8) | (DestAdrVals.Val << 4));
  1392.             AppendAdrVals(&DestAdrVals);
  1393.             AppendAdrVals(&SrcAdrVals);
  1394.           }
  1395.           break;
  1396.         default:
  1397.           break;
  1398.       }
  1399.       break;
  1400.     }
  1401.     case eModBaseAddress:
  1402.     {
  1403.       tAdrVals SrcAdrVals;
  1404.  
  1405.       if (DecodeAdr(&ArgStr[2], MModReg, &SrcAdrVals) == eModReg)
  1406.       {
  1407.         AppendCode(((OpSize == eSymbolSize32Bit) ? 0x3700 : (0x3200 | (OpSize << 8)))
  1408.                  | (DestAdrVals.Val << 4) | SrcAdrVals.Val);
  1409.         AppendAdrVals(&DestAdrVals);
  1410.       }
  1411.       break;
  1412.     }
  1413.     case eModBaseIndexed:
  1414.     {
  1415.       tAdrVals SrcAdrVals;
  1416.  
  1417.       if (DecodeAdr(&ArgStr[2], MModReg, &SrcAdrVals) == eModReg)
  1418.       {
  1419.         AppendCode(((OpSize == eSymbolSize32Bit) ? 0x7700 : (0x7200 | (OpSize << 8)))
  1420.                  | (DestAdrVals.Val << 4) | SrcAdrVals.Val);
  1421.         AppendAdrVals(&DestAdrVals);
  1422.       }
  1423.       break;
  1424.     }
  1425.     default:
  1426.       break;
  1427.   }
  1428. }
  1429.  
  1430. /*!------------------------------------------------------------------------
  1431.  * \fn     DecodeLDA(Word Code)
  1432.  * \brief  decode LDA instruction
  1433.  * ------------------------------------------------------------------------ */
  1434.  
  1435. static void DecodeLDA(Word Code)
  1436. {
  1437.   tAdrVals DestAdrVals, SrcAdrVals;
  1438.  
  1439.   UNUSED(Code);
  1440.  
  1441.   SetOpSize(AddrRegSize(), &OpPart);
  1442.   if (ChkArgCnt(2, 2)
  1443.    && DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals))
  1444.     switch (DecodeAdr(&ArgStr[2], MModDirect | MModIndexed | MModBaseAddress | MModBaseIndexed, &SrcAdrVals))
  1445.     {
  1446.       case eModDirect:
  1447.       case eModIndexed:
  1448.         AppendCode(0x7600 | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1449.         AppendAdrVals(&SrcAdrVals);
  1450.         break;
  1451.       case eModBaseAddress:
  1452.         AppendCode(0x3400 | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1453.         AppendAdrVals(&SrcAdrVals);
  1454.         break;
  1455.       case eModBaseIndexed:
  1456.         AppendCode(0x7400 | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1457.         AppendAdrVals(&SrcAdrVals);
  1458.         break;
  1459.       default:
  1460.         break;
  1461.     }
  1462. }
  1463.  
  1464. /*!------------------------------------------------------------------------
  1465.  * \fn     DecodeLDAR(Word Code)
  1466.  * \brief  decode LDAR instruction
  1467.  * ------------------------------------------------------------------------ */
  1468.  
  1469. static void DecodeLDAR(Word Code)
  1470. {
  1471.   tAdrVals DestAdrVals;
  1472.  
  1473.   SetOpSize(AddrRegSize(), &OpPart);
  1474.   if (ChkArgCnt(2, 2)
  1475.    && DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals))
  1476.   {
  1477.     tEvalResult EvalResult;
  1478.     LongWord Addr = EvalStrIntExpressionWithResult(&ArgStr[2], MemIntType, &EvalResult);
  1479.     if (EvalResult.OK)
  1480.     {
  1481.       Word Delta;
  1482.  
  1483.       if (!mFirstPassUnknownOrQuestionable(EvalResult.Flags) && (GetSegment(Addr) != GetSegment(EProgCounter())))
  1484.         WrStrErrorPos(ErrNum_InAccSegment, &ArgStr[2]);
  1485.  
  1486.       Delta = (Addr & 0xffff) - ((EProgCounter() + 4) & 0xffff);
  1487.       AppendCode(Code | DestAdrVals.Val);
  1488.       AppendCode(Delta);
  1489.     }
  1490.   }
  1491. }
  1492.  
  1493. /*!------------------------------------------------------------------------
  1494.  * \fn     DecodeLDCTL(Word Code)
  1495.  * \brief  decode LDCTL(B) instruction
  1496.  * ------------------------------------------------------------------------ */
  1497.  
  1498. static void DecodeLDCTL(Word Code)
  1499. {
  1500.   tAdrVals DestAdrVals;
  1501.  
  1502.   UNUSED(Code);
  1503.   if (SetOpSizeFromCode(Code)
  1504.    && ChkArgCnt(2, 2)
  1505.    && CheckSup(True))
  1506.     switch (DecodeAdr(&ArgStr[1], MModReg | MModCtl, &DestAdrVals))
  1507.     {
  1508.       case eModReg:
  1509.       {
  1510.         tAdrVals SrcAdrVals;
  1511.  
  1512.         if (DecodeAdr(&ArgStr[2], MModCtl, &SrcAdrVals))
  1513.           AppendCode((OpSize ? 0x7d00 : 0x8c00) | (DestAdrVals.Val << 4) | SrcAdrVals.Val);
  1514.         break;
  1515.       }
  1516.       case eModCtl:
  1517.       {
  1518.         tAdrVals SrcAdrVals;
  1519.  
  1520.         if (DecodeAdr(&ArgStr[2], MModReg, &SrcAdrVals))
  1521.           AppendCode((OpSize ? 0x7d08 : 0x8c08) | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1522.         break;
  1523.       }
  1524.       default:
  1525.         break;
  1526.     }
  1527. }
  1528.  
  1529. /*!------------------------------------------------------------------------
  1530.  * \fn     DecodeLDR(Word Code)
  1531.  * \brief  decode LDR[L|B]
  1532.  * \param  Code machine code
  1533.  * ------------------------------------------------------------------------ */
  1534.  
  1535. static void DecodeLDR(Word Code)
  1536. {
  1537.   Word Reg;
  1538.   tSymbolSize RegSize;
  1539.   int RegArgIndex = 1;
  1540.  
  1541.   if (SetOpSizeFromCode(Code)
  1542.    && ChkArgCnt(2, 2))
  1543.   switch (DecodeReg(&ArgStr[RegArgIndex], &Reg, &RegSize, ChkRegSize_8To32, False))
  1544.   {
  1545.     case eIsNoReg:
  1546.       RegArgIndex = 2;
  1547.       if (DecodeReg(&ArgStr[RegArgIndex], &Reg, &RegSize, ChkRegSize_8To32, True) != eIsReg)
  1548.         return;
  1549.       Code |= 2;
  1550.       /* fall-thru */
  1551.     case eIsReg:
  1552.     {
  1553.       tEvalResult EvalResult;
  1554.       LongWord Addr;
  1555.  
  1556.       if (!SetOpSize(RegSize, &ArgStr[RegArgIndex]))
  1557.         return;
  1558.       if (OpSize > eSymbolSize32Bit)
  1559.       {
  1560.         WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[RegArgIndex]);
  1561.         return;
  1562.       }
  1563.  
  1564.       Addr = EvalStrIntExpressionWithResult(&ArgStr[3 - RegArgIndex], MemIntType, &EvalResult);
  1565.       if (EvalResult.OK)
  1566.       {
  1567.         Word Delta;
  1568.  
  1569.         if (!mFirstPassUnknownOrQuestionable(EvalResult.Flags) && (GetSegment(Addr) != GetSegment(EProgCounter())))
  1570.           WrStrErrorPos(ErrNum_InAccSegment, &ArgStr[2]);
  1571.  
  1572.         Delta = (Addr & 0xffff) - ((EProgCounter() + 4) & 0xffff);
  1573.         AppendCode(((Lo(Code) | ((OpSize == eSymbolSize32Bit) ? 0x5 : OpSize)) << 8) | Reg);
  1574.         AppendCode(Delta);
  1575.       }
  1576.       break;
  1577.     }
  1578.     case eRegAbort:
  1579.       break;
  1580.   }
  1581. }
  1582.  
  1583. /*!------------------------------------------------------------------------
  1584.  * \fn     DecodeADD(Word Code)
  1585.  * \brief  decode ADD/ADDB/ADDL instruction
  1586.  * \param  Code instruction type
  1587.  * ------------------------------------------------------------------------ */
  1588.  
  1589. static void DecodeADD(Word Code)
  1590. {
  1591.   tAdrVals DestAdrVals;
  1592.  
  1593.   if (!SetOpSizeFromCode(Code)
  1594.    || !ChkArgCnt(2, 2))
  1595.     return;
  1596.  
  1597.   if (DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals) == eModReg)
  1598.   {
  1599.     tAdrVals SrcAdrVals;
  1600.  
  1601.     switch (DecodeAdr(&ArgStr[2], MModReg | MModImm | MModIReg | MModDirect | MModIndexed, &SrcAdrVals))
  1602.     {
  1603.       case eModReg:
  1604.         AppendCode(((OpSize == eSymbolSize32Bit) ? 0x9600 : (0x8000 | (OpSize << 8)))
  1605.                  | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1606.         break;
  1607.       case eModIReg:
  1608.       case eModImm:
  1609.         AppendCode(((OpSize == eSymbolSize32Bit) ? 0x1600 : (0x0000 | (OpSize << 8)))
  1610.                  | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1611.         AppendAdrVals(&SrcAdrVals);
  1612.         break;
  1613.       case eModDirect:
  1614.       case eModIndexed:
  1615.         AppendCode(((OpSize == eSymbolSize32Bit) ? 0x5600 : (0x4000 | (OpSize << 8)))
  1616.                  | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1617.         AppendAdrVals(&SrcAdrVals);
  1618.         break;
  1619.       default:
  1620.         break;
  1621.     }
  1622.   }
  1623. }
  1624.  
  1625. /*!------------------------------------------------------------------------
  1626.  * \fn     DecodeSUB(Word Code)
  1627.  * \brief  decode SUB/SUBB/SUBL instruction
  1628.  * \param  Code instruction type
  1629.  * ------------------------------------------------------------------------ */
  1630.  
  1631. static void DecodeSUB(Word Code)
  1632. {
  1633.   tAdrVals DestAdrVals;
  1634.  
  1635.   if (!SetOpSizeFromCode(Code)
  1636.    || !ChkArgCnt(2, 2))
  1637.     return;
  1638.  
  1639.   if (DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals) == eModReg)
  1640.   {
  1641.     tAdrVals SrcAdrVals;
  1642.  
  1643.     switch (DecodeAdr(&ArgStr[2], MModReg | MModImm | MModIReg | MModDirect | MModIndexed, &SrcAdrVals))
  1644.     {
  1645.       case eModReg:
  1646.         AppendCode(((OpSize == eSymbolSize32Bit) ? 0x9200 : (0x8200 | (OpSize << 8)))
  1647.                  | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1648.         break;
  1649.       case eModIReg:
  1650.       case eModImm:
  1651.         AppendCode(((OpSize == eSymbolSize32Bit) ? 0x1200 : (0x0200 | (OpSize << 8)))
  1652.                  | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1653.         AppendAdrVals(&SrcAdrVals);
  1654.         break;
  1655.       case eModDirect:
  1656.       case eModIndexed:
  1657.         AppendCode(((OpSize == eSymbolSize32Bit) ? 0x5200 : (0x4200 | (OpSize << 8)))
  1658.                  | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1659.         AppendAdrVals(&SrcAdrVals);
  1660.         break;
  1661.       default:
  1662.         break;
  1663.     }
  1664.   }
  1665. }
  1666.  
  1667. /*!------------------------------------------------------------------------
  1668.  * \fn     DecodeCP(Word Code)
  1669.  * \brief  decode CP/CPB/CPL instruction
  1670.  * \param  Code instruction type
  1671.  * ------------------------------------------------------------------------ */
  1672.  
  1673. static void DecodeCP(Word Code)
  1674. {
  1675.   tAdrVals DestAdrVals;
  1676.  
  1677.   if (!SetOpSizeFromCode(Code)
  1678.    || !ChkArgCnt(2, 2))
  1679.     return;
  1680.  
  1681.   switch (DecodeAdr(&ArgStr[1], MModReg | MModIReg | MModDirect | MModIndexed, &DestAdrVals))
  1682.   {
  1683.     case eModReg:
  1684.     {
  1685.       tAdrVals SrcAdrVals;
  1686.  
  1687.       switch (DecodeAdr(&ArgStr[2], MModReg | MModImm | MModIReg | MModDirect | MModIndexed, &SrcAdrVals))
  1688.       {
  1689.         case eModReg:
  1690.           AppendCode(((OpSize == eSymbolSize32Bit) ? 0x9000 : (0x8a00 | (OpSize << 8)))
  1691.                    | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1692.           break;
  1693.         case eModIReg:
  1694.         case eModImm:
  1695.           AppendCode(((OpSize == eSymbolSize32Bit) ? 0x1000 : (0x0a00 | (OpSize << 8)))
  1696.                    | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1697.           AppendAdrVals(&SrcAdrVals);
  1698.           break;
  1699.         case eModDirect:
  1700.         case eModIndexed:
  1701.           AppendCode(((OpSize == eSymbolSize32Bit) ? 0x5000 : (0x4a00 | (OpSize << 8)))
  1702.                    | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1703.           AppendAdrVals(&SrcAdrVals);
  1704.           break;
  1705.         default:
  1706.           break;
  1707.       }
  1708.       break;
  1709.     }
  1710.     case eModIReg:
  1711.     {
  1712.       tAdrVals SrcAdrVals;
  1713.  
  1714.       ImmOpSize = (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize;
  1715.       if (OpSize == eSymbolSize32Bit) WrStrErrorPos(ErrNum_InvOpSize, &OpPart);
  1716.       else if (eModImm == DecodeAdr(&ArgStr[2], MModImm, &SrcAdrVals))
  1717.       {
  1718.         AppendCode(0x0c01 | (DestAdrVals.Val << 4)  | (OpSize << 8));
  1719.         AppendAdrVals(&SrcAdrVals);
  1720.       }
  1721.       break;
  1722.     }
  1723.     case eModDirect:
  1724.     case eModIndexed:
  1725.     {
  1726.       tAdrVals SrcAdrVals;
  1727.  
  1728.       ImmOpSize = (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize;
  1729.       if (OpSize == eSymbolSize32Bit) WrStrErrorPos(ErrNum_InvOpSize, &OpPart);
  1730.       else if (eModImm == DecodeAdr(&ArgStr[2], MModImm, &SrcAdrVals))
  1731.       {
  1732.         AppendCode(0x4c01 | (DestAdrVals.Val << 4)  | (OpSize << 8));
  1733.         AppendAdrVals(&DestAdrVals);
  1734.         AppendAdrVals(&SrcAdrVals);
  1735.       }
  1736.       break;
  1737.     }
  1738.     default:
  1739.       break;
  1740.   }
  1741. }
  1742.  
  1743. /*!------------------------------------------------------------------------
  1744.  * \fn     DecodeADC_SBC(Word Code)
  1745.  * \brief  decode ADC/SBC instructions
  1746.  * \param  Code instruction type
  1747.  * ------------------------------------------------------------------------ */
  1748.  
  1749. static void DecodeADC_SBC(Word Code)
  1750. {
  1751.   tAdrVals DestAdrVals, SrcAdrVals;
  1752.  
  1753.   if (!SetOpSizeFromCode(Code)
  1754.    || !ChkArgCnt(2, 2))
  1755.     return;
  1756.  
  1757.   if ((DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals) == eModReg)
  1758.    && (DecodeAdr(&ArgStr[2], MModReg, &SrcAdrVals) == eModReg))
  1759.   {
  1760.     if (OpSize > eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
  1761.     else
  1762.       AppendCode(0x8000 | (((Code & 0xfe) | OpSize) << 8)
  1763.                | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1764.   }
  1765. }
  1766.  
  1767. /*!------------------------------------------------------------------------
  1768.  * \fn     DecodeAND_OR_XOR(Word Code)
  1769.  * \brief  decode AND/OR/XOR instructions
  1770.  * \param  Code instruction type
  1771.  * ------------------------------------------------------------------------ */
  1772.  
  1773. static void DecodeAND_OR_XOR(Word Code)
  1774. {
  1775.   tAdrVals DestAdrVals;
  1776.  
  1777.   if (!SetOpSizeFromCode(Code)
  1778.    || !ChkArgCnt(2, 2))
  1779.     return;
  1780.  
  1781.   if (DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals) == eModReg)
  1782.   {
  1783.     tAdrVals SrcAdrVals;
  1784.  
  1785.     if (OpSize > eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
  1786.     else switch (DecodeAdr(&ArgStr[2], MModReg | MModImm | MModIReg | MModDirect | MModIndexed, &SrcAdrVals))
  1787.     {
  1788.       case eModReg:
  1789.         AppendCode(0x8000 | (((Code & 0xfe) | OpSize) << 8)
  1790.                  | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1791.         break;
  1792.       case eModIReg:
  1793.       case eModImm:
  1794.         AppendCode(0x0000 | (((Code & 0xfe) | OpSize) << 8)
  1795.                  | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1796.         AppendAdrVals(&SrcAdrVals);
  1797.         break;
  1798.       case eModDirect:
  1799.       case eModIndexed:
  1800.         AppendCode(0x4000 | (((Code & 0xfe) | OpSize) << 8)
  1801.                  | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  1802.         AppendAdrVals(&SrcAdrVals);
  1803.         break;
  1804.       default:
  1805.         break;
  1806.     }
  1807.   }
  1808. }
  1809.  
  1810. /*!------------------------------------------------------------------------
  1811.  * \fn     DecodeINC_DEC(Word Code)
  1812.  * \brief  decode increment/decrement instructions
  1813.  * \param  Code instruction type
  1814.  * ------------------------------------------------------------------------ */
  1815.  
  1816. static void DecodeINC_DEC(Word Code)
  1817. {
  1818.   tAdrVals AdrVals;
  1819.  
  1820.   if (SetOpSizeFromCode(Code)
  1821.    && ChkArgCnt(1, 2)
  1822.    && DecodeAdr(&ArgStr[1], MModReg | MModIReg | MModDirect | MModIndexed, &AdrVals))
  1823.   {
  1824.     if (OpSize == eSymbolSizeUnknown)
  1825.       OpSize = eSymbolSize16Bit;
  1826.     if (OpSize > eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
  1827.     else
  1828.     {
  1829.       tEvalResult EvalResult;
  1830.       Word ImmVal = 0;
  1831.  
  1832.       if (2 == ArgCnt)
  1833.         ImmVal = DecodeImm1_16(&ArgStr[2], &EvalResult);
  1834.       else
  1835.         EvalResult.OK = True;
  1836.  
  1837.       if (EvalResult.OK)
  1838.         switch (AdrVals.Mode)
  1839.         {
  1840.           case eModReg:
  1841.             AppendCode(0x8000 | ((Code | OpSize) << 8) | (AdrVals.Val << 4) | ImmVal);
  1842.             break;
  1843.           case eModIReg:
  1844.             AppendCode(0x0000 | ((Code | OpSize) << 8) | (AdrVals.Val << 4) | ImmVal);
  1845.             break;
  1846.           case eModDirect:
  1847.           case eModIndexed:
  1848.             AppendCode(0x4000 | ((Code | OpSize) << 8) | (AdrVals.Val << 4) | ImmVal);
  1849.             AppendAdrVals(&AdrVals);
  1850.             break;
  1851.           default:
  1852.             break;
  1853.         }
  1854.     }
  1855.   }
  1856. }
  1857.  
  1858. /*!------------------------------------------------------------------------
  1859.  * \fn     DecodeBitOp(Word Code)
  1860.  * \brief  decode bit set/reset/test instructions
  1861.  * \param  Code instruction type
  1862.  * ------------------------------------------------------------------------ */
  1863.  
  1864. static void DecodeBitOp(Word Code)
  1865. {
  1866.   tAdrVals DestAdrVals, SrcAdrVals;
  1867.   tSymbolSize DestOpSize;
  1868.  
  1869.   if (!SetOpSizeFromCode(Code))
  1870.     return;
  1871.  
  1872.   switch (ArgCnt)
  1873.   {
  1874.     case 1:
  1875.     {
  1876.       LongWord PacketBit;
  1877.  
  1878.       if (DecodeBitArg(&PacketBit, 1, 1, OpSize))
  1879.       {
  1880.         LongWord Address;
  1881.         Byte BitPos;
  1882.         Boolean ForceShort;
  1883.  
  1884.         if (DissectBitSymbol(PacketBit, &Address, &BitPos, &DestOpSize, &ForceShort)
  1885.          && SetOpSize(DestOpSize, &ArgStr[1]))
  1886.         {
  1887.           ClearAdrVals(&SrcAdrVals);
  1888.           SrcAdrVals.Val = BitPos;
  1889.           ClearAdrVals(&DestAdrVals);
  1890.           FillAbsAddr(&DestAdrVals, Address, False, ForceShort);
  1891.           goto Abs2Imm; /* yeah! */
  1892.         }
  1893.       }
  1894.       break;
  1895.     }
  1896.     case 2:
  1897.       if (DecodeAdr(&ArgStr[1], MModReg | MModIReg | MModDirect | MModIndexed, &DestAdrVals))
  1898.       {
  1899.         DestOpSize = (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize;
  1900.  
  1901.         switch (DestOpSize)
  1902.         {
  1903.           case eSymbolSize8Bit:
  1904.             ImmOpSize = eSymbolSize3Bit; break;
  1905.           case eSymbolSize16Bit:
  1906.             ImmOpSize = eSymbolSize4Bit; break;
  1907.           default:
  1908.             WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]); return;
  1909.         }
  1910.         OpSize = eSymbolSizeUnknown;
  1911.  
  1912.         switch (DecodeAdr(&ArgStr[2], MModReg | MModImm, &SrcAdrVals))
  1913.         {
  1914.           case eModImm:
  1915.             switch (DestAdrVals.Mode)
  1916.             {
  1917.               case eModReg:
  1918.                 AppendCode(0x8000 | (((Code & 0xfe) | DestOpSize) << 8)
  1919.                          | (DestAdrVals.Val << 4) | SrcAdrVals.Val);
  1920.                 break;
  1921.               case eModIReg:
  1922.                 AppendCode(0x0000 | (((Code & 0xfe) | DestOpSize) << 8)
  1923.                          | (DestAdrVals.Val << 4) | SrcAdrVals.Val);
  1924.                 break;
  1925.               case eModDirect:
  1926.               case eModIndexed:
  1927.               Abs2Imm:
  1928.                 AppendCode(0x4000 | (((Code & 0xfe) | DestOpSize) << 8)
  1929.                          | (DestAdrVals.Val << 4) | SrcAdrVals.Val);
  1930.                 AppendAdrVals(&DestAdrVals);
  1931.                 break;
  1932.               default:
  1933.                 break;
  1934.             }
  1935.             break;
  1936.           case eModReg:
  1937.             switch (DestAdrVals.Mode)
  1938.             {
  1939.               case eModReg:
  1940.                 if (OpSize != eSymbolSize16Bit) WrStrErrorPos (ErrNum_InvOpSize, &ArgStr[2]);
  1941.                 else
  1942.                 {
  1943.                   AppendCode(0x0000 | (((Code & 0xfe) | DestOpSize) << 8) | SrcAdrVals.Val);
  1944.                   AppendCode(DestAdrVals.Val << 8);
  1945.                 }
  1946.                 break;
  1947.               case eModNone:
  1948.                 break;
  1949.               default:
  1950.                 WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  1951.             }
  1952.             break;
  1953.           default:
  1954.             break;
  1955.         }
  1956.       }
  1957.       break;
  1958.     default:
  1959.       (void)ChkArgCnt(1, 2);
  1960.   }
  1961. }
  1962.  
  1963. /*!------------------------------------------------------------------------
  1964.  * \fn     DecodeCALL_JP(Word Code)
  1965.  * \brief  decode jump/call instructions
  1966.  * \param  instruction code
  1967.  * ------------------------------------------------------------------------ */
  1968.  
  1969. static void DecodeCALL_JP(Word Code)
  1970. {
  1971.   tAdrVals AdrVals;
  1972.   Boolean IsCALL = Code & 1;
  1973.  
  1974.   if (ChkArgCnt(1, 2 - IsCALL))
  1975.   {
  1976.     Word Condition;
  1977.  
  1978.     if (IsCALL)
  1979.       Condition = 0;
  1980.     else if (!DecodeCondition((ArgCnt == 2) ? &ArgStr[1] : NULL, &Condition))
  1981.       return;
  1982.  
  1983.     switch (DecodeAdr(&ArgStr[ArgCnt], MModIReg | MModDirect | MModIndexed, &AdrVals))
  1984.     {
  1985.       case eModIReg:
  1986.         AppendCode(0x0000 | (Code << 8) | (AdrVals.Val << 4) | Condition);
  1987.         break;
  1988.       case eModDirect:
  1989.       case eModIndexed:
  1990.         AppendCode(0x4000 | (Code << 8) | (AdrVals.Val << 4) | Condition);
  1991.         AppendAdrVals(&AdrVals);
  1992.         break;
  1993.       default:
  1994.         break;
  1995.     }
  1996.   }
  1997. }
  1998.  
  1999. /*!------------------------------------------------------------------------
  2000.  * \fn     DecodeBranch(Word CodeWord MaxDist, Boolean Inverse, const tStrComp *pArg)
  2001.  * \brief  relative branch core decode
  2002.  * \param  Code instruction code (upper bits)
  2003.  * \param  MaxDist maximum positive distance (in bytes, e.g. even value)
  2004.  * \param  Inverse Displacement is subtraced and not added by CPU
  2005.  * \param  pArg source argument
  2006.  * ------------------------------------------------------------------------ */
  2007.  
  2008. static void DecodeBranch(Word Code, Word MaxDist, Boolean Inverse, const tStrComp *pArg)
  2009. {
  2010.   tEvalResult EvalResult;
  2011.   LongWord Addr = EvalStrIntExpressionWithResult(pArg, MemIntType, &EvalResult);
  2012.  
  2013.   if (EvalResult.OK)
  2014.   {
  2015.     Word Delta;
  2016.  
  2017.     /* considering wraparound in segment makes things a bit more complicated: */
  2018.  
  2019.     if (!mFirstPassUnknownOrQuestionable(EvalResult.Flags) && (GetSegment(Addr) != GetSegment(EProgCounter())))
  2020.       WrStrErrorPos(ErrNum_InAccSegment, pArg);
  2021.  
  2022.     Delta = (Addr & 0xffff) - ((EProgCounter() + 2) & 0xffff);
  2023.     if (Inverse)
  2024.       Delta = (~Delta) + 1;
  2025.     if ((Delta & 1) && !mFirstPassUnknownOrQuestionable(EvalResult.Flags)) WrStrErrorPos(ErrNum_AddrMustBeEven, pArg);
  2026.     else if ((Delta > MaxDist) && (Delta < (0xfffe - MaxDist)) && !mFirstPassUnknownOrQuestionable(EvalResult.Flags)) WrStrErrorPos(ErrNum_JmpDistTooBig, pArg);
  2027.     else
  2028.       AppendCode(Code | ((Delta >> 1) & (MaxDist + 1)));
  2029.   }
  2030. }
  2031.  
  2032. /*!------------------------------------------------------------------------
  2033.  * \fn     DecodeCALR(Word Code)
  2034.  * \brief  decode CALR instruction
  2035.  * \param  Code instruction code (upper bits)
  2036.  * ------------------------------------------------------------------------ */
  2037.  
  2038. static void DecodeCALR(Word Code)
  2039. {
  2040.   if (ChkArgCnt(1, 1))
  2041.     DecodeBranch(Code, 4094, True, &ArgStr[1]);
  2042. }
  2043.  
  2044. /*!------------------------------------------------------------------------
  2045.  * \fn     DecodeJR(Word Code)
  2046.  * \brief  decode JR instruction
  2047.  * \param  Code instruction code (upper bits)
  2048.  * ------------------------------------------------------------------------ */
  2049.  
  2050. static void DecodeJR(Word Code)
  2051. {
  2052.   Word Condition;
  2053.  
  2054.   if (ChkArgCnt(1, 2)
  2055.    && DecodeCondition(ArgCnt == 2 ? &ArgStr[1] : NULL, &Condition))
  2056.     DecodeBranch(Code | (Condition << 8), 254, False, &ArgStr[ArgCnt]);
  2057. }
  2058.  
  2059. /*!------------------------------------------------------------------------
  2060.  * \fn     DecodeDJNZ(Word Code)
  2061.  * \brief  decode DJNZ instructions
  2062.  * \param  size spec
  2063.  * ------------------------------------------------------------------------ */
  2064.  
  2065. static void DecodeDJNZ(Word Code)
  2066. {
  2067.   tAdrVals AdrVals;
  2068.  
  2069.   if (SetOpSizeFromCode(Code)
  2070.    && ChkArgCnt(2, 2)
  2071.    && DecodeAdr(&ArgStr[1], MModReg, &AdrVals))
  2072.   {
  2073.     if (OpSize > eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
  2074.     else
  2075.     {
  2076.       tEvalResult EvalResult;
  2077.       LongWord Addr = EvalStrIntExpressionWithResult(&ArgStr[2], MemIntType, &EvalResult);
  2078.  
  2079.       if (EvalResult.OK)
  2080.       {
  2081.         Word Delta;
  2082.  
  2083.         /* considering wraparound in segment makes things a bit more complicated: */
  2084.  
  2085.         if (!mFirstPassUnknownOrQuestionable(EvalResult.Flags) && (GetSegment(Addr) != GetSegment(EProgCounter())))
  2086.           WrStrErrorPos(ErrNum_InAccSegment, &ArgStr[2]);
  2087.  
  2088.         Delta = (Addr & 0xffff) - ((EProgCounter() + 2) & 0xffff);
  2089.         if ((Delta & 1) && !mFirstPassUnknownOrQuestionable(EvalResult.Flags)) WrStrErrorPos(ErrNum_AddrMustBeEven, &ArgStr[2]);
  2090.         else if ((Delta > 0) && (Delta < 0xff02) && !mFirstPassUnknownOrQuestionable(EvalResult.Flags)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[2]);
  2091.         else
  2092.         {
  2093.           Delta = (0x10000lu - Delta) >> 1;
  2094.           AppendCode(0xf000 | (AdrVals.Val << 8) | (OpSize << 7) | (Delta & 0x7f));
  2095.         }
  2096.       }
  2097.     }
  2098.   }
  2099. }
  2100.  
  2101. /*!------------------------------------------------------------------------
  2102.  * \fn     DecodeCLR_COM_NEG_TSET(Word Code)
  2103.  * \brief  decode CLR/COM/NEG/TSET instructions
  2104.  * \param  Code machine code + size spec
  2105.  * ------------------------------------------------------------------------ */
  2106.  
  2107. static void DecodeCLR_COM_NEG_TSET(Word Code)
  2108. {
  2109.   tAdrVals AdrVals;
  2110.  
  2111.   if (SetOpSizeFromCode(Code)
  2112.    && ChkArgCnt(1,1)
  2113.    && DecodeAdr(&ArgStr[1], MModReg | MModIReg | MModDirect | MModIndexed, &AdrVals))
  2114.   {
  2115.     if (OpSize == eSymbolSizeUnknown)
  2116.       OpSize = eSymbolSize16Bit;
  2117.     if (OpSize > eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
  2118.     else
  2119.     {
  2120.       Code = ((Code >> 4) & 0x0f) | (((Code & 0x0e) | OpSize) << 8);
  2121.       switch (AdrVals.Mode)
  2122.       {
  2123.         case eModReg:
  2124.           AppendCode(0x8000 | Code | (AdrVals.Val << 4));
  2125.           break;
  2126.         case eModIReg:
  2127.           AppendCode(0x0000 | Code | (AdrVals.Val << 4));
  2128.           break;
  2129.         case eModDirect:
  2130.         case eModIndexed:
  2131.           AppendCode(0x4000 | Code | (AdrVals.Val << 4));
  2132.           AppendAdrVals(&AdrVals);
  2133.           break;
  2134.         default:
  2135.           break;
  2136.       }
  2137.     }
  2138.   }
  2139. }
  2140.  
  2141. /*!------------------------------------------------------------------------
  2142.  * \fn     DecodeTEST(Word Code)
  2143.  * \brief  decode TEST instruction
  2144.  * \param  Code machine code + size spec
  2145.  * ------------------------------------------------------------------------ */
  2146.  
  2147. static void DecodeTEST(Word Code)
  2148. {
  2149.   tAdrVals AdrVals;
  2150.  
  2151.   if (SetOpSizeFromCode(Code)
  2152.    && ChkArgCnt(1, 1)
  2153.    && DecodeAdr(&ArgStr[1], MModReg | MModIReg | MModDirect | MModIndexed, &AdrVals))
  2154.   {
  2155.     if (OpSize == eSymbolSizeUnknown)
  2156.       OpSize = eSymbolSize16Bit;
  2157.     if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  2158.     else
  2159.     {
  2160.       Code = (Lo(Code) | ((OpSize == eSymbolSize32Bit) ? 0x10 : OpSize)) << 8 | ((OpSize == eSymbolSize32Bit) ? 8 : 4);
  2161.       switch (AdrVals.Mode)
  2162.       {
  2163.         case eModReg:
  2164.           AppendCode(0x8000 | Code | (AdrVals.Val << 4));
  2165.           break;
  2166.         case eModIReg:
  2167.           AppendCode(0x0000 | Code | (AdrVals.Val << 4));
  2168.           break;
  2169.         case eModDirect:
  2170.         case eModIndexed:
  2171.           AppendCode(0x4000 | Code | (AdrVals.Val << 4));
  2172.           AppendAdrVals(&AdrVals);
  2173.           break;
  2174.         default:
  2175.           break;
  2176.       }
  2177.     }
  2178.   }
  2179. }
  2180.  
  2181. /*!------------------------------------------------------------------------
  2182.  * \fn     DecodeEX(Word Code)
  2183.  * \brief  decode EX instruction
  2184.  * \param  Code machine code + size spec
  2185.  * ------------------------------------------------------------------------ */
  2186.  
  2187. static void DecodeEX(Word Code)
  2188. {
  2189.   tAdrVals SrcAdrVals, DestAdrVals;
  2190.  
  2191.   if (SetOpSizeFromCode(Code)
  2192.    && ChkArgCnt(2, 2)
  2193.    && DecodeAdr(&ArgStr[1], MModReg | MModIReg | MModDirect | MModIndexed, &DestAdrVals)
  2194.    && DecodeAdr(&ArgStr[2], MModReg | ((DestAdrVals.Mode == eModReg) ? (MModIReg | MModDirect | MModIndexed) : 0), &SrcAdrVals))
  2195.   {
  2196.     if (OpSize == eSymbolSizeUnknown)
  2197.       OpSize = eSymbolSize16Bit;
  2198.     if (OpSize > eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
  2199.     else
  2200.     {
  2201.       if (DestAdrVals.Mode != eModReg)
  2202.       {
  2203.         tAdrVals Swap;
  2204.         Swap = SrcAdrVals;
  2205.         SrcAdrVals = DestAdrVals;
  2206.         DestAdrVals = Swap;
  2207.       }
  2208.       Code = (Lo(Code) | OpSize) << 8;
  2209.       switch (SrcAdrVals.Mode)
  2210.       {
  2211.         case eModReg:
  2212.           AppendCode(0x8000 | Code | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  2213.           break;
  2214.         case eModIReg:
  2215.           AppendCode(0x0000 | Code | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  2216.           break;
  2217.         case eModDirect:
  2218.         case eModIndexed:
  2219.           AppendCode(0x4000 | Code | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  2220.           AppendAdrVals(&SrcAdrVals);
  2221.           break;
  2222.         default:
  2223.           break;
  2224.       }
  2225.     }
  2226.   }
  2227. }
  2228.  
  2229. /*!------------------------------------------------------------------------
  2230.  * \fn     DecodeEXTS(Word Code)
  2231.  * \brief  decode EXTS instruction
  2232.  * \param  Code machine code + size spec
  2233.  * ------------------------------------------------------------------------ */
  2234.  
  2235. static void DecodeEXTS(Word Code)
  2236. {
  2237.   if (SetOpSizeFromCode(Code)
  2238.    && ChkArgCnt(1, 1))
  2239.   {
  2240.     tAdrVals AdrVals;
  2241.  
  2242.     if (OpSize != eSymbolSizeUnknown)
  2243.       OpSize++;
  2244.     if (DecodeAdr(&ArgStr[1], MModReg, &AdrVals))
  2245.     {
  2246.       Code = (Lo(Code) << 8) | 0x8000 | (AdrVals.Val << 4);
  2247.       switch (OpSize)
  2248.       {
  2249.         case eSymbolSize16Bit:
  2250.           AppendCode(Code | 0x0000);
  2251.           break;
  2252.         case eSymbolSize32Bit:
  2253.           AppendCode(Code | 0x000a);
  2254.           break;
  2255.         case eSymbolSize64Bit:
  2256.           AppendCode(Code | 0x0007);
  2257.           break;
  2258.         default:
  2259.           WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
  2260.       }
  2261.     }
  2262.   }
  2263. }
  2264.  
  2265. /*!------------------------------------------------------------------------
  2266.  * \fn     DecodeMULT_DIV(Word Code)
  2267.  * \brief  decode multiply/divide instructions
  2268.  * \param  Code instruction code
  2269.  * ------------------------------------------------------------------------ */
  2270.  
  2271. static void DecodeMULT_DIV(Word Code)
  2272. {
  2273.   if (SetOpSizeFromCode(Code)
  2274.    && ChkArgCnt(2, 2))
  2275.   {
  2276.     tAdrVals DestAdrVals;
  2277.  
  2278.     if (OpSize != eSymbolSizeUnknown)
  2279.       OpSize++;
  2280.     if (DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals) == eModReg)
  2281.     {
  2282.       tAdrVals SrcAdrVals;
  2283.  
  2284.       if ((OpSize < eSymbolSize32Bit) || (OpSize > eSymbolSize64Bit))
  2285.       {
  2286.         WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
  2287.         return;
  2288.       }
  2289.  
  2290.       OpSize--;
  2291.       switch (DecodeAdr(&ArgStr[2], MModReg | MModImm | MModIReg | MModDirect | MModIndexed, &SrcAdrVals))
  2292.       {
  2293.         case eModReg:
  2294.           AppendCode(0x8000 | ((Code | (OpSize & 1)) << 8) | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  2295.           break;
  2296.         case eModImm:
  2297.         case eModIReg:
  2298.           AppendCode(0x0000 | ((Code | (OpSize & 1)) << 8) | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  2299.           AppendAdrVals(&SrcAdrVals);
  2300.           break;
  2301.         case eModDirect:
  2302.         case eModIndexed:
  2303.           AppendCode(0x4000 | ((Code | (OpSize & 1)) << 8) | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
  2304.           AppendAdrVals(&SrcAdrVals);
  2305.           break;
  2306.         default:
  2307.           break;
  2308.       }
  2309.     }
  2310.   }
  2311. }
  2312.  
  2313. /*!------------------------------------------------------------------------
  2314.  * \fn     DecodeDAB(Word Code)
  2315.  * \brief  decode DAB instruction
  2316.  * \param  Code instruction code
  2317.  * ------------------------------------------------------------------------ */
  2318.  
  2319. static void DecodeDAB(Word Code)
  2320. {
  2321.   tAdrVals AdrVals;
  2322.  
  2323.   SetOpSize(eSymbolSize8Bit, &OpPart);
  2324.   if (ChkArgCnt(1,1) && DecodeAdr(&ArgStr[1], MModReg, &AdrVals))
  2325.     AppendCode(Code | (AdrVals.Val << 4));
  2326. }
  2327.  
  2328. /*!------------------------------------------------------------------------
  2329.  * \fn     DecodeFLG(Word Code)
  2330.  * \brief  decode flag set/reset/complement instructions
  2331.  * \param  machine code
  2332.  * ------------------------------------------------------------------------ */
  2333.  
  2334. static void DecodeFLG(Word Code)
  2335. {
  2336.   if (ChkArgCnt(1, ArgCntMax))
  2337.   {
  2338.     int z;
  2339.     Word Num;
  2340.     static const char FlagNames[] = "PSZCV";
  2341.  
  2342.     for (z = 1; z <= ArgCnt; z++)
  2343.     {
  2344.       if (!as_strcasecmp(ArgStr[z].str.p_str, "P/V"))
  2345.         Num = 1 << 0;
  2346.       else if (!as_strcasecmp(ArgStr[z].str.p_str, "ZR"))
  2347.         Num = 1 << 2;
  2348.       else if (!as_strcasecmp(ArgStr[z].str.p_str, "CY"))
  2349.         Num = 1 << 3;
  2350.       else if (1 == strlen(ArgStr[z].str.p_str))
  2351.       {
  2352.         const char *pPos = strchr(FlagNames, as_toupper(*ArgStr[z].str.p_str));
  2353.         Num = pPos ? (1 << ((pPos - FlagNames) % 4)) : 0;
  2354.       }
  2355.       else
  2356.         Num = 0;
  2357.  
  2358.       if (!Num)
  2359.       {
  2360.         WrStrErrorPos(ErrNum_UnknownFlag, &ArgStr[z]);
  2361.         return;
  2362.       }
  2363.       else if (Code & (Num << 4))
  2364.       {
  2365.         WrStrErrorPos(ErrNum_DuplicateFlag, &ArgStr[z]);
  2366.         return;
  2367.       }
  2368.       else
  2369.         Code |= Num << 4;
  2370.     }
  2371.     AppendCode(Code);
  2372.   }
  2373. }
  2374.  
  2375. /*!------------------------------------------------------------------------
  2376.  * \fn     DecodeDI_EI(Word Code)
  2377.  * \brief  decode interrupt enable/disable instructions
  2378.  * \param  Code machine code
  2379.  * ------------------------------------------------------------------------ */
  2380.  
  2381. static void DecodeDI_EI(Word Code)
  2382. {
  2383.   if (ChkArgCnt(1, ArgCntMax)
  2384.    && CheckSup(True))
  2385.   {
  2386.     int z;
  2387.     Word Num;
  2388.  
  2389.     Code |= 3;
  2390.     for (z = 1; z <= ArgCnt; z++)
  2391.     {
  2392.       if (!as_strcasecmp(ArgStr[z].str.p_str, "VI"))
  2393.         Num = 1 << 1;
  2394.       else if (!as_strcasecmp(ArgStr[z].str.p_str, "NVI"))
  2395.         Num = 1 << 0;
  2396.       else
  2397.         Num = 0;
  2398.  
  2399.       if (!Num)
  2400.       {
  2401.         WrStrErrorPos(ErrNum_UnknownInt, &ArgStr[z]);
  2402.         return;
  2403.       }
  2404.       else if (!(Code & Num))
  2405.       {
  2406.         WrStrErrorPos(ErrNum_DuplicateInt, &ArgStr[z]);
  2407.         return;
  2408.       }
  2409.       else
  2410.         Code &= ~Num;
  2411.     }
  2412.     AppendCode(Code);
  2413.   }
  2414. }
  2415.  
  2416. /*!------------------------------------------------------------------------
  2417.  * \fn     DecodeIN_SIN_OUT_SOUT(Word Code)
  2418.  * \brief  decode IN/SIN/OUT/SOUT
  2419.  * \param  Code machine code
  2420.  * ------------------------------------------------------------------------ */
  2421.  
  2422. static void DecodeIN_SIN_OUT_SOUT(Word Code)
  2423. {
  2424.   tAdrVals RegAdrVals;
  2425.   Word IsOUT = Code & 2,
  2426.        IsSpecial = Code & 1;
  2427.   const tStrComp *pRegArg = IsOUT ? &ArgStr[2] : &ArgStr[1],
  2428.                  *pIOArg  = IsOUT ? &ArgStr[1] : &ArgStr[2];
  2429.  
  2430.   if (SetOpSizeFromCode(Code)
  2431.    && ChkArgCnt(2, 2)
  2432.    && CheckSup(True)
  2433.    && DecodeAdr(pRegArg, MModReg, &RegAdrVals))
  2434.   {
  2435.     tAdrVals IOAdrVals;
  2436.  
  2437.     if (OpSize > eSymbolSize16Bit)
  2438.     {
  2439.       WrStrErrorPos(ErrNum_InvOpSize, pRegArg);
  2440.       return;
  2441.     }
  2442.     switch (DecodeAdr(pIOArg, MModIO | MModDirect | (IsSpecial ? 0 : MModIReg), &IOAdrVals))
  2443.     {
  2444.       case eModIReg:
  2445.         AppendCode(0x3c00 | (IsOUT << 8) | (OpSize << 8) | (IOAdrVals.Val << 4) | RegAdrVals.Val);
  2446.         break;
  2447.       case eModDirect:
  2448.         AppendCode(0x3a04 | (OpSize << 8) | (RegAdrVals.Val << 4) | Lo(Code));
  2449.         AppendAdrVals(&IOAdrVals);
  2450.         break;
  2451.       default:
  2452.         break;
  2453.     }
  2454.   }
  2455. }
  2456.  
  2457. /*!------------------------------------------------------------------------
  2458.  * \fn     DecodeCPRep(Word Code)
  2459.  * \brief  decode CP[S](I/D)[R][D] instructions
  2460.  * \param  Code instruction code
  2461.  * ------------------------------------------------------------------------ */
  2462.  
  2463. static void DecodeCPRep(Word Code)
  2464. {
  2465.   tAdrVals DestAdrVals, SrcAdrVals, CntAdrVals;
  2466.   Word Condition;
  2467.   tAdrMode DestMode = (Code & 0x02) ? eModIReg : eModReg;
  2468.  
  2469.   if (!SetOpSizeFromCode(Code)
  2470.    || !ChkArgCnt(3, 4)
  2471.    || !DecodeCondition((ArgCnt == 4) ? &ArgStr[4] : NULL, &Condition))
  2472.     return;
  2473.  
  2474.   if ((DecodeAdr(&ArgStr[1], 1 << DestMode, &DestAdrVals) == DestMode)
  2475.    && (DecodeAdr(&ArgStr[2], MModIReg, &SrcAdrVals) == eModIReg))
  2476.   {
  2477.     tSymbolSize SaveOpSize;
  2478.  
  2479.     if (OpSize == eSymbolSizeUnknown)
  2480.       OpSize = eSymbolSize16Bit;
  2481.      SaveOpSize = OpSize;
  2482.     OpSize = eSymbolSize16Bit;
  2483.     if (DecodeAdr(&ArgStr[3], MModReg, &CntAdrVals) == eModReg)
  2484.     {
  2485.       if (SaveOpSize == eSymbolSize32Bit) WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
  2486.       else
  2487.       {
  2488.         int Index =
  2489.           ChkRegOverlap((unsigned)DestAdrVals.Val, ((DestMode == eModIReg) ? AddrRegSize() : SaveOpSize),
  2490.                         (unsigned)SrcAdrVals.Val, (int)AddrRegSize(),
  2491.                         (unsigned)CntAdrVals.Val, (int)eSymbolSize16Bit,
  2492.                         0, eSymbolSizeUnknown);
  2493.  
  2494.         if (Index >= 0)
  2495.           WrStrErrorPos(ErrNum_OverlapReg, &ArgStr[Index + 1]);
  2496.         AppendCode(0xba00 | (SaveOpSize << 8) | (SrcAdrVals.Val << 4) | Lo(Code));
  2497.         AppendCode((CntAdrVals.Val << 8) | (DestAdrVals.Val << 4) | Condition);
  2498.       }
  2499.     }
  2500.   }
  2501. }
  2502.  
  2503. /*!------------------------------------------------------------------------
  2504.  * \fn     DecodeINOUTRep(Word Code)
  2505.  * \brief  decode string I/O instructions
  2506.  * \param  Code instruction machine code
  2507.  * ------------------------------------------------------------------------ */
  2508.  
  2509. static void DecodeINOUTRep(Word Code)
  2510. {
  2511.   tAdrVals DestAdrVals, SrcAdrVals;
  2512.   Word IsOUT = Code & 0x20;
  2513.  
  2514.   if (!SetOpSizeFromCode(Code)
  2515.    || !CheckSup(True)
  2516.    || !ChkArgCnt(3, 3))
  2517.     return;
  2518.  
  2519.   if (DecodeAdr(&ArgStr[1], MModIReg | (IsOUT ? MModIO : 0), &DestAdrVals)
  2520.    && DecodeAdr(&ArgStr[2], MModIReg | (IsOUT ? 0 : MModIO), &SrcAdrVals))
  2521.   {
  2522.     tAdrVals CntAdrVals;
  2523.     tSymbolSize SaveOpSize = (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize;
  2524.  
  2525.     OpSize = eSymbolSize16Bit;
  2526.     if (DecodeAdr(&ArgStr[3], MModReg, &CntAdrVals))
  2527.     {
  2528.       AppendCode(0x3a00 | (SaveOpSize << 8) | (SrcAdrVals.Val << 4) | ((Code >> 4) & 15));
  2529.       AppendCode((CntAdrVals.Val << 8) | (DestAdrVals.Val << 4) | (Code & 15));
  2530.     }
  2531.   }
  2532. }
  2533.  
  2534. /*!------------------------------------------------------------------------
  2535.  * \fn     DecodeLDRep(Word Code)
  2536.  * \brief  decode string copy instructions
  2537.  * \param  Code instruction machine code
  2538.  * ------------------------------------------------------------------------ */
  2539.  
  2540. static void DecodeLDRep(Word Code)
  2541. {
  2542.   tAdrVals DestAdrVals, SrcAdrVals;
  2543.  
  2544.   if (!SetOpSizeFromCode(Code)
  2545.    || !ChkArgCnt(3, 3))
  2546.     return;
  2547.  
  2548.   if (DecodeAdr(&ArgStr[1], MModIReg, &DestAdrVals)
  2549.    && DecodeAdr(&ArgStr[2], MModIReg, &SrcAdrVals))
  2550.   {
  2551.     tAdrVals CntAdrVals;
  2552.     tSymbolSize SaveOpSize = (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize;
  2553.  
  2554.     OpSize = eSymbolSize16Bit;
  2555.     if (DecodeAdr(&ArgStr[3], MModReg, &CntAdrVals))
  2556.     {
  2557.       AppendCode(0xba00 | (SaveOpSize << 8) | (SrcAdrVals.Val << 4) | ((Code >> 4) & 15));
  2558.       AppendCode((CntAdrVals.Val << 8) | (DestAdrVals.Val << 4) | (Code & 15));
  2559.     }
  2560.   }
  2561. }
  2562.  
  2563. /*!------------------------------------------------------------------------
  2564.  * \fn     DecodeTRRep(Word Code)
  2565.  * \brief  decode string translate instructions
  2566.  * \param  Code instruction machine code
  2567.  * ------------------------------------------------------------------------ */
  2568.  
  2569. static void DecodeTRRep(Word Code)
  2570. {
  2571.   tAdrVals DestAdrVals, SrcAdrVals, CntAdrVals;
  2572.  
  2573.   /* op size only applies to counter reg */
  2574.  
  2575.   OpSize = eSymbolSize16Bit;
  2576.   if (ChkArgCnt(3, 3)
  2577.    && DecodeAdr(&ArgStr[1], MModIReg, &DestAdrVals)
  2578.    && DecodeAdr(&ArgStr[2], MModIReg, &SrcAdrVals)
  2579.    && DecodeAdr(&ArgStr[3], MModReg, &CntAdrVals))
  2580.   {
  2581.     Boolean OK = True;
  2582.     int Index;
  2583.  
  2584.     /* R0/R1 in non-seg mode or RR0 in seg mode must not be used as src/dest.
  2585.        R1 should not be used as counter.
  2586.        This is only spelled out for TRDB, but due to the implicit usage of RH1
  2587.        in all translate instructions, this restriction effectively applies to
  2588.        them all.
  2589.        Since (R)R0 is anyway not allowed for indirect addressing, this reduces
  2590.        to check fo R1: */
  2591.  
  2592.     if (!Segmented() && (DestAdrVals.Val == 1))
  2593.     {
  2594.       WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  2595.       OK = False;
  2596.     }
  2597.     if (!Segmented() && (SrcAdrVals.Val == 1))
  2598.     {
  2599.       WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  2600.       OK = False;
  2601.     }
  2602.     if (CntAdrVals.Val == 1)
  2603.     {
  2604.       WrStrErrorPos(ErrNum_InvReg, &ArgStr[3]);
  2605.       OK = False;
  2606.     }
  2607.  
  2608.     Index = ChkRegOverlap((unsigned)DestAdrVals.Val, AddrRegSize(),
  2609.                           (unsigned)SrcAdrVals.Val, (int)AddrRegSize(),
  2610.                           (unsigned)CntAdrVals.Val, (int)eSymbolSize16Bit,
  2611.                           0, eSymbolSizeUnknown);
  2612.     if (Index >= 0)
  2613.       WrStrErrorPos(ErrNum_OverlapReg, &ArgStr[Index + 1]);
  2614.  
  2615.     if (OK)
  2616.     {
  2617.       AppendCode(0xb800 | (DestAdrVals.Val << 4) | ((Code >> 4) & 15));
  2618.       AppendCode((CntAdrVals.Val << 8) | (SrcAdrVals.Val << 4) | (Code & 15));
  2619.     }
  2620.   }
  2621. }
  2622.  
  2623. /*!------------------------------------------------------------------------
  2624.  * \fn     DecodeLDK(Word Code)
  2625.  * \brief  decode LDK instruction
  2626.  * \param  Code machine code
  2627.  * ------------------------------------------------------------------------ */
  2628.  
  2629. static void DecodeLDK(Word Code)
  2630. {
  2631.   tAdrVals DestAdrVals;
  2632.  
  2633.   if (ChkArgCnt(2, 2)
  2634.    && DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals))
  2635.   {
  2636.     Word Value;
  2637.     Boolean OK;
  2638.  
  2639.     if (OpSize != eSymbolSize16Bit)
  2640.     {
  2641.       WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
  2642.       return;
  2643.     }
  2644.     Value = EvalStrIntExpressionOffs(&ArgStr[2], !!(*ArgStr[2].str.p_str == '#'), UInt4, &OK);
  2645.     if (OK)
  2646.       AppendCode(Code | (DestAdrVals.Val << 4) | Value);
  2647.   }
  2648. }
  2649.  
  2650. /*!------------------------------------------------------------------------
  2651.  * \fn     DecodeLDM(Word Code)
  2652.  * \brief  decode LDM instruction
  2653.  * \param  Code machine code
  2654.  * ------------------------------------------------------------------------ */
  2655.  
  2656. static void DecodeLDM(Word Code)
  2657. {
  2658.   Word Count;
  2659.   tEvalResult EvalResult;
  2660.   tAdrVals RegAdrVals, MemAdrVals;
  2661.   int RegArgIndex;
  2662.  
  2663.   if (!ChkArgCnt(3, 3))
  2664.     return;
  2665.  
  2666.   Count = DecodeImm1_16(&ArgStr[3], &EvalResult);
  2667.   if (!EvalResult.OK)
  2668.     return;
  2669.  
  2670.   switch (DecodeAdr(&ArgStr[1], MModReg | MModIReg | MModDirect | MModIndexed, &RegAdrVals))
  2671.   {
  2672.     case eModReg:
  2673.       RegArgIndex = 1;
  2674.       if (!DecodeAdr(&ArgStr[2], MModIReg | MModDirect | MModIndexed, &MemAdrVals))
  2675.         return;
  2676.       goto common;
  2677.     case eModIReg:
  2678.     case eModDirect:
  2679.     case eModIndexed:
  2680.       MemAdrVals = RegAdrVals;
  2681.       Code |= 0x0008;
  2682.       if (!DecodeAdr(&ArgStr[2], MModReg, &RegAdrVals))
  2683.         return;
  2684.       RegArgIndex = 2;
  2685.       /* fall-thru */
  2686.     common:
  2687.       if (OpSize != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[RegArgIndex]);
  2688.       else
  2689.       {
  2690.         if (RegAdrVals.Val + Count >= 16) WrStrErrorPos(ErrNum_RegNumWraparound, &ArgStr[3]);
  2691.         switch (MemAdrVals.Mode)
  2692.         {
  2693.           case eModIReg:
  2694.             AppendCode(Code | (MemAdrVals.Val << 4));
  2695.             AppendCode((RegAdrVals.Val << 8) | Count);
  2696.             break;
  2697.           case eModDirect:
  2698.           case eModIndexed:
  2699.             AppendCode(Code | 0x4000 | (MemAdrVals.Val << 4));
  2700.             AppendCode((RegAdrVals.Val << 8) | Count);
  2701.             AppendAdrVals(&MemAdrVals);
  2702.             break;
  2703.           default:
  2704.             break;
  2705.         }
  2706.       }
  2707.       break;
  2708.     default:
  2709.       break;
  2710.   }
  2711. }
  2712.  
  2713. /*!------------------------------------------------------------------------
  2714.  * \fn     DecodeLDPS(Word Code)
  2715.  * \brief  decode LDPS instruction
  2716.  * \param  Code machine code
  2717.  * ------------------------------------------------------------------------ */
  2718.  
  2719. static void DecodeLDPS(Word Code)
  2720. {
  2721.   tAdrVals AdrVals;
  2722.  
  2723.   if (ChkArgCnt(1, 1)
  2724.    && CheckSup(True))
  2725.     switch (DecodeAdr(&ArgStr[1], MModIReg | MModDirect | MModIndexed, &AdrVals))
  2726.     {
  2727.       case eModIReg:
  2728.         AppendCode(Code | 0x0000 | (AdrVals.Val << 4));
  2729.         break;
  2730.       case eModDirect:
  2731.       case eModIndexed:
  2732.         AppendCode(Code | 0x4000 | (AdrVals.Val << 4));
  2733.         AppendAdrVals(&AdrVals);
  2734.         break;
  2735.       default:
  2736.         break;
  2737.     }
  2738. }
  2739.  
  2740. /*!------------------------------------------------------------------------
  2741.  * \fn     DecodeMREQ(Word Code)
  2742.  * \brief  decode MREQ instruction
  2743.  * \param  Code instruction code
  2744.  * ------------------------------------------------------------------------ */
  2745.  
  2746. static void DecodeMREQ(Word Code)
  2747. {
  2748.   tAdrVals AdrVals;
  2749.  
  2750.   SetOpSize(eSymbolSize16Bit, &OpPart);
  2751.   if (ChkArgCnt(1, 1)
  2752.    && CheckSup(True)
  2753.    && DecodeAdr(&ArgStr[1], MModReg, &AdrVals))
  2754.     AppendCode(Code | (AdrVals.Val << 4));
  2755. }
  2756.  
  2757. /*!------------------------------------------------------------------------
  2758.  * \fn     DecodePUSH_POP(Word Code)
  2759.  * \brief  decode PUSH(L)/POP(L)
  2760.  * \param  Code machine code & size
  2761.  * ------------------------------------------------------------------------ */
  2762.  
  2763. static void DecodePUSH_POP(Word Code)
  2764. {
  2765.   tAdrVals RegAdrVals;
  2766.   Word IsPOP = Code & 0x04;
  2767.   int OpArg = !IsPOP + 1, RegArg = 3 - OpArg;
  2768.  
  2769.   if (SetOpSizeFromCode(Code)
  2770.    && ChkArgCnt(2, 2)
  2771.    && DecodeAdr(&ArgStr[RegArg], MModIReg, &RegAdrVals))
  2772.   {
  2773.     tAdrVals OpAdrVals;
  2774.  
  2775.     ImmOpSize = (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize;
  2776.     if (DecodeAdr(&ArgStr[OpArg], MModReg | MModIReg | MModDirect | MModIndexed | (IsPOP ? 0 : MModImm), &OpAdrVals))
  2777.     {
  2778.       int Index;
  2779.  
  2780.       if (OpSize == eSymbolSizeUnknown)
  2781.         OpSize = eSymbolSize16Bit;
  2782.       if ((OpSize < eSymbolSize16Bit) || (OpSize > eSymbolSize32Bit))
  2783.       {
  2784.         WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[OpArg]);
  2785.         return;
  2786.       }
  2787.       switch (OpAdrVals.Mode)
  2788.       {
  2789.         case eModReg:
  2790.           Index = ChkRegOverlap((unsigned)OpAdrVals.Val, OpSize,
  2791.                                 (unsigned)RegAdrVals.Val, (int)AddrRegSize(),
  2792.                                 0, eSymbolSizeUnknown);
  2793.           break;
  2794.         case eModIReg:
  2795.           Index = ChkRegOverlap((unsigned)OpAdrVals.Val, AddrRegSize(),
  2796.                                 (unsigned)RegAdrVals.Val, (int)AddrRegSize(),
  2797.                                 0, eSymbolSizeUnknown);
  2798.           break;
  2799.         case eModIndexed:
  2800.           Index = ChkRegOverlap((unsigned)OpAdrVals.Val, eSymbolSize16Bit,
  2801.                                 (unsigned)RegAdrVals.Val, (int)AddrRegSize(),
  2802.                                 0, eSymbolSizeUnknown);
  2803.           break;
  2804.         default:
  2805.           Index = -1;
  2806.           break;
  2807.       }
  2808.       if (Index >= 0)
  2809.         WrStrErrorPos(ErrNum_OverlapReg, &ArgStr[Index ? RegArg : OpArg]);
  2810.       Code = Lo(Code) | ((OpSize == eSymbolSize16Bit) ? 2 : 0);
  2811.       switch (OpAdrVals.Mode)
  2812.       {
  2813.         case eModImm:
  2814.           if (OpSize != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &OpPart);
  2815.           else
  2816.           {
  2817.             AppendCode(0x0d09 | (RegAdrVals.Val << 4));
  2818.             AppendAdrVals(&OpAdrVals);
  2819.           }
  2820.           break;
  2821.         case eModReg:
  2822.           AppendCode(0x8000 | (Code << 8) | (RegAdrVals.Val << 4) | OpAdrVals.Val);
  2823.           break;
  2824.         case eModIReg:
  2825.           AppendCode(0x0000 | (Code << 8) | (RegAdrVals.Val << 4) | OpAdrVals.Val);
  2826.           break;
  2827.         case eModDirect:
  2828.         case eModIndexed:
  2829.           AppendCode(0x4000 | (Code << 8) | (RegAdrVals.Val << 4) | OpAdrVals.Val);
  2830.           AppendAdrVals(&OpAdrVals);
  2831.           break;
  2832.         default:
  2833.           break;
  2834.       }
  2835.     }
  2836.   }
  2837. }
  2838.  
  2839. /*!------------------------------------------------------------------------
  2840.  * \fn     DecodeRET(Word Code)
  2841.  * \brief  decode RET instruction
  2842.  * \param  Code machine code
  2843.  * ------------------------------------------------------------------------ */
  2844.  
  2845. static void DecodeRET(Word Code)
  2846. {
  2847.   Word Condition;
  2848.  
  2849.   if (ChkArgCnt(0, 1)
  2850.    && DecodeCondition((ArgCnt >= 1) ? &ArgStr[1] : NULL, &Condition))
  2851.     AppendCode(Code | Condition);
  2852. }
  2853.  
  2854. /*!------------------------------------------------------------------------
  2855.  * \fn     DecodeRotate(Word Code)
  2856.  * \brief  handle rotate instructions
  2857.  * \param  Code machine code
  2858.  * ------------------------------------------------------------------------ */
  2859.  
  2860. static void DecodeRotate(Word Code)
  2861. {
  2862.   tAdrVals RegAdrVals;
  2863.  
  2864.   if (ChkArgCnt(1, 2)
  2865.    && SetOpSizeFromCode(Code)
  2866.    && DecodeAdr(&ArgStr[1], MModReg, &RegAdrVals))
  2867.   {
  2868.     Word Count = 1;
  2869.     tEvalResult EvalResult;
  2870.  
  2871.     if (OpSize > eSymbolSize16Bit)
  2872.     {
  2873.       WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
  2874.       return;
  2875.     }
  2876.     if (ArgCnt >= 2)
  2877.     {
  2878.       Count = EvalStrIntExpressionOffsWithResult(&ArgStr[2], !!(*ArgStr[2].str.p_str == '#'), UInt2, &EvalResult);
  2879.       if (EvalResult.OK && mFirstPassUnknownOrQuestionable(EvalResult.Flags))
  2880.         Count = 1;
  2881.     }
  2882.     if (ChkRange(Count, 1, 2))
  2883.       AppendCode(0xb200 | (OpSize << 8) | (RegAdrVals.Val << 4) | Lo(Code) | ((Count - 1) << 1));
  2884.   }
  2885. }
  2886.  
  2887. /*!------------------------------------------------------------------------
  2888.  * \fn     DecodeRotateDigit(Word Code)
  2889.  * \brief  decode nibble-wide rotates
  2890.  * \param  Code machine code
  2891.  * ------------------------------------------------------------------------ */
  2892.  
  2893. static void DecodeRotateDigit(Word Code)
  2894. {
  2895.   tAdrVals LinkAdrVals, SrcAdrVals;
  2896.  
  2897.   SetOpSize(eSymbolSize8Bit, &OpPart);
  2898.   if (ChkArgCnt(2, 2)
  2899.    && DecodeAdr(&ArgStr[1], MModReg, &LinkAdrVals)
  2900.    && DecodeAdr(&ArgStr[2], MModReg, &SrcAdrVals))
  2901.     AppendCode(Code | (SrcAdrVals.Val << 4) | LinkAdrVals.Val);
  2902. }
  2903.  
  2904. /*!------------------------------------------------------------------------
  2905.  * \fn     DecodeSC(Word Code)
  2906.  * \brief  decode SC instruction
  2907.  * \param  Code machine code
  2908.  * ------------------------------------------------------------------------ */
  2909.  
  2910. static void DecodeSC(Word Code)
  2911. {
  2912.   if (ChkArgCnt(1, 1))
  2913.   {
  2914.     Boolean OK;
  2915.     Word Arg = EvalStrIntExpressionOffs(&ArgStr[1], !!(*ArgStr[1].str.p_str == '#'), Int8, &OK);
  2916.  
  2917.     if (OK)
  2918.       AppendCode(Code | (Arg & 0xff));
  2919.   }
  2920. }
  2921.  
  2922. /*!------------------------------------------------------------------------
  2923.  * \fn     DecodeSD(Word Code)
  2924.  * \brief  decode dynamic shifts
  2925.  * \param  Code machine code
  2926.  * ------------------------------------------------------------------------ */
  2927.  
  2928. static void DecodeSD(Word Code)
  2929. {
  2930.   tAdrVals DestAdrVals;
  2931.  
  2932.   if (ChkArgCnt(2, 2)
  2933.    && SetOpSizeFromCode(Code)
  2934.    && DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals))
  2935.   {
  2936.     tAdrVals SrcAdrVals;
  2937.     tSymbolSize SaveOpSize = (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize;
  2938.  
  2939.     if (SaveOpSize > eSymbolSize32Bit)
  2940.     {
  2941.       WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
  2942.       return;
  2943.     }
  2944.     OpSize = eSymbolSize16Bit;
  2945.     if (DecodeAdr(&ArgStr[2], MModReg, &SrcAdrVals))
  2946.     {
  2947.       AppendCode(0xb200 | (((SaveOpSize == eSymbolSize32Bit) ? 1 : SaveOpSize) << 8) | (DestAdrVals.Val << 4) | Lo(Code) | (SaveOpSize == eSymbolSize32Bit ? 4 : 0));
  2948.       AppendCode(SrcAdrVals.Val << 8);
  2949.     }
  2950.   }
  2951. }
  2952.  
  2953. /*!------------------------------------------------------------------------
  2954.  * \fn     DecodeShift(Word Code)
  2955.  * \brief  decode statuc shifts
  2956.  * \param  Code machine code
  2957.  * ------------------------------------------------------------------------ */
  2958.  
  2959. static void DecodeShift(Word Code)
  2960. {
  2961.   tAdrVals DestAdrVals;
  2962.  
  2963.   if (ChkArgCnt(1, 2)
  2964.    && SetOpSizeFromCode(Code)
  2965.    && DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals))
  2966.   {
  2967.     Word Count;
  2968.     Word Negate = Code & 0x80;
  2969.  
  2970.     if (OpSize == eSymbolSizeUnknown)
  2971.       OpSize = eSymbolSize16Bit;
  2972.     if (OpSize > eSymbolSize32Bit)
  2973.     {
  2974.       WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
  2975.       return;
  2976.     }
  2977.  
  2978.     if (ArgCnt >= 2)
  2979.     {
  2980.       tEvalResult EvalResult;
  2981.  
  2982.       Count = EvalStrIntExpressionOffsWithResult(&ArgStr[2], !!(*ArgStr[2].str.p_str == '#'), (OpSize == eSymbolSize32Bit) ? UInt6 : (OpSize == eSymbolSize16Bit) ? UInt5 : UInt4, &EvalResult);
  2983.       if (mFirstPassUnknownOrQuestionable(EvalResult.Flags))
  2984.         Count = 1;
  2985.       if (!ChkRange(Count, Negate ? 1 : 0, 8 << OpSize))
  2986.         return;
  2987.     }
  2988.     else
  2989.       Count = 1;
  2990.  
  2991.     if (Negate)
  2992.     {
  2993.       Code ^= Negate;
  2994.       Count = 0x10000ul - Count;
  2995.       if (OpSize == eSymbolSize8Bit)
  2996.         Count &= 0xff;
  2997.     }
  2998.     AppendCode(0xb200 | (((OpSize == eSymbolSize32Bit) ? 1 : OpSize) << 8) | (DestAdrVals.Val << 4) | Lo(Code) | (OpSize == eSymbolSize32Bit ? 4 : 0));
  2999.     AppendCode(Count);
  3000.   }
  3001. }
  3002.  
  3003. /*!------------------------------------------------------------------------
  3004.  * \fn     DecodeTCC(Word Code)
  3005.  * \brief  decode TCC instruction
  3006.  * \param  Code machine code
  3007.  * ------------------------------------------------------------------------ */
  3008.  
  3009. static void DecodeTCC(Word Code)
  3010. {
  3011.   Word Condition;
  3012.   tAdrVals DestAdrVals;
  3013.  
  3014.   if (ChkArgCnt(1, 2)
  3015.    && SetOpSizeFromCode(Code)
  3016.    && DecodeCondition((ArgCnt == 2) ? &ArgStr[1] : NULL, &Condition)
  3017.    && DecodeAdr(&ArgStr[ArgCnt], MModReg, &DestAdrVals))
  3018.   {
  3019.     if (OpSize > eSymbolSize16Bit)
  3020.     {
  3021.       WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[2]);
  3022.       return;
  3023.     }
  3024.     AppendCode(0xae00 | (OpSize << 8) | (DestAdrVals.Val << 4) | Condition);
  3025.   }
  3026. }
  3027.  
  3028. /*!------------------------------------------------------------------------
  3029.  * \fn     DecodePORT(Word Code)
  3030.  * \brief  decode PORT instruction
  3031.  * ------------------------------------------------------------------------ */
  3032.  
  3033. static void DecodePORT(Word Code)
  3034. {
  3035.   UNUSED(Code);
  3036.   CodeEquate(SegIO, 0, SegLimits[SegIO]);
  3037. }
  3038.  
  3039. /*!------------------------------------------------------------------------
  3040.  * \fn     DecodeDEFBIT(Word Code)
  3041.  * \brief  decode DEFBIT(B) instructions
  3042.  * \param  Code machine code
  3043.  * ------------------------------------------------------------------------ */
  3044.  
  3045. static void DecodeDEFBIT(Word Code)
  3046. {
  3047.   LongWord BitSpec;
  3048.  
  3049.   OpSize = (tSymbolSize)Code;
  3050.  
  3051.   /* if in structure definition, add special element to structure */
  3052.  
  3053.   if (ActPC == StructSeg)
  3054.   {
  3055.     Boolean OK;
  3056.     Byte BitPos;
  3057.     PStructElem pElement;
  3058.  
  3059.     if (!ChkArgCnt(2, 2))
  3060.       return;
  3061.     BitPos = EvalBitPosition(&ArgStr[2], &OK, OpSize);
  3062.     if (!OK)
  3063.       return;
  3064.     pElement = CreateStructElem(&LabPart);
  3065.     if (!pElement)
  3066.       return;
  3067.     pElement->pRefElemName = as_strdup(ArgStr[1].str.p_str);
  3068.     pElement->OpSize = OpSize;
  3069.     pElement->BitPos = BitPos;
  3070.     pElement->ExpandFnc = ExpandZ8000Bit;
  3071.     AddStructElem(pInnermostNamedStruct->StructRec, pElement);
  3072.   }
  3073.   else
  3074.   {
  3075.     if (DecodeBitArg(&BitSpec, 1, ArgCnt, OpSize))
  3076.     {
  3077.       *ListLine = '=';
  3078.       DissectBit_Z8000(ListLine + 1, STRINGSIZE - 3, BitSpec);
  3079.       PushLocHandle(-1);
  3080.       EnterIntSymbol(&LabPart, BitSpec, SegBData, False);
  3081.       PopLocHandle();
  3082.       /* TODO: MakeUseList? */
  3083.     }
  3084.   }
  3085. }
  3086.  
  3087. /*--------------------------------------------------------------------------*/
  3088. /* Instruction Table Buildup/Teardown */
  3089.  
  3090. /*!------------------------------------------------------------------------
  3091.  * \fn     InitFields(void)
  3092.  * \brief  Set up hash table
  3093.  * ------------------------------------------------------------------------ */
  3094.  
  3095. static void AddFixed(const char *NName, Word Code, Boolean Privileged)
  3096. {
  3097.   order_array_rsv_end(FixedOrders, FixedOrder);
  3098.   FixedOrders[InstrZ].Code = Code;
  3099.   FixedOrders[InstrZ].Privileged = Privileged;
  3100.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
  3101. }
  3102.  
  3103. static void AddCtl(const char *pName, Word Code, tCtlFlags Flags, tSymbolSize Size)
  3104. {
  3105.   order_array_rsv_end(CtlRegs, tCtlReg);
  3106.   CtlRegs[InstrZ  ].pName = pName;
  3107.   CtlRegs[InstrZ  ].Code  = Code;
  3108.   CtlRegs[InstrZ  ].Flags = Flags;
  3109.   CtlRegs[InstrZ++].Size  = Size;
  3110. }
  3111.  
  3112. static void AddCondition(const char *pName, Word Code)
  3113. {
  3114.   order_array_rsv_end(Conditions, tCondition);
  3115.   Conditions[InstrZ].pName = pName;
  3116.   Conditions[InstrZ++].Code = Code;
  3117. }
  3118.  
  3119. static void AddSizeInstTable(const char *pName, unsigned SizeMask, Word Code, InstProc Proc)
  3120. {
  3121.   char Name[20];
  3122.  
  3123.   AddInstTable(InstTable, pName, Code | 0xff00, Proc);
  3124.   if (SizeMask & (1 << eSymbolSize8Bit))
  3125.   {
  3126.     as_snprintf(Name, sizeof(Name), "%sB", pName);
  3127.     AddInstTable(InstTable, Name, Code | (eSymbolSize8Bit << 8), Proc);
  3128.   }
  3129.   if (SizeMask & (1 << eSymbolSize32Bit))
  3130.   {
  3131.     as_snprintf(Name, sizeof(Name), "%sL", pName);
  3132.     AddInstTable(InstTable, Name, Code | (eSymbolSize32Bit << 8), Proc);
  3133.   }
  3134. }
  3135.  
  3136. static void InitFields(void)
  3137. {
  3138.   InstTable = CreateInstTable(201);
  3139.   SetDynamicInstTable(InstTable);
  3140.  
  3141.   InstrZ = 0;
  3142.   AddFixed("HALT" , 0x7a00 , True );
  3143.   AddFixed("IRET" , 0x7b00 , True );
  3144.   AddFixed("MBIT" , 0x7b0a , True );
  3145.   AddFixed("MRES" , 0x7b09 , True );
  3146.   AddFixed("MSET" , 0x7b08 , True );
  3147.   AddFixed("NOP"  , NOPCode, False);
  3148.  
  3149.   InstrZ = 0;
  3150.   AddCtl("FCW"     , 2, ePrivileged | eSegMode | eNonSegMode , eSymbolSize16Bit);
  3151.   AddCtl("REFRESH" , 3, ePrivileged | eSegMode | eNonSegMode , eSymbolSize16Bit);
  3152.   AddCtl("PSAPSEG" , 4, ePrivileged | eSegMode               , eSymbolSize16Bit);
  3153.   AddCtl("PSAPOFF" , 5, ePrivileged | eSegMode | eNonSegMode , eSymbolSize16Bit);
  3154.   AddCtl("PSAP"    , 5, ePrivileged            | eNonSegMode , eSymbolSize16Bit);
  3155.   AddCtl("NSPSEG"  , 6, ePrivileged | eSegMode               , eSymbolSize16Bit);
  3156.   AddCtl("NSPOFF"  , 7, ePrivileged | eSegMode | eNonSegMode , eSymbolSize16Bit);
  3157.   AddCtl("NSP"     , 7, ePrivileged            | eNonSegMode , eSymbolSize16Bit);
  3158.   AddCtl("FLAGS"   , 1,               eSegMode | eNonSegMode , eSymbolSize8Bit );
  3159.   CtlRegCnt = InstrZ;
  3160.  
  3161.   InstrZ = 0;
  3162.   AddCondition(""   , 0x08);
  3163.   AddCondition("F"  , 0x00);
  3164.   AddCondition("LT" , 0x01);
  3165.   AddCondition("LE" , 0x02);
  3166.   AddCondition("ULE", 0x03);
  3167.   AddCondition("PE" , 0x04);
  3168.   AddCondition("MI" , 0x05);
  3169.   AddCondition("Z"  , 0x06);
  3170.   AddCondition("ULT", 0x07);
  3171.   AddCondition("GE" , 0x09);
  3172.   AddCondition("GT" , 0x0a);
  3173.   AddCondition("UGT", 0x0b);
  3174.   AddCondition("PO" , 0x0c);
  3175.   AddCondition("PL" , 0x0d);
  3176.   AddCondition("NZ" , 0x0e);
  3177.   AddCondition("UGE", 0x0f);
  3178.   AddCondition("OV" , 0x04);
  3179.   AddCondition("EQ" , 0x06);
  3180.   AddCondition("C"  , 0x07);
  3181.   AddCondition("NOV", 0x0c);
  3182.   AddCondition("NE" , 0x0e);
  3183.   AddCondition("NC" , 0x0f);
  3184.  
  3185.   /* non-Zilog conditions */
  3186.  
  3187.   AddCondition("ZR" , 0x06);
  3188.   AddCondition("CY" , 0x07);
  3189.   AddCondition("LLE", 0x03);
  3190.   AddCondition("LLT", 0x07);
  3191.   AddCondition("LGT", 0x0b);
  3192.   AddCondition("LGE", 0x0f);
  3193.   AddCondition(NULL , 0);
  3194.  
  3195.  
  3196.   AddSizeInstTable("LD"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0, DecodeLD);
  3197.   AddInstTable(InstTable, "LDA" , 0, DecodeLDA);
  3198.   AddInstTable(InstTable, "LDAR", 0x3400, DecodeLDAR);
  3199.   AddInstTable(InstTable, "LDK" , 0xbd00, DecodeLDK);
  3200.   AddInstTable(InstTable, "LDM" , 0x1c01, DecodeLDM);
  3201.   AddInstTable(InstTable, "LDPS", 0x3900, DecodeLDPS);
  3202.   AddSizeInstTable("LDR", (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0x30, DecodeLDR);
  3203.   AddSizeInstTable("LDCTL", 1 << eSymbolSize8Bit, 0x00, DecodeLDCTL);
  3204.   AddSizeInstTable("ADD" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0, DecodeADD);
  3205.   AddSizeInstTable("SUB" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0, DecodeSUB);
  3206.   AddSizeInstTable("CP"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0, DecodeCP);
  3207.   AddSizeInstTable("ADC" , 1 << eSymbolSize8Bit, 0x34, DecodeADC_SBC);
  3208.   AddSizeInstTable("SBC" , 1 << eSymbolSize8Bit, 0x36, DecodeADC_SBC);
  3209.   AddSizeInstTable("AND" , 1 << eSymbolSize8Bit, 0x06, DecodeAND_OR_XOR);
  3210.   AddSizeInstTable("OR"  , 1 << eSymbolSize8Bit, 0x04, DecodeAND_OR_XOR);
  3211.   AddSizeInstTable("XOR" , 1 << eSymbolSize8Bit, 0x08, DecodeAND_OR_XOR);
  3212.   AddSizeInstTable("INC" , 1 << eSymbolSize8Bit, 0x28, DecodeINC_DEC);
  3213.   AddSizeInstTable("DEC" , 1 << eSymbolSize8Bit, 0x2a, DecodeINC_DEC);
  3214.   AddSizeInstTable("BIT" , 1 << eSymbolSize8Bit, 0x26, DecodeBitOp);
  3215.   AddSizeInstTable("DIV" , 1 << eSymbolSize32Bit, 0x1a, DecodeMULT_DIV);
  3216.   AddSizeInstTable("MULT", 1 << eSymbolSize32Bit, 0x18, DecodeMULT_DIV);
  3217.   AddSizeInstTable("RES" , 1 << eSymbolSize8Bit, 0x22, DecodeBitOp);
  3218.   AddSizeInstTable("SET" , 1 << eSymbolSize8Bit, 0x24, DecodeBitOp);
  3219.   AddInstTable(InstTable, "CALL", 0x1f, DecodeCALL_JP);
  3220.   AddInstTable(InstTable, "JP"  , 0x1e, DecodeCALL_JP);
  3221.   AddInstTable(InstTable, "CALR", 0xd000, DecodeCALR);
  3222.   AddInstTable(InstTable, "JR"  , 0xe000, DecodeJR);
  3223.   AddInstTable(InstTable, "DJNZ" , 0xff00, DecodeDJNZ);
  3224.   AddInstTable(InstTable, "DBJNZ", eSymbolSize8Bit << 8, DecodeDJNZ);
  3225.   AddInstTable(InstTable, "RET", 0x9e00, DecodeRET);
  3226.   AddSizeInstTable("CLR" , 1 << eSymbolSize8Bit, 0x8c, DecodeCLR_COM_NEG_TSET);
  3227.   AddSizeInstTable("COM" , 1 << eSymbolSize8Bit, 0x0c, DecodeCLR_COM_NEG_TSET);
  3228.   AddSizeInstTable("NEG" , 1 << eSymbolSize8Bit, 0x2c, DecodeCLR_COM_NEG_TSET);
  3229.   AddSizeInstTable("TSET", 1 << eSymbolSize8Bit, 0x6c, DecodeCLR_COM_NEG_TSET);
  3230.   AddSizeInstTable("TEST", (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0x0c, DecodeTEST);
  3231.   AddSizeInstTable("EX", 1 << eSymbolSize8Bit, 0x2c, DecodeEX);
  3232.   AddSizeInstTable("EXTS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0x31, DecodeEXTS);
  3233.   AddInstTable(InstTable, "DAB", 0xb000, DecodeDAB);
  3234.   AddInstTable(InstTable, "COMFLG", 0x8d05, DecodeFLG);
  3235.   AddInstTable(InstTable, "SETFLG", 0x8d01, DecodeFLG);
  3236.   AddInstTable(InstTable, "RESFLG", 0x8d03, DecodeFLG);
  3237.   AddInstTable(InstTable, "DI", 0x7c00, DecodeDI_EI);
  3238.   AddInstTable(InstTable, "EI", 0x7c04, DecodeDI_EI);
  3239.   AddInstTable(InstTable, "MREQ", 0x7b0d, DecodeMREQ);
  3240.   AddSizeInstTable("IN"  , 1 << eSymbolSize8Bit, 0x00, DecodeIN_SIN_OUT_SOUT);
  3241.   AddSizeInstTable("SIN" , 1 << eSymbolSize8Bit, 0x01, DecodeIN_SIN_OUT_SOUT);
  3242.   AddSizeInstTable("OUT" , 1 << eSymbolSize8Bit, 0x02, DecodeIN_SIN_OUT_SOUT);
  3243.   AddSizeInstTable("SOUT", 1 << eSymbolSize8Bit, 0x03, DecodeIN_SIN_OUT_SOUT);
  3244.   AddSizeInstTable("CPD"  , 1 << eSymbolSize8Bit, 0x08, DecodeCPRep);
  3245.   AddSizeInstTable("CPDR" , 1 << eSymbolSize8Bit, 0x0c, DecodeCPRep);
  3246.   AddSizeInstTable("CPI"  , 1 << eSymbolSize8Bit, 0x00, DecodeCPRep);
  3247.   AddSizeInstTable("CPIR" , 1 << eSymbolSize8Bit, 0x04, DecodeCPRep);
  3248.   AddSizeInstTable("CPSD" , 1 << eSymbolSize8Bit, 0x0a, DecodeCPRep);
  3249.   AddSizeInstTable("CPSDR", 1 << eSymbolSize8Bit, 0x0e, DecodeCPRep);
  3250.   AddSizeInstTable("CPSI" , 1 << eSymbolSize8Bit, 0x02, DecodeCPRep);
  3251.   AddSizeInstTable("CPSIR", 1 << eSymbolSize8Bit, 0x06, DecodeCPRep);
  3252.   AddSizeInstTable("IND"  , 1 << eSymbolSize8Bit, 0x88, DecodeINOUTRep);
  3253.   AddSizeInstTable("INDR" , 1 << eSymbolSize8Bit, 0x80, DecodeINOUTRep);
  3254.   AddSizeInstTable("SIND" , 1 << eSymbolSize8Bit, 0x98, DecodeINOUTRep);
  3255.   AddSizeInstTable("SINDR", 1 << eSymbolSize8Bit, 0x90, DecodeINOUTRep);
  3256.   AddSizeInstTable("INI"  , 1 << eSymbolSize8Bit, 0x08, DecodeINOUTRep);
  3257.   AddSizeInstTable("INIR" , 1 << eSymbolSize8Bit, 0x00, DecodeINOUTRep);
  3258.   AddSizeInstTable("SINI" , 1 << eSymbolSize8Bit, 0x18, DecodeINOUTRep);
  3259.   AddSizeInstTable("SINIR", 1 << eSymbolSize8Bit, 0x10, DecodeINOUTRep);
  3260.   AddSizeInstTable("OUTD" , 1 << eSymbolSize8Bit, 0xa8, DecodeINOUTRep);
  3261.   AddSizeInstTable("OTDR" , 1 << eSymbolSize8Bit, 0xa0, DecodeINOUTRep);
  3262.   AddSizeInstTable("SOUTD", 1 << eSymbolSize8Bit, 0xb8, DecodeINOUTRep);
  3263.   AddSizeInstTable("SOTDR", 1 << eSymbolSize8Bit, 0xb0, DecodeINOUTRep);
  3264.   AddSizeInstTable("OUTI" , 1 << eSymbolSize8Bit, 0x28, DecodeINOUTRep);
  3265.   AddSizeInstTable("OTIR" , 1 << eSymbolSize8Bit, 0x20, DecodeINOUTRep);
  3266.   AddSizeInstTable("SOUTI", 1 << eSymbolSize8Bit, 0x38, DecodeINOUTRep);
  3267.   AddSizeInstTable("SOTIR", 1 << eSymbolSize8Bit, 0x30, DecodeINOUTRep);
  3268.   AddSizeInstTable("LDD"  , 1 << eSymbolSize8Bit, 0x98, DecodeLDRep);
  3269.   AddSizeInstTable("LDDR" , 1 << eSymbolSize8Bit, 0x90, DecodeLDRep);
  3270.   AddSizeInstTable("LDI"  , 1 << eSymbolSize8Bit, 0x18, DecodeLDRep);
  3271.   AddSizeInstTable("LDIR" , 1 << eSymbolSize8Bit, 0x10, DecodeLDRep);
  3272.   AddInstTable(InstTable, "TRDB"  , 0x80, DecodeTRRep);
  3273.   AddInstTable(InstTable, "TRDRB" , 0xc0, DecodeTRRep);
  3274.   AddInstTable(InstTable, "TRIB"  , 0x00, DecodeTRRep);
  3275.   AddInstTable(InstTable, "TRIRB" , 0x40, DecodeTRRep);
  3276.   AddInstTable(InstTable, "TRTDB" , 0xa0, DecodeTRRep);
  3277.   AddInstTable(InstTable, "TRTDRB", 0xee, DecodeTRRep);
  3278.   AddInstTable(InstTable, "TRTIB" , 0x20, DecodeTRRep);
  3279.   AddInstTable(InstTable, "TRTIRB", 0x6e, DecodeTRRep);
  3280.   AddSizeInstTable("POP"  , 1 << eSymbolSize32Bit, 0x15, DecodePUSH_POP);
  3281.   AddSizeInstTable("PUSH" , 1 << eSymbolSize32Bit, 0x11, DecodePUSH_POP);
  3282.   AddSizeInstTable("RL"   , 1 << eSymbolSize8Bit, 0x00, DecodeRotate);
  3283.   AddSizeInstTable("RLC"  , 1 << eSymbolSize8Bit, 0x08, DecodeRotate);
  3284.   AddSizeInstTable("RR"   , 1 << eSymbolSize8Bit, 0x04, DecodeRotate);
  3285.   AddSizeInstTable("RRC"  , 1 << eSymbolSize8Bit, 0x0c, DecodeRotate);
  3286.   AddInstTable(InstTable, "RLDB" , 0xbe00, DecodeRotateDigit);
  3287.   AddInstTable(InstTable, "RRDB" , 0xbc00, DecodeRotateDigit);
  3288.   AddSizeInstTable("SDA", (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0x0b, DecodeSD);
  3289.   AddSizeInstTable("SDL", (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0x03, DecodeSD);
  3290.   AddSizeInstTable("SLA", (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0x09, DecodeShift);
  3291.   AddSizeInstTable("SLL", (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0x01, DecodeShift);
  3292.   AddSizeInstTable("SRA", (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0x89, DecodeShift);
  3293.   AddSizeInstTable("SRL", (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0x81, DecodeShift);
  3294.   AddInstTable(InstTable, "SC", 0x7f00, DecodeSC);
  3295.   AddSizeInstTable("TCC", 1 << eSymbolSize8Bit, 0x00, DecodeTCC);
  3296.  
  3297.   AddInstTable(InstTable, "PORT", 0, DecodePORT);
  3298.   AddInstTable(InstTable, "REG" , 0, CodeREG);
  3299.   AddInstTable(InstTable, "DEFBIT" , eSymbolSize16Bit, DecodeDEFBIT);
  3300.   AddInstTable(InstTable, "DEFBITB", eSymbolSize8Bit , DecodeDEFBIT);
  3301. }
  3302.  
  3303. /*!------------------------------------------------------------------------
  3304.  * \fn     DeinitFields(void)
  3305.  * \brief  Tear down hash table
  3306.  * ------------------------------------------------------------------------ */
  3307.  
  3308. static void DeinitFields(void)
  3309. {
  3310.   order_array_free(CtlRegs);
  3311.   order_array_free(FixedOrders);
  3312.   order_array_free(Conditions);
  3313.  
  3314.   DestroyInstTable(InstTable);
  3315. }
  3316.  
  3317. /*---------------------------------------------------------------------*/
  3318.  
  3319. /*!------------------------------------------------------------------------
  3320.  * \fn     MakeCode_Z8000(void)
  3321.  * \brief  encode machine instruction
  3322.  * ------------------------------------------------------------------------ */
  3323.  
  3324. static void MakeCode_Z8000(void)
  3325. {
  3326.   CodeLen = 0; DontPrint = False;
  3327.   ImmOpSize = OpSize = eSymbolSizeUnknown;
  3328.  
  3329.   /* to be ignored */
  3330.  
  3331.   if (Memo("")) return;
  3332.  
  3333.   /* Pseudo Instructions */
  3334.  
  3335.   if (DecodeIntelPseudo(True))
  3336.     return;
  3337.  
  3338.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  3339.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  3340. }
  3341.  
  3342. /*!------------------------------------------------------------------------
  3343.  * \fn     InternSymbol_Z8000(char *pArg, TempResult *pResult)
  3344.  * \brief  handle built-in symbols on Z8000
  3345.  * \param  pArg source argument
  3346.  * \param  pResult result buffer
  3347.  * ------------------------------------------------------------------------ */
  3348.  
  3349. static void InternSymbol_Z8000(char *pArg, TempResult *pResult)
  3350. {
  3351.   Word Reg;
  3352.   tSymbolSize Size;
  3353.  
  3354.   if (DecodeRegCore(pArg, &Reg, &Size))
  3355.   {
  3356.     pResult->Typ = TempReg;
  3357.     pResult->DataSize = Size;
  3358.     pResult->Contents.RegDescr.Reg = Reg;
  3359.     pResult->Contents.RegDescr.Dissect = DissectReg_Z8000;
  3360.     pResult->Contents.RegDescr.compare = NULL;
  3361.   }
  3362. }
  3363.  
  3364. /*!------------------------------------------------------------------------
  3365.  * \fn     IsDef_Z8000(void)
  3366.  * \brief  check whether insn makes own use of label
  3367.  * \return True if yes
  3368.  * ------------------------------------------------------------------------ */
  3369.  
  3370. static Boolean IsDef_Z8000(void)
  3371. {
  3372.   return Memo("REG")
  3373.       || Memo("PORT")
  3374.       || Memo("DEFBIT")
  3375.       || Memo("DEFBITB");
  3376. }
  3377.  
  3378. /*!------------------------------------------------------------------------
  3379.  * \fn     PotOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
  3380.  * \brief  special ^ operator for AMD syntax
  3381.  * \param  pErg operator result
  3382.  * \param  pRVal input argument
  3383.  * ------------------------------------------------------------------------ */
  3384.  
  3385. static void PotOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
  3386. {
  3387.   UNUSED(pLVal);
  3388.  
  3389.   /* If in front of a label, takes the address as an 'untyped' value.  This
  3390.      will instruct the address decode to use immediate instead of direct
  3391.      addressing: */
  3392.  
  3393.   if (pRVal->AddrSpaceMask)
  3394.     pErg->AddrSpaceMask = 0;
  3395.  
  3396.   /* Vice-versa, for a constant, this makes an address of it: */
  3397.  
  3398.   else
  3399.     pErg->AddrSpaceMask |= (1 << SegCode);
  3400.  
  3401.   /* clone remainder as-is */
  3402.  
  3403.   pErg->Typ = pRVal->Typ;
  3404.   pErg->Contents = pRVal->Contents;
  3405.   pErg->Flags |= (pLVal->Flags & eSymbolFlags_Promotable);
  3406.   if (pErg->DataSize == eSymbolSizeUnknown) pErg->DataSize = pLVal->DataSize;
  3407. }
  3408.  
  3409. static const Operator PotMonadicOperator =
  3410. {
  3411.   "^" ,1 , False, 8, { TempInt | (TempInt << 4), 0, 0, 0 }, PotOp
  3412. };
  3413.  
  3414. /*!------------------------------------------------------------------------
  3415.  * \fn     SwitchTo_Z8000(void *pUser)
  3416.  * \brief  prepare to assemble code for this target
  3417.  * \param  pUser CPU properties
  3418.  * ------------------------------------------------------------------------ */
  3419.  
  3420. static Boolean TrueFnc(void)
  3421. {
  3422.   return True;
  3423. }
  3424.  
  3425. static void SwitchTo_Z8000(void *pUser)
  3426. {
  3427.   const TFamilyDescr *pDescr = FindFamilyByName("Z8000");
  3428.  
  3429.   TurnWords = True;
  3430.   SetIntConstMode(eIntConstModeIntel);
  3431.  
  3432.   pCurrCPUProps = (const tCPUProps*)pUser;
  3433.  
  3434.   PCSymbol = "$"; HeaderID = pDescr->Id;
  3435.   NOPCode = 0x8d07;
  3436.   DivideChars = ","; HasAttrs = False;
  3437.  
  3438.   ValidSegs = (1 << SegCode) | (1 << SegIO);
  3439.   Grans[SegCode] = 1; ListGrans[SegCode] = 2; SegInits[SegCode] = 0;
  3440.   SegLimits[SegCode] = pCurrCPUProps->SuppSegmented ? 0x7fffff : 0xffff;
  3441.   Grans[SegIO] = 1; ListGrans[SegIO] = 1; SegInits[SegIO] = 0;
  3442.   SegLimits[SegIO] = 0xffff;
  3443.   MemIntType = Segmented() ? UInt23 : UInt16;
  3444.  
  3445.   MakeCode = MakeCode_Z8000;
  3446.   IsDef = IsDef_Z8000;
  3447.   DissectReg = DissectReg_Z8000;
  3448.   DissectBit = DissectBit_Z8000;
  3449.   InternSymbol = InternSymbol_Z8000;
  3450.   SwitchFrom = DeinitFields;
  3451.   InitFields();
  3452.   SetIsOccupiedFnc = TrueFnc;
  3453.   if (AMDSyntax)
  3454.     pPotMonadicOperator = &PotMonadicOperator;
  3455.   onoff_supmode_add();
  3456. }
  3457.  
  3458. /*!------------------------------------------------------------------------
  3459.  * \fn     codez8000_init(void)
  3460.  * \brief  register target to AS
  3461.  * ------------------------------------------------------------------------ */
  3462.  
  3463. static const tCPUProps CPUProps[] =
  3464. {
  3465.   { "Z8001" , eCoreZ8001   , True  },
  3466.   { "Z8002" , eCoreZ8001   , False },
  3467.   { "Z8003" , eCoreZ8003   , True  },
  3468.   { "Z8004" , eCoreZ8003   , False },
  3469.   { NULL    , eCoreNone    , False }
  3470. };
  3471.  
  3472. void codez8000_init(void)
  3473. {
  3474.   const tCPUProps *pRun;
  3475.   static const tCPUArg Z8000Args[] =
  3476.   {
  3477.     { "AMDSYNTAX", 0, 1, 0, &AMDSyntax },
  3478.     { NULL       , 0, 0, 0, NULL       }
  3479.   };
  3480.  
  3481.   for (pRun = CPUProps; pRun->pName; pRun++)
  3482.     (void)AddCPUUserWithArgs(pRun->pName, SwitchTo_Z8000, (void*)pRun, NULL, Z8000Args);
  3483. }
  3484.