Subversion Repositories pentevo

Rev

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

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