Subversion Repositories pentevo

Rev

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

  1. /* codexa.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* AS-Codegenerator Philips XA                                               */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "nls.h"
  16. #include "strutil.h"
  17. #include "bpemu.h"
  18. #include "asmdef.h"
  19. #include "asmsub.h"
  20. #include "asmpars.h"
  21. #include "asmallg.h"
  22. #include "onoff_common.h"
  23. #include "asmitree.h"
  24. #include "asmcode.h"
  25. #include "codepseudo.h"
  26. #include "intpseudo.h"
  27. #include "motpseudo.h"
  28. #include "codevars.h"
  29. #include "errmsg.h"
  30.  
  31. #include "codexa.h"
  32.  
  33. /*-------------------------------------------------------------------------*/
  34. /* Definitionen */
  35.  
  36. #define ModNone (-1)
  37. #define ModReg 0
  38. #define MModReg (1 << ModReg)
  39. #define ModMem 1
  40. #define MModMem (1 << ModMem)
  41. #define ModImm 2
  42. #define MModImm (1 << ModImm)
  43. #define ModAbs 3
  44. #define MModAbs (1 << ModAbs)
  45.  
  46. #define REG_SP 7
  47.  
  48. #define RETICode 0xd690
  49.  
  50. #define eSymbolSize5Bit ((tSymbolSize)-4)
  51. #define eSymbolSizeSigned4Bit ((tSymbolSize)-3)
  52. #define eSymbolSize4Bit ((tSymbolSize)-2)
  53.  
  54. typedef struct
  55. {
  56.   Byte SizeMask;
  57.   Byte Code;
  58. } RegOrder;
  59.  
  60. typedef struct
  61. {
  62.   const char *Name;
  63.   Byte SizeMask;
  64.   Byte Code;
  65.   Byte Inversion;
  66. } InvOrder;
  67.  
  68. static CPUVar CPUXAG1,CPUXAG2,CPUXAG3;
  69.  
  70. static InvOrder *JBitOrders;
  71. static RegOrder *RegOrders;
  72. static InvOrder *RelOrders;
  73.  
  74. static LongInt Reg_DS;
  75.  
  76. static ShortInt AdrMode;
  77. static Byte AdrPart,MemPart;
  78. static Byte AdrVals[4];
  79. static tSymbolSize OpSize;
  80. static Boolean DoBranchExt; /* automatically extend branches */
  81.  
  82. #define ASSUMEXACount 1
  83. static ASSUMERec ASSUMEXAs[ASSUMEXACount] =
  84. {
  85.   {"DS", &Reg_DS, 0, 0xff, 0x100, NULL}
  86. };
  87.  
  88. /*-------------------------------------------------------------------------*/
  89. /* Hilfsroutinen */
  90.  
  91. static void SetOpSize(tSymbolSize NSize)
  92. {
  93.   if (OpSize == eSymbolSizeUnknown) OpSize = NSize;
  94.   else if (OpSize != NSize)
  95.   {
  96.     AdrMode = ModNone; AdrCnt = 0; WrError(ErrNum_ConfOpSizes);
  97.   }
  98. }
  99.  
  100. /*!------------------------------------------------------------------------
  101.  * \fn     DecodeRegCore(const char *pArg, tSymbolSize *pSize, Byte *pResult)
  102.  * \brief  check whether argument is a CPU register
  103.  * \param  pArg source argument
  104.  * \param  pSize register size if yes
  105.  * \param  pResult register number if yes
  106.  * \return Reg eval result
  107.  * ------------------------------------------------------------------------ */
  108.  
  109. static tRegEvalResult DecodeRegCore(const char *pArg, tSymbolSize *pSize, Byte *pResult)
  110. {
  111.   int len;
  112.  
  113.   if (!as_strcasecmp(pArg, "SP"))
  114.   {
  115.     *pResult = REG_SP | REGSYM_FLAG_ALIAS;
  116.     *pSize = eSymbolSize16Bit;
  117.     return eIsReg;
  118.   }
  119.  
  120.   len = strlen(pArg);
  121.   if ((len >= 2) && (as_toupper(*pArg) == 'R') && (pArg[1] >= '0') && (pArg[1] <= '7'))
  122.   {
  123.     *pResult = pArg[1] - '0';
  124.     if (len == 2)
  125.     {
  126.       if (OpSize == eSymbolSize32Bit)
  127.       {
  128.         *pSize = eSymbolSize32Bit;
  129.         if (*pResult & 1)
  130.         {
  131.           WrError(ErrNum_InvRegPair);
  132.           (*pResult)--;
  133.           return eRegAbort;
  134.         }
  135.         else
  136.           return eIsReg;
  137.       }
  138.       else
  139.       {
  140.         *pSize = eSymbolSize16Bit;
  141.         return eIsReg;
  142.       }
  143.     }
  144.     else if ((len == 3) && (as_toupper(pArg[2]) == 'L'))
  145.     {
  146.       *pResult <<= 1;
  147.       *pSize = eSymbolSize8Bit;
  148.       return eIsReg;
  149.     }
  150.     else if ((len == 3) && (as_toupper(pArg[2]) == 'H'))
  151.     {
  152.       *pResult = (*pResult << 1) + 1;
  153.       *pSize = eSymbolSize8Bit;
  154.       return eIsReg;
  155.     }
  156.     else
  157.       return eIsNoReg;
  158.   }
  159.   return eIsNoReg;
  160. }
  161.  
  162. /*!------------------------------------------------------------------------
  163.  * \fn     DissectReg_XA(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  164.  * \brief  dissect register symbols - XA variant
  165.  * \param  pDest destination buffer
  166.  * \param  DestSize destination buffer size
  167.  * \param  Value numeric register value
  168.  * \param  InpSize register size
  169.  * ------------------------------------------------------------------------ */
  170.  
  171. static void DissectReg_XA(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  172. {
  173.   switch (InpSize)
  174.   {
  175.     case eSymbolSize8Bit:
  176.       as_snprintf(pDest, DestSize, "R%u%c", (unsigned)(Value >> 1), "LH"[Value & 1]);
  177.       break;
  178.     case eSymbolSize16Bit:
  179.       as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
  180.       break;
  181.     case eSymbolSize32Bit:
  182.       as_snprintf(pDest, DestSize, "R%u.D", (unsigned)Value);
  183.       break;
  184.     default:
  185.       as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
  186.   }
  187. }
  188.  
  189.  
  190. /*!------------------------------------------------------------------------
  191.  * \fn     DecodeReg(const tStrComp *pArg, tSymbolSize *pSize, Byte *pResult, Boolean MustBeReg)
  192.  * \brief  check whether argument is a CPU register or register alias
  193.  * \param  pArg source argument
  194.  * \param  pSize register size if yes
  195.  * \param  pResult register number if yes
  196.  * \param  MustBeReg expecting register?
  197.  * \return Reg eval result
  198.  * ------------------------------------------------------------------------ */
  199.  
  200. static tRegEvalResult DecodeReg(const tStrComp *pArg, tSymbolSize *pSize, Byte *pResult, Boolean MustBeReg)
  201. {
  202.   tRegDescr RegDescr;
  203.   tEvalResult EvalResult;
  204.   tRegEvalResult RegEvalResult;
  205.  
  206.   RegEvalResult = DecodeRegCore(pArg->str.p_str, pSize, pResult);
  207.   if (RegEvalResult != eIsNoReg)
  208.   {
  209.     *pResult &= ~REGSYM_FLAG_ALIAS;
  210.     return RegEvalResult;
  211.   }
  212.  
  213.   RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
  214.   if (RegEvalResult == eIsReg)
  215.   {
  216.     *pResult = RegDescr.Reg & ~REGSYM_FLAG_ALIAS;
  217.     *pSize = EvalResult.DataSize;
  218.   }
  219.   return RegEvalResult;
  220. }
  221.  
  222. static Boolean ChkAdr(Word Mask, const tStrComp *pComp)
  223. {
  224.   if ((AdrMode != ModNone) && (!(Mask & (1 << AdrMode))))
  225.   {
  226.     WrStrErrorPos(ErrNum_InvAddrMode, pComp);
  227.     AdrMode = ModNone;
  228.     AdrCnt = 0;
  229.     return False;
  230.   }
  231.   return True;
  232. }
  233.  
  234. typedef struct
  235. {
  236.   as_eval_cb_data_t cb_data;
  237.   Byte reg;
  238. } xa_eval_cb_data_t;
  239.  
  240. DECLARE_AS_EVAL_CB(xa_eval_cb)
  241. {
  242.   xa_eval_cb_data_t *p_xa_eval_cb_data = (xa_eval_cb_data_t*)p_data;
  243.   Byte reg;
  244.   tSymbolSize reg_size;
  245.  
  246.   switch (DecodeReg(p_arg, &reg_size, &reg, False))
  247.   {
  248.     case eIsReg:
  249.       if ((reg_size != eSymbolSize16Bit)
  250.        || (p_xa_eval_cb_data->reg != 0xff)
  251.        || !as_eval_cb_data_stack_plain_add(p_data->p_stack))
  252.       {
  253.         WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  254.         return e_eval_fail;
  255.       }
  256.       p_xa_eval_cb_data->reg = reg;
  257.       as_tempres_set_int(p_res, 0);
  258.       return e_eval_ok;
  259.     case eRegAbort:
  260.       return e_eval_fail;
  261.     default:
  262.       return e_eval_none;
  263.   }
  264. }
  265.  
  266. static Boolean DecodeAdrIndirect(tStrComp *pArg, Word Mask)
  267. {
  268.   unsigned ArgLen;
  269.  
  270.   ArgLen = strlen(pArg->str.p_str);
  271.   if (pArg->str.p_str[ArgLen - 1] == '+')
  272.   {
  273.     tSymbolSize NSize;
  274.  
  275.     StrCompShorten(pArg, 1); ArgLen--;
  276.     if (!DecodeReg(pArg, &NSize, &AdrPart, True));
  277.     else if (NSize != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  278.     else
  279.     {
  280.       AdrMode = ModMem; MemPart = 3;
  281.     }
  282.   }
  283.   else
  284.   {
  285.     LongInt DispAcc;
  286.     xa_eval_cb_data_t xa_eval_cb_data;
  287.     tEvalResult eval_result;
  288.  
  289.     as_eval_cb_data_ini(&xa_eval_cb_data.cb_data, xa_eval_cb);
  290.     xa_eval_cb_data.reg = 0xff;
  291.     DispAcc = EvalStrIntExprWithResultAndCallback(pArg, SInt16, &eval_result, &xa_eval_cb_data.cb_data);
  292.  
  293.     AdrPart = xa_eval_cb_data.reg;
  294.     if (xa_eval_cb_data.reg == 0xff) WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  295.     else if (DispAcc == 0)
  296.     {
  297.       AdrMode = ModMem; MemPart = 2;
  298.     }
  299.     else if ((DispAcc >= -128) && (DispAcc < 127))
  300.     {
  301.       AdrMode = ModMem; MemPart = 4;
  302.       AdrVals[0] = DispAcc & 0xff; AdrCnt = 1;
  303.     }
  304.     else if (ChkRange(DispAcc, -0x8000l, 0x7fffl))
  305.     {
  306.       AdrMode = ModMem; MemPart = 5;
  307.       AdrVals[0] = (DispAcc >> 8) & 0xff;
  308.       AdrVals[1] = DispAcc & 0xff;
  309.       AdrCnt = 2;
  310.     }
  311.   }
  312.   return ChkAdr(Mask, pArg);
  313. }
  314.  
  315. static Boolean DecodeAdr(tStrComp *pArg, Word Mask)
  316. {
  317.   tSymbolSize NSize;
  318.   LongInt AdrLong;
  319.   tEvalResult EvalResult;
  320.   Word AdrInt;
  321.   int ArgLen;
  322.  
  323.   AdrMode = ModNone; AdrCnt = 0;
  324.   KillPrefBlanksStrComp(pArg);
  325.   KillPostBlanksStrComp(pArg);
  326.  
  327.   switch (DecodeReg(pArg, &NSize, &AdrPart, False))
  328.   {
  329.     case eIsReg:
  330.       if (Mask & MModReg)
  331.       {
  332.         AdrMode = ModReg;
  333.         SetOpSize(NSize);
  334.       }
  335.       else
  336.       {
  337.         AdrMode = ModMem;
  338.         MemPart = 1;
  339.         SetOpSize(NSize);
  340.       }
  341.       return ChkAdr(Mask, pArg);
  342.     case eRegAbort:
  343.       return False;
  344.     default:
  345.       break;
  346.   }
  347.  
  348.   if (*pArg->str.p_str == '#')
  349.   {
  350.     tStrComp ImmComp;
  351.     Boolean OK;
  352.  
  353.     StrCompRefRight(&ImmComp, pArg, 1);
  354.     switch ((int)OpSize)
  355.     {
  356.       case eSymbolSize5Bit:
  357.         AdrVals[0] = EvalStrIntExpression(&ImmComp, UInt5, &OK);
  358.         if (OK)
  359.         {
  360.           AdrCnt = 1; AdrMode = ModImm;
  361.         }
  362.         break;
  363.       case eSymbolSizeSigned4Bit:
  364.         AdrVals[0] = EvalStrIntExpression(&ImmComp, SInt4, &OK);
  365.         if (OK)
  366.         {
  367.           AdrCnt = 1; AdrMode = ModImm;
  368.         }
  369.         break;
  370.       case eSymbolSize4Bit:
  371.         AdrVals[0] = EvalStrIntExpression(&ImmComp, UInt4, &OK);
  372.         if (OK)
  373.         {
  374.           AdrCnt = 1; AdrMode = ModImm;
  375.         }
  376.         break;
  377.       case eSymbolSizeUnknown:
  378.         WrError(ErrNum_UndefOpSizes);
  379.         break;
  380.       case eSymbolSize8Bit:
  381.         AdrVals[0] = EvalStrIntExpression(&ImmComp, Int8, &OK);
  382.         if (OK)
  383.         {
  384.           AdrCnt = 1; AdrMode = ModImm;
  385.         }
  386.         break;
  387.       case eSymbolSize16Bit:
  388.         AdrInt = EvalStrIntExpression(&ImmComp, Int16, &OK);
  389.         if (OK)
  390.         {
  391.           AdrVals[0] = Hi(AdrInt);
  392.           AdrVals[1] = Lo(AdrInt);
  393.           AdrCnt = 2;
  394.           AdrMode = ModImm;
  395.         }
  396.         break;
  397.       case eSymbolSize32Bit:
  398.         AdrLong = EvalStrIntExpression(&ImmComp, Int32, &OK);
  399.         if (OK)
  400.         {
  401.           AdrVals[0] = (AdrLong >> 24) & 0xff;
  402.           AdrVals[1] = (AdrLong >> 16) & 0xff;
  403.           AdrVals[2] = (AdrLong >> 8) & 0xff;
  404.           AdrVals[3] = AdrLong & 0xff;
  405.           AdrCnt = 4;
  406.           AdrMode = ModImm;
  407.         }
  408.         break;
  409.       default:
  410.         break;
  411.     }
  412.     return ChkAdr(Mask, pArg);
  413.   }
  414.  
  415.   ArgLen = strlen(pArg->str.p_str);
  416.   if ((*pArg->str.p_str == '[') && (pArg->str.p_str[ArgLen - 1] == ']'))
  417.   {
  418.     tStrComp IndirComp;
  419.  
  420.     StrCompShorten(pArg, 1);
  421.     StrCompRefRight(&IndirComp, pArg, 1);
  422.     KillPrefBlanksStrComp(&IndirComp);
  423.     KillPostBlanksStrComp(&IndirComp);
  424.  
  425.     return DecodeAdrIndirect(&IndirComp, Mask);
  426.   }
  427.  
  428.   AdrLong = EvalStrIntExpressionWithResult(pArg, UInt24, &EvalResult);
  429.   if (EvalResult.OK)
  430.   {
  431.     if (mFirstPassUnknown(EvalResult.Flags))
  432.     {
  433.       if (!(Mask & MModAbs)) AdrLong &= 0x3ff;
  434.     }
  435.     if ((AdrLong & 0xffff) > 0x7ff) WrError(ErrNum_AdrOverflow);
  436.     else if ((AdrLong & 0xffff) <= 0x3ff)
  437.     {
  438.       if ((AdrLong >> 16) != Reg_DS) WrError(ErrNum_InAccPage);
  439.       ChkSpace(SegData, EvalResult.AddrSpaceMask);
  440.       AdrMode = ModMem; MemPart = 6;
  441.       AdrPart = Hi(AdrLong);
  442.       AdrVals[0] = Lo(AdrLong);
  443.       AdrCnt = 1;
  444.     }
  445.     else if (AdrLong > 0x7ff) WrError(ErrNum_AdrOverflow);
  446.     else
  447.     {
  448.       ChkSpace(SegIO, EvalResult.AddrSpaceMask);
  449.       AdrMode = ModMem; MemPart = 6;
  450.       AdrPart = Hi(AdrLong);
  451.       AdrVals[0] = Lo(AdrLong);
  452.       AdrCnt = 1;
  453.     }
  454.   }
  455.  
  456.   return ChkAdr(Mask, pArg);
  457. }
  458.  
  459. static Boolean DecodeBitAddr(tStrComp *pArg, LongInt *Erg)
  460. {
  461.   char *p;
  462.   Byte BPos, Reg;
  463.   ShortInt Res;
  464.   tSymbolSize Size;
  465.   LongInt AdrLong;
  466.   tEvalResult EvalResult;
  467.  
  468.   p = RQuotPos(pArg->str.p_str, '.'); Res = 0;
  469.   if (!p)
  470.   {
  471.     AdrLong = EvalStrIntExpressionWithResult(pArg, UInt24, &EvalResult);
  472.     if (mFirstPassUnknown(EvalResult.Flags)) AdrLong &= 0x3ff;
  473.     *Erg = AdrLong; Res = 1;
  474.   }
  475.   else
  476.   {
  477.     int l = p - pArg->str.p_str;
  478.  
  479.     BPos = EvalStrIntExpressionOffsWithResult(pArg, l + 1, UInt4, &EvalResult);
  480.     if (mFirstPassUnknown(EvalResult.Flags)) BPos &= 7;
  481.  
  482.     *p = '\0'; pArg->Pos.Len -= l + 1;
  483.     if (EvalResult.OK)
  484.     {
  485.       switch (DecodeReg(pArg, &Size, &Reg, False))
  486.       {
  487.         case eRegAbort:
  488.           return False;
  489.         case eIsReg:
  490.           if ((Size == eSymbolSize8Bit) && (BPos > 7)) WrError(ErrNum_OverRange);
  491.           else
  492.           {
  493.             if (Size == eSymbolSize8Bit) *Erg = (Reg << 3) + BPos;
  494.             else *Erg = (Reg << 4) + BPos;
  495.             Res = 1;
  496.           }
  497.           break;
  498.         default:
  499.           if (BPos > 7) WrError(ErrNum_OverRange);
  500.           else
  501.           {
  502.             AdrLong = EvalStrIntExpressionWithResult(pArg, UInt24, &EvalResult);
  503.             if (EvalResult.AddrSpaceMask & (1 << SegIO))
  504.             {
  505.               ChkSpace(SegIO, EvalResult.AddrSpaceMask);
  506.               if (mFirstPassUnknown(EvalResult.Flags)) AdrLong = (AdrLong & 0x3f) | 0x400;
  507.               if (ChkRange(AdrLong, 0x400, 0x43f))
  508.               {
  509.                 *Erg = 0x200 + ((AdrLong & 0x3f) << 3) + BPos;
  510.                 Res = 1;
  511.               }
  512.               else
  513.                 Res = -1;
  514.             }
  515.             else
  516.             {
  517.               ChkSpace(SegData, EvalResult.AddrSpaceMask);
  518.               if (mFirstPassUnknown(EvalResult.Flags)) AdrLong = (AdrLong & 0x00ff003f) | 0x20;
  519.               if (ChkRange(AdrLong & 0xff, 0x20, 0x3f))
  520.               {
  521.                 *Erg = 0x100 + ((AdrLong & 0x1f) << 3) + BPos + (AdrLong & 0xff0000);
  522.                 Res = 1;
  523.               }
  524.               else
  525.                 Res = -1;
  526.             }
  527.           }
  528.         break;
  529.       }
  530.     }
  531.     *p = '.';
  532.   }
  533.   if (Res == 0) WrError(ErrNum_InvAddrMode);
  534.   return (Res == 1);
  535. }
  536.  
  537. static void ChkBitPage(LongInt Adr)
  538. {
  539.   if ((Adr >> 16) != Reg_DS) WrError(ErrNum_InAccPage);
  540. }
  541.  
  542. static LongWord MkEven24(LongWord Inp)
  543. {
  544.   return Inp & 0xfffffeul;
  545. }
  546.  
  547. static LongWord GetBranchDest(const tStrComp *pComp, tEvalResult *pEvalResult)
  548. {
  549.   LongWord Result;
  550.  
  551.   Result = EvalStrIntExpressionWithResult(pComp, UInt24, pEvalResult);
  552.   if (pEvalResult->OK)
  553.   {
  554.     if (mFirstPassUnknown(pEvalResult->Flags)) Result = MkEven24(Result);
  555.     ChkSpace(SegCode, pEvalResult->AddrSpaceMask);
  556.     if (Result & 1)
  557.     {
  558.       WrStrErrorPos(ErrNum_NotAligned, pComp);
  559.       pEvalResult->OK = False;
  560.     }
  561.   }
  562.   return Result;
  563. }
  564.  
  565. static Boolean ChkShortEvenDist(LongInt *pDist, tSymbolFlags Flags)
  566. {
  567.   if (!mSymbolQuestionable(Flags) && ((*pDist > 254) || (*pDist < -256)))
  568.     return False;
  569.   else
  570.   {
  571.     *pDist >>= 1;
  572.     return True;
  573.   }
  574. }
  575.  
  576. static Boolean ChkLongEvenDist(LongInt *pDist, const tStrComp *pComp, tSymbolFlags Flags)
  577. {
  578.   if (!mSymbolQuestionable(Flags) && ((*pDist > 65534) || (*pDist < -65536)))
  579.   {
  580.     WrStrErrorPos(ErrNum_JmpDistTooBig, pComp);
  581.     return False;
  582.   }
  583.   else
  584.   {
  585.     *pDist >>= 1;
  586.     return True;
  587.   }
  588. }
  589.  
  590. /*-------------------------------------------------------------------------*/
  591. /* Befehlsdekoder */
  592.  
  593. static void DecodePORT(Word Index)
  594. {
  595.   UNUSED(Index);
  596.  
  597.   CodeEquate(SegIO, 0x400, 0x7ff);
  598. }
  599.  
  600. static void DecodeBIT(Word Index)
  601. {
  602.   LongInt BAdr;
  603.  
  604.   UNUSED(Index);
  605.  
  606.   if (!ChkArgCnt(1, 1));
  607.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  608.   else if (DecodeBitAddr(&ArgStr[1], &BAdr))
  609.   {
  610.     EnterIntSymbol(&LabPart, BAdr, SegNone, False);
  611.     switch ((BAdr & 0x3ff) >> 8)
  612.     {
  613.       case 0:
  614.         as_snprintf(ListLine, STRINGSIZE, "=R%d.%d",
  615.                     (unsigned)((BAdr >> 4) & 15),
  616.                     (unsigned) (BAdr & 15));
  617.         break;
  618.       case 1:
  619.         as_snprintf(ListLine, STRINGSIZE, "=%x:%x.%d",
  620.                     (unsigned)((BAdr >> 16) & 255),
  621.                     (unsigned)((BAdr & 0x1f8) >> 3), (unsigned)(BAdr & 7));
  622.         break;
  623.       default:
  624.         as_snprintf(ListLine, STRINGSIZE, "=S:%x.%d",
  625.                     (unsigned)(((BAdr >> 3) & 0x3f) + 0x400),
  626.                     (unsigned)(BAdr & 7));
  627.         break;
  628.     }
  629.   }
  630. }
  631.  
  632. static void DecodeFixed(Word Code)
  633. {
  634.   if (ChkArgCnt(0, 0))
  635.   {
  636.     if (Hi(Code) != 0) BAsmCode[CodeLen++] = Hi(Code);
  637.     BAsmCode[CodeLen++] = Lo(Code);
  638.     if ((Code == RETICode) && (!SupAllowed)) WrError(ErrNum_PrivOrder);
  639.   }
  640. }
  641.  
  642. static void DecodeStack(Word Code)
  643. {
  644.   Byte HReg;
  645.   Boolean OK;
  646.   Word Mask;
  647.   int i;
  648.  
  649.   if (ChkArgCnt(1, ArgCntMax))
  650.   {
  651.     HReg = 0xff; OK = True; Mask = 0;
  652.     for (i = 1; i <= ArgCnt; i++)
  653.       if (OK)
  654.       {
  655.         DecodeAdr(&ArgStr[i], MModMem);
  656.         if (AdrMode == ModNone) OK = False;
  657.         else switch (MemPart)
  658.         {
  659.           case 1:
  660.             if (HReg == 0)
  661.             {
  662.               WrError(ErrNum_InvAddrMode); OK = False;
  663.             }
  664.             else
  665.             {
  666.               HReg = 1; Mask |= (1 << AdrPart);
  667.             }
  668.             break;
  669.           case 6:
  670.             if (HReg != 0xff)
  671.             {
  672.               WrError(ErrNum_InvAddrMode); OK = False;
  673.             }
  674.             else
  675.               HReg = 0;
  676.             break;
  677.           default:
  678.             WrError(ErrNum_InvAddrMode); OK = False;
  679.         }
  680.       }
  681.     if (OK)
  682.     {
  683.       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  684.       else if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  685.       else if (HReg == 0)
  686.       {
  687.         BAsmCode[CodeLen++] = 0x87 + (OpSize << 3);
  688.         BAsmCode[CodeLen++] = Hi(Code) + AdrPart;
  689.         BAsmCode[CodeLen++] = AdrVals[0];
  690.       }
  691.       else if (Code < 0x2000)  /* POP(U): obere Register zuerst */
  692.       {
  693.         if (Hi(Mask) != 0)
  694.         {
  695.           BAsmCode[CodeLen++] = Lo(Code) + (OpSize << 3) + 0x40;
  696.           BAsmCode[CodeLen++]=Hi(Mask);
  697.         }
  698.         if (Lo(Mask) != 0)
  699.         {
  700.           BAsmCode[CodeLen++] = Lo(Code) + (OpSize << 3);
  701.           BAsmCode[CodeLen++] = Lo(Mask);
  702.         }
  703.         if ((OpSize == eSymbolSize16Bit) && (Code == 0x1027) && (Mask & 0x80)) WrError(ErrNum_Unpredictable);
  704.       }
  705.       else              /* PUSH(U): untere Register zuerst */
  706.       {
  707.         if (Lo(Mask) != 0)
  708.         {
  709.           BAsmCode[CodeLen++] = Lo(Code) + (OpSize << 3);
  710.           BAsmCode[CodeLen++] = Lo(Mask);
  711.         }
  712.         if (Hi(Mask) != 0)
  713.         {
  714.           BAsmCode[CodeLen++] = Lo(Code) + (OpSize << 3) + 0x40;
  715.           BAsmCode[CodeLen++] = Hi(Mask);
  716.         }
  717.       }
  718.     }
  719.   }
  720. }
  721.  
  722. static void DecodeALU(Word Index)
  723. {
  724.   Byte HReg, HCnt, HVals[3], HMem;
  725.  
  726.   if (ChkArgCnt(2, 2))
  727.   {
  728.     DecodeAdr(&ArgStr[1], MModReg | MModMem);
  729.     switch (AdrMode)
  730.     {
  731.       case ModReg:
  732.         if (OpSize >= eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  733.         else if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  734.         else
  735.         {
  736.           HReg = AdrPart;
  737.           DecodeAdr(&ArgStr[2], MModMem | MModImm);
  738.           switch (AdrMode)
  739.           {
  740.             case ModMem:
  741.               BAsmCode[CodeLen++] = (Index << 4) + (OpSize << 3) + MemPart;
  742.               BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  743.               memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  744.               CodeLen += AdrCnt;
  745.               if ((MemPart == 3) && ((HReg >> (1 - OpSize)) == AdrPart)) WrError(ErrNum_Unpredictable);
  746.               break;
  747.             case ModImm:
  748.               BAsmCode[CodeLen++] = 0x91 + (OpSize << 3);
  749.               BAsmCode[CodeLen++] = (HReg << 4) + Index;
  750.               memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  751.               CodeLen += AdrCnt;
  752.               break;
  753.           }
  754.         }
  755.         break;
  756.       case ModMem:
  757.         HReg = AdrPart; HMem = MemPart; HCnt = AdrCnt;
  758.         memcpy(HVals, AdrVals, AdrCnt);
  759.         DecodeAdr(&ArgStr[2], MModReg | MModImm);
  760.         switch (AdrMode)
  761.         {
  762.           case ModReg:
  763.             if (OpSize == eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  764.             else if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  765.             else
  766.             {
  767.               BAsmCode[CodeLen++] = (Index << 4) + (OpSize << 3) + HMem;
  768.               BAsmCode[CodeLen++] = (AdrPart << 4) + 8 + HReg;
  769.               memcpy(BAsmCode + CodeLen, HVals, HCnt);
  770.               CodeLen += HCnt;
  771.               if ((HMem == 3) && ((AdrPart >> (1 - OpSize)) == HReg)) WrError(ErrNum_Unpredictable);
  772.             }
  773.             break;
  774.           case ModImm:
  775.             if (OpSize == eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  776.             else if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  777.             else
  778.             {
  779.               BAsmCode[CodeLen++] = 0x90 + HMem + (OpSize << 3);
  780.               BAsmCode[CodeLen++] = (HReg << 4) + Index;
  781.               memcpy(BAsmCode + CodeLen, HVals, HCnt);
  782.               memcpy(BAsmCode + CodeLen + HCnt, AdrVals, AdrCnt);
  783.               CodeLen += AdrCnt + HCnt;
  784.             }
  785.             break;
  786.         }
  787.         break;
  788.     }
  789.   }
  790. }
  791.  
  792. static void DecodeRegO(Word Index)
  793. {
  794.   RegOrder *Op = RegOrders + Index;
  795.  
  796.   if (ChkArgCnt(1, 1))
  797.   {
  798.     DecodeAdr(&ArgStr[1], MModReg);
  799.     switch (AdrMode)
  800.     {
  801.       case ModReg:
  802.         if ((Op->SizeMask & (1 << OpSize)) == 0) WrError(ErrNum_InvOpSize);
  803.         else
  804.         {
  805.           BAsmCode[CodeLen++] = 0x90 + (OpSize << 3);
  806.           BAsmCode[CodeLen++] = (AdrPart << 4) + Op->Code;
  807.         }
  808.         break;
  809.     }
  810.   }
  811. }
  812.  
  813. static void DecodeShift(Word Index)
  814. {
  815.   Byte HReg, HMem;
  816.  
  817.   if (!ChkArgCnt(2, 2));
  818.   else if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  819.   else
  820.   {
  821.     DecodeAdr(&ArgStr[1], MModReg);
  822.     switch (AdrMode)
  823.     {
  824.       case ModReg:
  825.         HReg = AdrPart; HMem = OpSize;
  826.         if (*ArgStr[2].str.p_str == '#')
  827.           OpSize = (HMem == 2) ? eSymbolSize5Bit : eSymbolSize4Bit;
  828.         else
  829.           OpSize = eSymbolSize8Bit;
  830.         DecodeAdr(&ArgStr[2], MModReg | ((Index == 3) ? 0 : MModImm));
  831.         switch (AdrMode)
  832.         {
  833.           case ModReg:
  834.             BAsmCode[CodeLen++] = 0xc0 + ((HMem & 1) << 3) + Index;
  835.             if (HMem == 2) BAsmCode[CodeLen - 1] += 12;
  836.             BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  837.             if (Index == 3)
  838.             {
  839.               if (HMem == 2)
  840.               {
  841.                 if ((AdrPart >> 2) == (HReg >> 1)) WrError(ErrNum_Unpredictable);
  842.               }
  843.               else if ((AdrPart >> HMem) == HReg) WrError(ErrNum_Unpredictable);
  844.             }
  845.             break;
  846.           case ModImm:
  847.             BAsmCode[CodeLen++] = 0xd0 + ((HMem & 1) << 3) + Index;
  848.             if (HMem == 2)
  849.             {
  850.               BAsmCode[CodeLen - 1] += 12;
  851.               BAsmCode[CodeLen++] = ((HReg & 14) << 4) + AdrVals[0];
  852.             }
  853.             else
  854.               BAsmCode[CodeLen++] = (HReg << 4) + AdrVals[0];
  855.             break;
  856.         }
  857.         break;
  858.     }
  859.   }
  860. }
  861.  
  862. static void DecodeRotate(Word Code)
  863. {
  864.   Byte HReg, HMem;
  865.  
  866.   if (ChkArgCnt(2, 2))
  867.   {
  868.     DecodeAdr(&ArgStr[1], MModReg);
  869.     switch (AdrMode)
  870.     {
  871.       case ModReg:
  872.         if (OpSize == eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  873.         else
  874.         {
  875.           HReg = AdrPart; HMem = OpSize; OpSize = eSymbolSize4Bit;
  876.           DecodeAdr(&ArgStr[2], MModImm);
  877.           switch (AdrMode)
  878.           {
  879.             case ModImm:
  880.               BAsmCode[CodeLen++] = Code + (HMem << 3);
  881.               BAsmCode[CodeLen++] = (HReg << 4) + AdrVals[0];
  882.               break;
  883.           }
  884.         }
  885.         break;
  886.     }
  887.   }
  888. }
  889.  
  890. static void DecodeRel(Word Index)
  891. {
  892.   InvOrder *Op = RelOrders + Index;
  893.   LongWord Dest;
  894.   LongInt Dist;
  895.   tEvalResult EvalResult;
  896.  
  897.   if (!ChkArgCnt(1, 1));
  898.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  899.   else
  900.   {
  901.     Dest = GetBranchDest(&ArgStr[1], &EvalResult);
  902.     if (EvalResult.OK)
  903.     {
  904.       Dist = Dest - MkEven24(EProgCounter() + CodeLen + 2);
  905.       if (ChkShortEvenDist(&Dist, EvalResult.Flags))
  906.       {
  907.         BAsmCode[CodeLen++] = Op->Code;
  908.         BAsmCode[CodeLen++] = Dist & 0xff;
  909.       }
  910.       else if (!DoBranchExt) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
  911.       else if (Op->Inversion == 255)  /* BR */
  912.       {
  913.         Dist = Dest - MkEven24(EProgCounter() + CodeLen + 3);
  914.         if (ChkLongEvenDist(&Dist, &ArgStr[1], EvalResult.Flags))
  915.         {
  916.           Dist >>= 1;
  917.           BAsmCode[CodeLen++] = 0xd5;
  918.           BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
  919.           BAsmCode[CodeLen++] = Dist        & 0xff;
  920.         }
  921.       }
  922.       else
  923.       {
  924.         Dist = Dest - MkEven24(EProgCounter() + CodeLen + 5);
  925.         if (ChkLongEvenDist(&Dist, &ArgStr[1], EvalResult.Flags))
  926.         {
  927.           BAsmCode[CodeLen++] = RelOrders[Op->Inversion].Code;
  928.           BAsmCode[CodeLen++] = 2;
  929.           BAsmCode[CodeLen++] = 0xd5;
  930.           BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
  931.           BAsmCode[CodeLen++] = Dist        & 0xff;
  932.           if (Odd(EProgCounter() + CodeLen)) BAsmCode[CodeLen++] = 0;
  933.         }
  934.       }
  935.     }
  936.   }
  937. }
  938.  
  939. static void DecodeJBit(Word Index)
  940. {
  941.   LongInt BitAdr, Dist, odd;
  942.   LongWord Dest;
  943.   tEvalResult EvalResult;
  944.   InvOrder *Op = JBitOrders + Index;
  945.  
  946.   if (!ChkArgCnt(2, 2));
  947.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  948.   else if (DecodeBitAddr(&ArgStr[1], &BitAdr))
  949.   {
  950.     Dest = GetBranchDest(&ArgStr[2], &EvalResult);
  951.     if (EvalResult.OK)
  952.     {
  953.       Dist = Dest - MkEven24(EProgCounter() + CodeLen + 4);
  954.       if (ChkShortEvenDist(&Dist, EvalResult.Flags))
  955.       {
  956.         BAsmCode[CodeLen++] = 0x97;
  957.         BAsmCode[CodeLen++] = Op->Code + Hi(BitAdr);
  958.         BAsmCode[CodeLen++] = Lo(BitAdr);
  959.         BAsmCode[CodeLen++] = Dist & 0xff;
  960.       }
  961.       else if (!DoBranchExt) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[2]);
  962.       else if (Op->Inversion == 255)
  963.       {
  964.         odd = EProgCounter() & 1;
  965.         Dist = Dest - MkEven24(EProgCounter() + CodeLen + 9 + odd);
  966.         if (ChkLongEvenDist(&Dist, &ArgStr[2], EvalResult.Flags))
  967.         {
  968.           BAsmCode[CodeLen++] = 0x97;
  969.           BAsmCode[CodeLen++] = Op->Code + Hi(BitAdr);
  970.           BAsmCode[CodeLen++] = Lo(BitAdr);
  971.           BAsmCode[CodeLen++] = 1 + odd;
  972.           BAsmCode[CodeLen++] = 0xfe;
  973.           BAsmCode[CodeLen++] = 2 + odd;
  974.           if (odd) BAsmCode[CodeLen++] = 0;
  975.           BAsmCode[CodeLen++] = 0xd5;
  976.           BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
  977.           BAsmCode[CodeLen++] = Dist        & 0xff;
  978.           BAsmCode[CodeLen++] = 0;
  979.         }
  980.       }
  981.       else
  982.       {
  983.         Dist = Dest - MkEven24(EProgCounter() + CodeLen + 7);
  984.         if (ChkLongEvenDist(&Dist, &ArgStr[2], EvalResult.Flags))
  985.         {
  986.           BAsmCode[CodeLen++] = 0x97;
  987.           BAsmCode[CodeLen++] = JBitOrders[Op->Inversion].Code + Hi(BitAdr);
  988.           BAsmCode[CodeLen++] = Lo(BitAdr);
  989.           BAsmCode[CodeLen++] = 2;
  990.           BAsmCode[CodeLen++] = 0xd5;
  991.           BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
  992.           BAsmCode[CodeLen++] = Dist        & 0xff;
  993.           if (Odd(EProgCounter() + CodeLen)) BAsmCode[CodeLen++] = 0;
  994.         }
  995.       }
  996.     }
  997.   }
  998. }
  999.  
  1000.  
  1001. static void DecodeMOV(Word Index)
  1002. {
  1003.   LongInt AdrLong;
  1004.   Byte HVals[3], HReg, HPart, HCnt;
  1005.   UNUSED(Index);
  1006.  
  1007.   if (!ChkArgCnt(2, 2));
  1008.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "C"))
  1009.   {
  1010.     if (DecodeBitAddr(&ArgStr[2], &AdrLong))
  1011.     {
  1012.       if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1013.       else
  1014.       {
  1015.         ChkBitPage(AdrLong);
  1016.         BAsmCode[CodeLen++] = 0x08;
  1017.         BAsmCode[CodeLen++] = 0x20 + Hi(AdrLong);
  1018.         BAsmCode[CodeLen++] = Lo(AdrLong);
  1019.       }
  1020.     }
  1021.   }
  1022.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "C"))
  1023.   {
  1024.     if (DecodeBitAddr(&ArgStr[1], &AdrLong))
  1025.     {
  1026.       if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1027.       else
  1028.       {
  1029.         ChkBitPage(AdrLong);
  1030.         BAsmCode[CodeLen++] = 0x08;
  1031.         BAsmCode[CodeLen++] = 0x30 + Hi(AdrLong);
  1032.         BAsmCode[CodeLen++] = Lo(AdrLong);
  1033.       }
  1034.     }
  1035.   }
  1036.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "USP"))
  1037.   {
  1038.     SetOpSize(eSymbolSize16Bit);
  1039.     DecodeAdr(&ArgStr[2], MModReg);
  1040.     if (AdrMode == ModReg)
  1041.     {
  1042.       BAsmCode[CodeLen++] = 0x98;
  1043.       BAsmCode[CodeLen++] = (AdrPart << 4) + 0x0f;
  1044.     }
  1045.   }
  1046.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "USP"))
  1047.   {
  1048.     SetOpSize(eSymbolSize16Bit);
  1049.     DecodeAdr(&ArgStr[1], MModReg);
  1050.     if (AdrMode == ModReg)
  1051.     {
  1052.       BAsmCode[CodeLen++] = 0x90;
  1053.       BAsmCode[CodeLen++] = (AdrPart << 4)+0x0f;
  1054.     }
  1055.   }
  1056.   else
  1057.   {
  1058.     DecodeAdr(&ArgStr[1], MModReg | MModMem);
  1059.     switch (AdrMode)
  1060.     {
  1061.       case ModReg:
  1062.         if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  1063.         else
  1064.         {
  1065.           HReg = AdrPart;
  1066.           DecodeAdr(&ArgStr[2], MModMem | MModImm);
  1067.           switch (AdrMode)
  1068.           {
  1069.             case ModMem:
  1070.               BAsmCode[CodeLen++] = 0x80 + (OpSize << 3) + MemPart;
  1071.               BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  1072.               memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  1073.               CodeLen += AdrCnt;
  1074.               if ((MemPart == 3) && ((HReg >> (1 - OpSize)) == AdrPart)) WrError(ErrNum_Unpredictable);
  1075.               break;
  1076.             case ModImm:
  1077.               BAsmCode[CodeLen++] = 0x91 + (OpSize << 3);
  1078.               BAsmCode[CodeLen++] = 0x08 + (HReg << 4);
  1079.               memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  1080.               CodeLen += AdrCnt;
  1081.               break;
  1082.           }
  1083.         }
  1084.         break;
  1085.       case ModMem:
  1086.         memcpy(HVals, AdrVals, AdrCnt); HCnt = AdrCnt; HPart = MemPart; HReg = AdrPart;
  1087.         DecodeAdr(&ArgStr[2], MModReg | MModMem | MModImm);
  1088.         switch (AdrMode)
  1089.         {
  1090.           case ModReg:
  1091.             if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  1092.             else
  1093.             {
  1094.               BAsmCode[CodeLen++] = 0x80 + (OpSize << 3) + HPart;
  1095.               BAsmCode[CodeLen++] = (AdrPart << 4) + 0x08 + HReg;
  1096.               memcpy(BAsmCode + CodeLen, HVals, HCnt);
  1097.               CodeLen += HCnt;
  1098.               if ((HPart == 3) && ((AdrPart >> (1 - OpSize)) == HReg)) WrError(ErrNum_Unpredictable);
  1099.             }
  1100.             break;
  1101.           case ModMem:
  1102.             if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1103.             else if ((OpSize != eSymbolSize8Bit) & (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  1104.             else if ((HPart == 6) && (MemPart == 6))
  1105.             {
  1106.               BAsmCode[CodeLen++] = 0x97 + (OpSize << 3);
  1107.               BAsmCode[CodeLen++] = (HReg << 4)+AdrPart;
  1108.               BAsmCode[CodeLen++] = HVals[0];
  1109.               BAsmCode[CodeLen++] = AdrVals[0];
  1110.             }
  1111.             else if ((HPart == 6) && (MemPart == 2))
  1112.             {
  1113.               BAsmCode[CodeLen++] = 0xa0 + (OpSize << 3);
  1114.               BAsmCode[CodeLen++] = 0x80 + (AdrPart << 4) + HReg;
  1115.               BAsmCode[CodeLen++] = HVals[0];
  1116.             }
  1117.             else if ((HPart == 2) && (MemPart == 6))
  1118.             {
  1119.               BAsmCode[CodeLen++] = 0xa0 + (OpSize << 3);
  1120.               BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  1121.               BAsmCode[CodeLen++] = AdrVals[0];
  1122.             }
  1123.             else if ((HPart == 3) && (MemPart == 3))
  1124.             {
  1125.               BAsmCode[CodeLen++] = 0x90 + (OpSize << 3);
  1126.               BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  1127.               if (HReg == AdrPart) WrError(ErrNum_Unpredictable);
  1128.             }
  1129.             else
  1130.               WrError(ErrNum_InvAddrMode);
  1131.             break;
  1132.           case ModImm:
  1133.             if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1134.             else if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  1135.             else
  1136.             {
  1137.               BAsmCode[CodeLen++] = 0x90 + (OpSize << 3) + HPart;
  1138.               BAsmCode[CodeLen++] = 0x08 + (HReg << 4);
  1139.               memcpy(BAsmCode + CodeLen, HVals, HCnt);
  1140.               memcpy(BAsmCode + CodeLen + HCnt, AdrVals, AdrCnt);
  1141.               CodeLen += HCnt + AdrCnt;
  1142.             }
  1143.             break;
  1144.         }
  1145.         break;
  1146.     }
  1147.   }
  1148. }
  1149.  
  1150. static void DecodeMOVC(Word Index)
  1151. {
  1152.   Byte HReg;
  1153.   UNUSED(Index);
  1154.  
  1155.   if (!ChkArgCnt(2, 2));
  1156.   else
  1157.   {
  1158.     if (!*AttrPart.str.p_str && !as_strcasecmp(ArgStr[1].str.p_str, "A")) OpSize = eSymbolSize8Bit;
  1159.     if (!as_strcasecmp(ArgStr[2].str.p_str, "[A+DPTR]"))
  1160.     {
  1161.       if (as_strcasecmp(ArgStr[1].str.p_str, "A")) WrError(ErrNum_InvAddrMode);
  1162.       else if (OpSize != eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
  1163.       else
  1164.       {
  1165.         BAsmCode[CodeLen++] = 0x90;
  1166.         BAsmCode[CodeLen++] = 0x4e;
  1167.       }
  1168.     }
  1169.     else if (!as_strcasecmp(ArgStr[2].str.p_str, "[A+PC]"))
  1170.     {
  1171.       if (as_strcasecmp(ArgStr[1].str.p_str, "A")) WrError(ErrNum_InvAddrMode);
  1172.       else if (OpSize != eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
  1173.       else
  1174.       {
  1175.         BAsmCode[CodeLen++] = 0x90;
  1176.         BAsmCode[CodeLen++] = 0x4c;
  1177.       }
  1178.     }
  1179.     else
  1180.     {
  1181.       DecodeAdr(&ArgStr[1], MModReg);
  1182.       if (AdrMode != ModNone)
  1183.       {
  1184.         if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  1185.         else
  1186.         {
  1187.           HReg = AdrPart;
  1188.           DecodeAdr(&ArgStr[2], MModMem);
  1189.           if (AdrMode != ModNone)
  1190.           {
  1191.             if (MemPart != 3) WrError(ErrNum_InvAddrMode);
  1192.             else
  1193.             {
  1194.               BAsmCode[CodeLen++] = 0x80 + (OpSize << 3);
  1195.               BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  1196.               if ((MemPart == 3) && ((HReg >> (1 - OpSize)) == AdrPart)) WrError(ErrNum_Unpredictable);
  1197.             }
  1198.           }
  1199.         }
  1200.       }
  1201.     }
  1202.   }
  1203. }
  1204.  
  1205. static void DecodeMOVX(Word Index)
  1206. {
  1207.   Byte HReg;
  1208.   UNUSED(Index);
  1209.  
  1210.   if (!ChkArgCnt(2, 2));
  1211.   else
  1212.   {
  1213.     DecodeAdr(&ArgStr[1], MModMem);
  1214.     if (AdrMode == ModMem)
  1215.     {
  1216.       switch (MemPart)
  1217.       {
  1218.         case 1:
  1219.           if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  1220.           else
  1221.           {
  1222.             HReg = AdrPart; DecodeAdr(&ArgStr[2], MModMem);
  1223.             if (AdrMode == ModMem)
  1224.             {
  1225.               if (MemPart != 2) WrError(ErrNum_InvAddrMode);
  1226.               else
  1227.               {
  1228.                 BAsmCode[CodeLen++] = 0xa7 + (OpSize << 3);
  1229.                 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  1230.               }
  1231.             }
  1232.           }
  1233.           break;
  1234.         case 2:
  1235.           HReg = AdrPart; DecodeAdr(&ArgStr[2], MModReg);
  1236.           if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  1237.           else
  1238.           {
  1239.             BAsmCode[CodeLen++] = 0xa7 + (OpSize << 3);
  1240.             BAsmCode[CodeLen++] = 0x08 + (AdrPart << 4) + HReg;
  1241.           }
  1242.           break;
  1243.         default:
  1244.           WrError(ErrNum_InvAddrMode);
  1245.       }
  1246.     }
  1247.   }
  1248. }
  1249.  
  1250. static void DecodeXCH(Word Index)
  1251. {
  1252.   Byte HReg, HPart, HVals[3];
  1253.   UNUSED(Index);
  1254.  
  1255.   if (ChkArgCnt(2, 2))
  1256.   {
  1257.     DecodeAdr(&ArgStr[1], MModMem);
  1258.     if (AdrMode == ModMem)
  1259.     {
  1260.       switch (MemPart)
  1261.       {
  1262.         case 1:
  1263.           HReg = AdrPart; DecodeAdr(&ArgStr[2], MModMem);
  1264.           if (AdrMode == ModMem)
  1265.           {
  1266.             if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize8Bit)) WrError(ErrNum_InvOpSize);
  1267.             else switch (MemPart)
  1268.             {
  1269.               case 1:
  1270.                 BAsmCode[CodeLen++] = 0x60 + (OpSize << 3);
  1271.                 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  1272.                 if (HReg == AdrPart) WrError(ErrNum_Unpredictable);
  1273.                 break;
  1274.               case 2:
  1275.                 BAsmCode[CodeLen++] = 0x50 + (OpSize << 3);
  1276.                 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  1277.                 break;
  1278.               case 6:
  1279.                 BAsmCode[CodeLen++] = 0xa0 + (OpSize << 3);
  1280.                 BAsmCode[CodeLen++] = 0x08 + (HReg << 4) + AdrPart;
  1281.                 BAsmCode[CodeLen++] = AdrVals[0];
  1282.                 break;
  1283.               default:
  1284.                 WrError(ErrNum_InvAddrMode);
  1285.             }
  1286.           }
  1287.           break;
  1288.         case 2:
  1289.           HReg = AdrPart;
  1290.           DecodeAdr(&ArgStr[2], MModReg);
  1291.           if (AdrMode == ModReg)
  1292.           {
  1293.             if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  1294.             else
  1295.             {
  1296.               BAsmCode[CodeLen++] = 0x50 + (OpSize << 3);
  1297.               BAsmCode[CodeLen++] = (AdrPart << 4) + HReg;
  1298.             }
  1299.           }
  1300.           break;
  1301.         case 6:
  1302.           HPart = AdrPart; HVals[0] = AdrVals[0];
  1303.           DecodeAdr(&ArgStr[2], MModReg);
  1304.           if (AdrMode == ModReg)
  1305.           {
  1306.             if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  1307.             else
  1308.             {
  1309.               BAsmCode[CodeLen++] = 0xa0 + (OpSize << 3);
  1310.               BAsmCode[CodeLen++] = 0x08 + (AdrPart << 4) + HPart;
  1311.               BAsmCode[CodeLen++] = HVals[0];
  1312.             }
  1313.           }
  1314.           break;
  1315.         default:
  1316.           WrError(ErrNum_InvAddrMode);
  1317.       }
  1318.     }
  1319.   }
  1320. }
  1321.  
  1322. static void DecodeADDSMOVS(Word Index)
  1323. {
  1324.   Byte HReg;
  1325.   tSymbolSize HSize;
  1326.  
  1327.   if (ChkArgCnt(2, 2))
  1328.   {
  1329.     HSize = OpSize;
  1330.     OpSize = eSymbolSizeSigned4Bit;
  1331.     DecodeAdr(&ArgStr[2], MModImm);
  1332.     switch (AdrMode)
  1333.     {
  1334.       case ModImm:
  1335.         HReg = AdrVals[0]; OpSize = HSize;
  1336.         DecodeAdr(&ArgStr[1], MModMem);
  1337.         switch (AdrMode)
  1338.         {
  1339.           case ModMem:
  1340.             if (OpSize == eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  1341.             else if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1342.             else
  1343.             {
  1344.                BAsmCode[CodeLen++] = 0xa0 + (Index << 4) + (OpSize << 3) + MemPart;
  1345.                BAsmCode[CodeLen++] = (AdrPart << 4) + (HReg & 0x0f);
  1346.                memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  1347.                CodeLen += AdrCnt;
  1348.             }
  1349.             break;
  1350.         }
  1351.         break;
  1352.     }
  1353.   }
  1354. }
  1355.  
  1356. static void DecodeDIV(Word Index)
  1357. {
  1358.   Byte HReg;
  1359.   UNUSED(Index);
  1360.  
  1361.   if (ChkArgCnt(2, 2))
  1362.   {
  1363.     DecodeAdr(&ArgStr[1], MModReg);
  1364.     if (AdrMode == ModReg)
  1365.     {
  1366.       if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  1367.       else
  1368.       {
  1369.         HReg = AdrPart; OpSize--; DecodeAdr(&ArgStr[2], MModReg | MModImm);
  1370.         switch (AdrMode)
  1371.         {
  1372.           case ModReg:
  1373.             BAsmCode[CodeLen++] = 0xe7 + (OpSize << 3);
  1374.             BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  1375.             break;
  1376.           case ModImm:
  1377.             BAsmCode[CodeLen++] = 0xe8 + OpSize;
  1378.             BAsmCode[CodeLen++] = (HReg << 4) + 0x0b - (OpSize << 1);
  1379.             memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  1380.             CodeLen += AdrCnt;
  1381.             break;
  1382.         }
  1383.       }
  1384.     }
  1385.   }
  1386. }
  1387.  
  1388. static void DecodeDIVU(Word Index)
  1389. {
  1390.   Byte HReg;
  1391.   int z;
  1392.   UNUSED(Index);
  1393.  
  1394.   if (ChkArgCnt(2, 2))
  1395.   {
  1396.     DecodeAdr(&ArgStr[1], MModReg);
  1397.     if (AdrMode == ModReg)
  1398.     {
  1399.       if ((OpSize == eSymbolSize8Bit) && (AdrPart & 1)) WrError(ErrNum_InvReg);
  1400.       else
  1401.       {
  1402.         HReg = AdrPart; z = OpSize; if (OpSize != eSymbolSize8Bit) OpSize--;
  1403.         DecodeAdr(&ArgStr[2], MModReg | MModImm);
  1404.         switch (AdrMode)
  1405.         {
  1406.           case ModReg:
  1407.             BAsmCode[CodeLen++] = 0xe1 + (z << 2);
  1408.             if (z == 2) BAsmCode[CodeLen - 1] += 4;
  1409.             BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  1410.             break;
  1411.           case ModImm:
  1412.             BAsmCode[CodeLen++] = 0xe8 + Ord(z == 2);
  1413.             BAsmCode[CodeLen++] = (HReg << 4) + 0x01 + (Ord(z == 1) << 1);
  1414.             memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  1415.             CodeLen += AdrCnt;
  1416.             break;
  1417.         }
  1418.       }
  1419.     }
  1420.   }
  1421. }
  1422.  
  1423. static void DecodeMUL(Word Index)
  1424. {
  1425.   Byte HReg;
  1426.   UNUSED(Index);
  1427.  
  1428.   if (ChkArgCnt(2, 2))
  1429.   {
  1430.     DecodeAdr(&ArgStr[1], MModReg);
  1431.     if (AdrMode == ModReg)
  1432.     {
  1433.       if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
  1434.       else if (AdrPart & 1) WrError(ErrNum_InvReg);
  1435.       else
  1436.       {
  1437.         HReg = AdrPart; DecodeAdr(&ArgStr[2], MModReg | MModImm);
  1438.         switch (AdrMode)
  1439.         {
  1440.           case ModReg:
  1441.             BAsmCode[CodeLen++] = 0xe6;
  1442.             BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  1443.             break;
  1444.           case ModImm:
  1445.             BAsmCode[CodeLen++] = 0xe9;
  1446.             BAsmCode[CodeLen++] = (HReg << 4) + 0x08;
  1447.             memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  1448.             CodeLen += AdrCnt;
  1449.             break;
  1450.         }
  1451.       }
  1452.     }
  1453.   }
  1454. }
  1455.  
  1456. static void DecodeMULU(Word Index)
  1457. {
  1458.   Byte HReg;
  1459.   UNUSED(Index);
  1460.  
  1461.   if (ChkArgCnt(2, 2))
  1462.   {
  1463.     DecodeAdr(&ArgStr[1], MModReg);
  1464.     if (AdrMode == ModReg)
  1465.     {
  1466.       if (AdrPart & 1) WrError(ErrNum_InvReg);
  1467.       else
  1468.       {
  1469.         HReg = AdrPart;
  1470.         DecodeAdr(&ArgStr[2], MModReg | MModImm);
  1471.         switch (AdrMode)
  1472.         {
  1473.           case ModReg:
  1474.             BAsmCode[CodeLen++] = 0xe0 + (OpSize << 2);
  1475.             BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  1476.             break;
  1477.           case ModImm:
  1478.             BAsmCode[CodeLen++] = 0xe8 + OpSize;
  1479.             BAsmCode[CodeLen++] = (HReg << 4);
  1480.             memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  1481.             CodeLen += AdrCnt;
  1482.             break;
  1483.         }
  1484.       }
  1485.     }
  1486.   }
  1487. }
  1488.  
  1489. static void DecodeLEA(Word Index)
  1490. {
  1491.   Byte HReg;
  1492.   UNUSED(Index);
  1493.  
  1494.   if (ChkArgCnt(2, 2))
  1495.   {
  1496.     DecodeAdr(&ArgStr[1], MModReg);
  1497.     if (AdrMode == ModReg)
  1498.     {
  1499.       if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
  1500.       else
  1501.       {
  1502.         HReg = AdrPart;
  1503.         DecodeAdrIndirect(&ArgStr[2], MModMem);
  1504.         if (AdrMode == ModMem)
  1505.           switch (MemPart)
  1506.           {
  1507.             case 4:
  1508.             case 5:
  1509.               BAsmCode[CodeLen++] = 0x20 + (MemPart << 3);
  1510.               BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  1511.               memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  1512.               CodeLen += AdrCnt;
  1513.               break;
  1514.             default:
  1515.               WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  1516.           }
  1517.       }
  1518.     }
  1519.   }
  1520. }
  1521.  
  1522. static void DecodeANLORL(Word Index)
  1523. {
  1524.   if (!ChkArgCnt(2, 2));
  1525.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1526.   else if (as_strcasecmp(ArgStr[1].str.p_str, "C")) WrError(ErrNum_InvAddrMode);
  1527.   else
  1528.   {
  1529.     Byte Invert = 0;
  1530.     LongInt AdrLong;
  1531.     Boolean Result;
  1532.  
  1533.     if (*ArgStr[2].str.p_str == '/')
  1534.     {
  1535.       tStrComp Comp;
  1536.  
  1537.       StrCompRefRight(&Comp, &ArgStr[2], 1);
  1538.       Result = DecodeBitAddr(&Comp, &AdrLong);
  1539.       Invert = 1;
  1540.     }
  1541.     else
  1542.       Result = DecodeBitAddr(&ArgStr[2], &AdrLong);
  1543.     if (Result)
  1544.     {
  1545.       ChkBitPage(AdrLong);
  1546.       BAsmCode[CodeLen++] = 0x08;
  1547.       BAsmCode[CodeLen++] = 0x40 | (Index << 5) | (Ord(Invert) << 4) | (Hi(AdrLong) & 3);
  1548.       BAsmCode[CodeLen++] = Lo(AdrLong);
  1549.     }
  1550.   }
  1551. }
  1552.  
  1553. static void DecodeCLRSETB(Word Index)
  1554. {
  1555.   LongInt AdrLong;
  1556.  
  1557.   if (!ChkArgCnt(1, 1));
  1558.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1559.   else if (DecodeBitAddr(&ArgStr[1], &AdrLong))
  1560.   {
  1561.     ChkBitPage(AdrLong);
  1562.     BAsmCode[CodeLen++] = 0x08;
  1563.     BAsmCode[CodeLen++] = (Index << 4) + (Hi(AdrLong) & 3);
  1564.     BAsmCode[CodeLen++] = Lo(AdrLong);
  1565.   }
  1566. }
  1567.  
  1568. static void DecodeTRAP(Word Index)
  1569. {
  1570.   UNUSED(Index);
  1571.  
  1572.   if (!ChkArgCnt(1, 1));
  1573.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1574.   else
  1575.   {
  1576.     OpSize = eSymbolSize4Bit;
  1577.     DecodeAdr(&ArgStr[1], MModImm);
  1578.     switch (AdrMode)
  1579.     {
  1580.       case ModImm:
  1581.         BAsmCode[CodeLen++] = 0xd6;
  1582.         BAsmCode[CodeLen++] = 0x30 + AdrVals[0];
  1583.         break;
  1584.     }
  1585.   }
  1586. }
  1587.  
  1588. static void DecodeCALL(Word Index)
  1589. {
  1590.   UNUSED(Index);
  1591.  
  1592.   if (!ChkArgCnt(1, 1));
  1593.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1594.   else if (*ArgStr[1].str.p_str == '[')
  1595.   {
  1596.     DecodeAdr(&ArgStr[1], MModMem);
  1597.     if (AdrMode != ModNone)
  1598.     {
  1599.       if (MemPart != 2) WrError(ErrNum_InvAddrMode);
  1600.       else
  1601.       {
  1602.         BAsmCode[CodeLen++] = 0xc6;
  1603.         BAsmCode[CodeLen++] = AdrPart;
  1604.       }
  1605.     }
  1606.   }
  1607.   else
  1608.   {
  1609.     tEvalResult EvalResult;
  1610.     LongWord Dest = GetBranchDest(&ArgStr[1], &EvalResult);
  1611.  
  1612.     if (EvalResult.OK)
  1613.     {
  1614.       LongInt Dist = Dest - MkEven24(EProgCounter() + CodeLen + 3);
  1615.  
  1616.       if (ChkLongEvenDist(&Dist, &ArgStr[1], EvalResult.Flags))
  1617.       {
  1618.         BAsmCode[CodeLen++] = 0xc5;
  1619.         BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
  1620.         BAsmCode[CodeLen++] = Dist & 0xff;
  1621.       }
  1622.     }
  1623.   }
  1624. }
  1625.  
  1626. static void DecodeJMP(Word Index)
  1627. {
  1628.   UNUSED(Index);
  1629.  
  1630.   if (!ChkArgCnt(1, 1));
  1631.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1632.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "[A+DPTR]"))
  1633.   {
  1634.     BAsmCode[CodeLen++] = 0xd6;
  1635.     BAsmCode[CodeLen++] = 0x46;
  1636.   }
  1637.   else if (!strncmp(ArgStr[1].str.p_str, "[[", 2))
  1638.   {
  1639.     tStrComp Comp;
  1640.  
  1641.     ArgStr[1].str.p_str[strlen(ArgStr[1].str.p_str) - 1] = '\0';
  1642.     ArgStr[1].Pos.Len--;
  1643.     StrCompRefRight(&Comp, &ArgStr[1], 1);
  1644.     DecodeAdr(&Comp, MModMem);
  1645.     if (AdrMode == ModMem)
  1646.      switch (MemPart)
  1647.      {
  1648.        case 3:
  1649.          BAsmCode[CodeLen++] = 0xd6;
  1650.          BAsmCode[CodeLen++] = 0x60 + AdrPart;
  1651.          break;
  1652.        default:
  1653.          WrError(ErrNum_InvAddrMode);
  1654.      }
  1655.   }
  1656.   else if (*ArgStr[1].str.p_str == '[')
  1657.   {
  1658.     DecodeAdr(&ArgStr[1], MModMem);
  1659.     if (AdrMode == ModMem)
  1660.       switch (MemPart)
  1661.       {
  1662.         case 2:
  1663.           BAsmCode[CodeLen++] = 0xd6;
  1664.           BAsmCode[CodeLen++] = 0x70 + AdrPart;
  1665.           break;
  1666.         default:
  1667.           WrError(ErrNum_InvAddrMode);
  1668.       }
  1669.   }
  1670.   else
  1671.   {
  1672.     tEvalResult EvalResult;
  1673.     LongWord Dest = GetBranchDest(&ArgStr[1], &EvalResult);
  1674.  
  1675.     if (EvalResult.OK)
  1676.     {
  1677.       LongInt Dist = Dest - MkEven24(EProgCounter() + CodeLen + 3);
  1678.  
  1679.       if (ChkLongEvenDist(&Dist, &ArgStr[1], EvalResult.Flags))
  1680.       {
  1681.         BAsmCode[CodeLen++] = 0xd5;
  1682.         BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
  1683.         BAsmCode[CodeLen++] = Dist & 0xff;
  1684.       }
  1685.     }
  1686.   }
  1687. }
  1688.  
  1689. static void DecodeCJNE(Word Index)
  1690. {
  1691.   Byte HReg;
  1692.   UNUSED(Index);
  1693.  
  1694.   if (ChkArgCnt(3, 3))
  1695.   {
  1696.     tEvalResult EvalResult;
  1697.     LongWord Dest = GetBranchDest(&ArgStr[3], &EvalResult);
  1698.  
  1699.     if (EvalResult.OK)
  1700.     {
  1701.       EvalResult.OK = False; HReg = 0;
  1702.       DecodeAdr(&ArgStr[1], MModMem);
  1703.       if (AdrMode == ModMem)
  1704.       {
  1705.         switch (MemPart)
  1706.         {
  1707.           case 1:
  1708.             if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  1709.             else
  1710.             {
  1711.               HReg = AdrPart; DecodeAdr(&ArgStr[2], MModMem | MModImm);
  1712.               switch (AdrMode)
  1713.               {
  1714.                 case ModMem:
  1715.                   if (MemPart != 6) WrError(ErrNum_InvAddrMode);
  1716.                   else
  1717.                   {
  1718.                     BAsmCode[CodeLen] = 0xe2 + (OpSize << 3);
  1719.                     BAsmCode[CodeLen + 1] = (HReg << 4) + AdrPart;
  1720.                     BAsmCode[CodeLen + 2] = AdrVals[0];
  1721.                     HReg=CodeLen + 3;
  1722.                     CodeLen += 4; EvalResult.OK = True;
  1723.                   }
  1724.                   break;
  1725.                 case ModImm:
  1726.                   BAsmCode[CodeLen] = 0xe3 + (OpSize << 3);
  1727.                   BAsmCode[CodeLen + 1] = HReg << 4;
  1728.                   HReg=CodeLen + 2;
  1729.                   memcpy(BAsmCode + CodeLen + 3, AdrVals, AdrCnt);
  1730.                   CodeLen += 3 + AdrCnt; EvalResult.OK = True;
  1731.                   break;
  1732.               }
  1733.             }
  1734.             break;
  1735.           case 2:
  1736.             if ((OpSize != eSymbolSizeUnknown) && (OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  1737.             else
  1738.             {
  1739.               HReg = AdrPart; DecodeAdr(&ArgStr[2], MModImm);
  1740.               if (AdrMode == ModImm)
  1741.               {
  1742.                 BAsmCode[CodeLen] = 0xe3 + (OpSize << 3);
  1743.                 BAsmCode[CodeLen + 1] = (HReg << 4)+8;
  1744.                 HReg = CodeLen + 2;
  1745.                 memcpy(BAsmCode + CodeLen + 3, AdrVals, AdrCnt);
  1746.                 CodeLen += 3 + AdrCnt; EvalResult.OK = True;
  1747.               }
  1748.             }
  1749.             break;
  1750.           default:
  1751.             WrError(ErrNum_InvAddrMode);
  1752.         }
  1753.       }
  1754.       if (EvalResult.OK)
  1755.       {
  1756.         LongInt Dist = Dest - MkEven24(EProgCounter() + CodeLen);
  1757.  
  1758.         EvalResult.OK = False;
  1759.         if (ChkShortEvenDist(&Dist, EvalResult.Flags))
  1760.         {
  1761.           BAsmCode[HReg] = Dist & 0xff;
  1762.           EvalResult.OK = True;
  1763.         }
  1764.         else if (!DoBranchExt) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[3]);
  1765.         else
  1766.         {
  1767.           LongWord odd = (EProgCounter() + CodeLen) & 1;
  1768.  
  1769.           Dist = Dest - MkEven24(EProgCounter() + CodeLen + 5 + odd);
  1770.           if (ChkLongEvenDist(&Dist, &ArgStr[3], EvalResult.Flags))
  1771.           {
  1772.             BAsmCode[HReg] = 1 + odd;
  1773.             BAsmCode[CodeLen++] = 0xfe;
  1774.             BAsmCode[CodeLen++] = 2 + odd;
  1775.             if (odd) BAsmCode[CodeLen++] = 0;
  1776.             BAsmCode[CodeLen++] = 0xd5;
  1777.             BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
  1778.             BAsmCode[CodeLen++] = Dist        & 0xff;
  1779.             BAsmCode[CodeLen++] = 0;
  1780.             EvalResult.OK = True;
  1781.           }
  1782.         }
  1783.       }
  1784.       if (!EvalResult.OK)
  1785.         CodeLen = 0;
  1786.     }
  1787.   }
  1788. }
  1789.  
  1790. static void DecodeDJNZ(Word Index)
  1791. {
  1792.   Byte HReg;
  1793.   UNUSED(Index);
  1794.  
  1795.   if (ChkArgCnt(2, 2))
  1796.   {
  1797.     tEvalResult EvalResult;
  1798.     LongInt Dest = GetBranchDest(&ArgStr[2], &EvalResult);
  1799.  
  1800.     if (EvalResult.OK)
  1801.     {
  1802.       HReg = 0;
  1803.       DecodeAdr(&ArgStr[1], MModMem);
  1804.       EvalResult.OK = False; DecodeAdr(&ArgStr[1], MModMem);
  1805.       if (AdrMode == ModMem)
  1806.         switch (MemPart)
  1807.         {
  1808.           case 1:
  1809.             if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  1810.             else
  1811.             {
  1812.               BAsmCode[CodeLen] = 0x87 + (OpSize << 3);
  1813.               BAsmCode[CodeLen + 1] = (AdrPart << 4) + 0x08;
  1814.               HReg=CodeLen + 2;
  1815.               CodeLen += 3; EvalResult.OK = True;
  1816.             }
  1817.             break;
  1818.           case 6:
  1819.             if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1820.             else if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  1821.             else
  1822.             {
  1823.               BAsmCode[CodeLen] = 0xe2 + (OpSize << 3);
  1824.               BAsmCode[CodeLen+1] = 0x08 + AdrPart;
  1825.               BAsmCode[CodeLen+2] = AdrVals[0];
  1826.               HReg=CodeLen + 3;
  1827.               CodeLen += 4; EvalResult.OK = True;
  1828.             }
  1829.             break;
  1830.           default:
  1831.             WrError(ErrNum_InvAddrMode);
  1832.         }
  1833.       if (EvalResult.OK)
  1834.       {
  1835.         LongInt Dist = Dest - MkEven24(EProgCounter() + CodeLen);
  1836.  
  1837.         EvalResult.OK = False;
  1838.         if (ChkShortEvenDist(&Dist, EvalResult.Flags))
  1839.         {
  1840.           BAsmCode[HReg] = Dist & 0xff;
  1841.           EvalResult.OK = True;
  1842.         }
  1843.         else if (!DoBranchExt) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[2]);
  1844.         else
  1845.         {
  1846.           LongWord odd = (EProgCounter() + CodeLen) & 1;
  1847.  
  1848.           Dist = Dest - MkEven24(EProgCounter() + CodeLen + 5 + odd);
  1849.           if (ChkLongEvenDist(&Dist, &ArgStr[2], EvalResult.Flags))
  1850.           {
  1851.             BAsmCode[HReg] = 1 + odd;
  1852.             BAsmCode[CodeLen++] = 0xfe;
  1853.             BAsmCode[CodeLen++] = 2 + odd;
  1854.             if (odd) BAsmCode[CodeLen++] = 0;
  1855.             BAsmCode[CodeLen++] = 0xd5;
  1856.             BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
  1857.             BAsmCode[CodeLen++] = Dist        & 0xff;
  1858.             BAsmCode[CodeLen++] = 0;
  1859.             EvalResult.OK = True;
  1860.           }
  1861.         }
  1862.       }
  1863.       if (!EvalResult.OK)
  1864.         CodeLen = 0;
  1865.     }
  1866.   }
  1867. }
  1868.  
  1869. static void DecodeFCALLJMP(Word Index)
  1870. {
  1871.   if (!ChkArgCnt(1, 1));
  1872.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1873.   else
  1874.   {
  1875.     tEvalResult EvalResult;
  1876.     LongInt AdrLong = GetBranchDest(&ArgStr[1], &EvalResult);
  1877.     if (EvalResult.OK)
  1878.     {
  1879.       BAsmCode[CodeLen++] = 0xc4 | (Index << 4);
  1880.       BAsmCode[CodeLen++] = (AdrLong >> 8) & 0xff;
  1881.       BAsmCode[CodeLen++] = AdrLong & 0xff;
  1882.       BAsmCode[CodeLen++] = (AdrLong >> 16) & 0xff;
  1883.     }
  1884.   }
  1885. }
  1886.  
  1887. static Boolean IsRealDef(void)
  1888. {
  1889.   switch (*OpPart.str.p_str)
  1890.   {
  1891.     case 'P':
  1892.       return Memo("PORT");
  1893.     case 'B':
  1894.       return Memo("BIT");
  1895.     case 'R':
  1896.       return Memo("REG");
  1897.     default:
  1898.       return FALSE;
  1899.   }
  1900. }
  1901.  
  1902. static void ForceAlign(void)
  1903. {
  1904.   if (EProgCounter() & 1)
  1905.   {
  1906.     BAsmCode[0] = NOPCode; CodeLen = 1;
  1907.   }
  1908. }
  1909.  
  1910. static Boolean DecodeAttrPart_XA(void)
  1911. {
  1912.   if (strlen(AttrPart.str.p_str) > 1)
  1913.   {
  1914.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  1915.     return False;
  1916.   }
  1917.  
  1918.   if (*AttrPart.str.p_str)
  1919.     switch (as_toupper(*AttrPart.str.p_str))
  1920.     {
  1921.       case 'B': AttrPartOpSize[0] = eSymbolSize8Bit; break;
  1922.       case 'W': AttrPartOpSize[0] = eSymbolSize16Bit; break;
  1923.       case 'D': AttrPartOpSize[0] = eSymbolSize32Bit; break;
  1924.       default : WrStrErrorPos(ErrNum_UndefAttr, &AttrPart); return False;
  1925.     }
  1926.   return True;
  1927. }
  1928.  
  1929. static void MakeCode_XA(void)
  1930. {
  1931.   /* Operandengroesse */
  1932.  
  1933.   OpSize = eSymbolSizeUnknown;
  1934.   if (*AttrPart.str.p_str)
  1935.     SetOpSize(AttrPartOpSize[0]);
  1936.  
  1937.   /* Labels muessen auf geraden Adressen liegen.
  1938.      TODO: Do not enforce for DB...DO, DC/DS */
  1939.  
  1940.   if ( (ActPC == SegCode) && (!IsRealDef()) &&
  1941.        ((*LabPart.str.p_str != '\0') ||((ArgCnt == 1) && (!strcmp(ArgStr[1].str.p_str, "$")))) )
  1942.   {
  1943.     ForceAlign();
  1944.     if (*LabPart.str.p_str != '\0')
  1945.       EnterIntSymbol(&LabPart, EProgCounter() + CodeLen, (as_addrspace_t)ActPC, False);
  1946.   }
  1947.  
  1948.   /* via Tabelle suchen */
  1949.  
  1950.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1951.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1952. }
  1953.  
  1954. /*-------------------------------------------------------------------------*/
  1955. /* Codetabellenverwaltung */
  1956.  
  1957. static void AddFixed(const char *NName, Word NCode)
  1958. {
  1959.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  1960. }
  1961.  
  1962. static void AddJBit(const char *NName, Word NCode)
  1963. {
  1964.   order_array_rsv_end(JBitOrders, InvOrder);
  1965.   JBitOrders[InstrZ].Name = NName;
  1966.   JBitOrders[InstrZ].Inversion = 255;
  1967.   JBitOrders[InstrZ].Code = NCode;
  1968.   AddInstTable(InstTable, NName, InstrZ++, DecodeJBit);
  1969. }
  1970.  
  1971. static void AddStack(const char *NName, Word NCode)
  1972. {
  1973.   AddInstTable(InstTable, NName, NCode, DecodeStack);
  1974. }
  1975.  
  1976. static void AddReg(const char *NName, Byte NMask, Byte NCode)
  1977. {
  1978.   order_array_rsv_end(RegOrders, RegOrder);
  1979.   RegOrders[InstrZ].Code = NCode;
  1980.   RegOrders[InstrZ].SizeMask = NMask;
  1981.   AddInstTable(InstTable, NName, InstrZ++, DecodeRegO);
  1982. }
  1983.  
  1984. static void AddRotate(const char *NName, Word NCode)
  1985. {
  1986.   AddInstTable(InstTable, NName, NCode, DecodeRotate);
  1987. }
  1988.  
  1989. static void AddRel(const char *NName, Word NCode)
  1990. {
  1991.   order_array_rsv_end(RelOrders, InvOrder);
  1992.   RelOrders[InstrZ].Name = NName;
  1993.   RelOrders[InstrZ].Inversion = 255;
  1994.   RelOrders[InstrZ].Code = NCode;
  1995.   AddInstTable(InstTable, NName, InstrZ++, DecodeRel);
  1996. }
  1997.  
  1998. static void SetInv(const char *Name1, const char *Name2, InvOrder *Orders)
  1999. {
  2000.   InvOrder *Order1, *Order2;
  2001.  
  2002.   for (Order1 = Orders; strcmp(Order1->Name, Name1); Order1++);
  2003.   for (Order2 = Orders; strcmp(Order2->Name, Name2); Order2++);
  2004.   Order1->Inversion = Order2 - Orders;
  2005.   Order2->Inversion = Order1 - Orders;
  2006. }
  2007.  
  2008. static void InitFields(void)
  2009. {
  2010.   InstTable = CreateInstTable(201);
  2011.  
  2012.   add_null_pseudo(InstTable);
  2013.  
  2014.   AddInstTable(InstTable, "MOV"  , 0, DecodeMOV);
  2015.   AddInstTable(InstTable, "MOVC" , 0, DecodeMOVC);
  2016.   AddInstTable(InstTable, "MOVX" , 0, DecodeMOVX);
  2017.   AddInstTable(InstTable, "XCH"  , 0, DecodeXCH);
  2018.   AddInstTable(InstTable, "ADDS" , 0, DecodeADDSMOVS);
  2019.   AddInstTable(InstTable, "MOVS" , 1, DecodeADDSMOVS);
  2020.   AddInstTable(InstTable, "DIV"  , 0, DecodeDIV);
  2021.   AddInstTable(InstTable, "DIVU" , 0, DecodeDIVU);
  2022.   AddInstTable(InstTable, "MUL"  , 0, DecodeMUL);
  2023.   AddInstTable(InstTable, "MULU" , 0, DecodeMULU);
  2024.   AddInstTable(InstTable, "LEA"  , 0, DecodeLEA);
  2025.   AddInstTable(InstTable, "ANL"  , 0, DecodeANLORL);
  2026.   AddInstTable(InstTable, "ORL"  , 1, DecodeANLORL);
  2027.   AddInstTable(InstTable, "CLR"  , 0, DecodeCLRSETB);
  2028.   AddInstTable(InstTable, "SETB" , 1, DecodeCLRSETB);
  2029.   AddInstTable(InstTable, "TRAP" , 0, DecodeTRAP);
  2030.   AddInstTable(InstTable, "CALL" , 0, DecodeCALL);
  2031.   AddInstTable(InstTable, "JMP"  , 0, DecodeJMP);
  2032.   AddInstTable(InstTable, "CJNE" , 0, DecodeCJNE);
  2033.   AddInstTable(InstTable, "DJNZ" , 0, DecodeDJNZ);
  2034.   AddInstTable(InstTable, "FCALL", 0, DecodeFCALLJMP);
  2035.   AddInstTable(InstTable, "FJMP" , 1, DecodeFCALLJMP);
  2036.   AddInstTable(InstTable, "PORT" , 0, DecodePORT);
  2037.   AddInstTable(InstTable, "BIT"  , 0, DecodeBIT);
  2038.   AddInstTable(InstTable, "REG"  , 0, CodeREG);
  2039.  
  2040.   AddFixed("NOP"  , 0x0000);
  2041.   AddFixed("RET"  , 0xd680);
  2042.   AddFixed("RETI" , RETICode);
  2043.   AddFixed("BKPT" , 0x00ff);
  2044.   AddFixed("RESET", 0xd610);
  2045.  
  2046.   InstrZ = 0;
  2047.   AddJBit("JB"  , 0x80);
  2048.   AddJBit("JBC" , 0xc0);
  2049.   AddJBit("JNB" , 0xa0);
  2050.   SetInv("JB", "JNB", JBitOrders);
  2051.  
  2052.   AddStack("POP"  , 0x1027);
  2053.   AddStack("POPU" , 0x0037);
  2054.   AddStack("PUSH" , 0x3007);
  2055.   AddStack("PUSHU", 0x2017);
  2056.  
  2057.   InstrZ = 0;
  2058.   AddInstTable(InstTable, "ADD" , InstrZ++, DecodeALU);
  2059.   AddInstTable(InstTable, "ADDC", InstrZ++, DecodeALU);
  2060.   AddInstTable(InstTable, "SUB" , InstrZ++, DecodeALU);
  2061.   AddInstTable(InstTable, "SUBB", InstrZ++, DecodeALU);
  2062.   AddInstTable(InstTable, "CMP" , InstrZ++, DecodeALU);
  2063.   AddInstTable(InstTable, "AND" , InstrZ++, DecodeALU);
  2064.   AddInstTable(InstTable, "OR"  , InstrZ++, DecodeALU);
  2065.   AddInstTable(InstTable, "XOR" , InstrZ++, DecodeALU);
  2066.  
  2067.   InstrZ = 0;
  2068.   AddReg("NEG" , 3, 0x0b);
  2069.   AddReg("CPL" , 3, 0x0a);
  2070.   AddReg("SEXT", 3, 0x09);
  2071.   AddReg("DA"  , 1, 0x08);
  2072.  
  2073.   AddInstTable(InstTable, "LSR" , 0, DecodeShift);
  2074.   AddInstTable(InstTable, "ASL" , 1, DecodeShift);
  2075.   AddInstTable(InstTable, "ASR" , 2, DecodeShift);
  2076.   AddInstTable(InstTable, "NORM", 3, DecodeShift);
  2077.  
  2078.   AddRotate("RR" , 0xb0); AddRotate("RL" , 0xd3);
  2079.   AddRotate("RRC", 0xb7); AddRotate("RLC", 0xd7);
  2080.  
  2081.   InstrZ = 0;
  2082.   AddRel("BCC", 0xf0); AddRel("BCS", 0xf1); AddRel("BNE", 0xf2);
  2083.   AddRel("BEQ", 0xf3); AddRel("BNV", 0xf4); AddRel("BOV", 0xf5);
  2084.   AddRel("BPL", 0xf6); AddRel("BMI", 0xf7); AddRel("BG" , 0xf8);
  2085.   AddRel("BL" , 0xf9); AddRel("BGE", 0xfa); AddRel("BLT", 0xfb);
  2086.   AddRel("BGT", 0xfc); AddRel("BLE", 0xfd); AddRel("BR" , 0xfe);
  2087.   AddRel("JZ" , 0xec); AddRel("JNZ", 0xee);
  2088.   SetInv("BCC", "BCS", RelOrders);
  2089.   SetInv("BNE", "BEQ", RelOrders);
  2090.   SetInv("BNV", "BOV", RelOrders);
  2091.   SetInv("BPL", "BMI", RelOrders);
  2092.   SetInv("BG" , "BL" , RelOrders);
  2093.   SetInv("BGE", "BLT", RelOrders);
  2094.   SetInv("BGT", "BLE", RelOrders);
  2095.   SetInv("JZ" , "JNZ", RelOrders);
  2096.  
  2097.   AddIntelPseudo(InstTable, eIntPseudoFlag_LittleEndian);
  2098.   AddInstTable(InstTable, "DC", e_moto_pseudo_flags_le, DecodeMotoDC);
  2099. }
  2100.  
  2101. static void DeinitFields(void)
  2102. {
  2103.   order_array_free(JBitOrders);
  2104.   order_array_free(RegOrders);
  2105.   order_array_free(RelOrders);
  2106.  
  2107.   DestroyInstTable(InstTable);
  2108. }
  2109.  
  2110. /*-------------------------------------------------------------------------*/
  2111. /* Callbacks */
  2112.  
  2113. /*!------------------------------------------------------------------------
  2114.  * \fn     InternSymbol_XA(char *pArg, TempResult *pResult)
  2115.  * \brief  handle built-in symbols on XA
  2116.  * \param  pArg source argument
  2117.  * \param  pResult result buffer
  2118.  * ------------------------------------------------------------------------ */
  2119.  
  2120. static void InternSymbol_XA(char *pArg, TempResult *pResult)
  2121. {
  2122.   Byte Reg;
  2123.   tSymbolSize Size;
  2124.  
  2125.   if (*AttrPart.str.p_str)
  2126.     OpSize = AttrPartOpSize[0];
  2127.  
  2128.   if (DecodeRegCore(pArg, &Size, &Reg))
  2129.   {
  2130.     pResult->Typ = TempReg;
  2131.     pResult->DataSize = Size;
  2132.     pResult->Contents.RegDescr.Reg = Reg;
  2133.     pResult->Contents.RegDescr.Dissect = DissectReg_XA;
  2134.     pResult->Contents.RegDescr.compare = NULL;
  2135.   }
  2136. }
  2137.  
  2138. static void InitCode_XA(void)
  2139. {
  2140.   Reg_DS = 0;
  2141. }
  2142.  
  2143. static Boolean ChkPC_XA(LargeWord Addr)
  2144. {
  2145.   switch (ActPC)
  2146.   {
  2147.     case SegCode:
  2148.     case SegData:
  2149.       return (Addr<0x1000000);
  2150.     case SegIO:
  2151.       return ((Addr > 0x3ff) && (Addr < 0x800));
  2152.     default:
  2153.       return False;
  2154.   }
  2155. }
  2156.  
  2157. static Boolean IsDef_XA(void)
  2158. {
  2159.   return (ActPC == SegCode) || IsRealDef();
  2160. }
  2161.  
  2162. static void SwitchTo_XA(void)
  2163. {
  2164.   TurnWords = False;
  2165.   SetIntConstMode(eIntConstModeIntel);
  2166.  
  2167.   PCSymbol = "$"; HeaderID = 0x3c; NOPCode = 0x00;
  2168.   DivideChars = ","; HasAttrs = True; AttrChars = ".";
  2169.  
  2170.   ValidSegs =(1 << SegCode) | (1 << SegData) | (1 << SegIO);
  2171.   Grans[SegCode ] = 1; ListGrans[SegCode ] = 1; SegInits[SegCode ] = 0;
  2172.   Grans[SegData ] = 1; ListGrans[SegData ] = 1; SegInits[SegData ] = 0;
  2173.   Grans[SegIO   ] = 1; ListGrans[SegIO   ] = 1; SegInits[SegIO   ] = 0x400;
  2174.  
  2175.   DecodeAttrPart = DecodeAttrPart_XA;
  2176.   MakeCode = MakeCode_XA;
  2177.   ChkPC = ChkPC_XA;
  2178.   IsDef = IsDef_XA;
  2179.   InternSymbol = InternSymbol_XA;
  2180.   DissectReg = DissectReg_XA;
  2181.   SwitchFrom = DeinitFields; InitFields();
  2182.   onoff_supmode_add();
  2183.   if (!onoff_test_and_set(e_onoff_reg_branchext))
  2184.     SetFlag(&DoBranchExt, BranchExtSymName, False);
  2185.   AddONOFF(BranchExtCmdName, &DoBranchExt, BranchExtSymName , False);
  2186.   AddMoto16PseudoONOFF(False);
  2187.  
  2188.   pASSUMERecs = ASSUMEXAs;
  2189.   ASSUMERecCnt = ASSUMEXACount;
  2190. }
  2191.  
  2192. void codexa_init(void)
  2193. {
  2194.   CPUXAG1 = AddCPU("XAG1", SwitchTo_XA);
  2195.   CPUXAG2 = AddCPU("XAG2", SwitchTo_XA);
  2196.   CPUXAG3 = AddCPU("XAG3", SwitchTo_XA);
  2197.  
  2198.   AddInitPassProc(InitCode_XA);
  2199. }
  2200.