Subversion Repositories pentevo

Rev

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

  1. /* code51.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator fuer MCS-51/252 Prozessoren                                 */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "bpemu.h"
  16. #include "strutil.h"
  17. #include "chunks.h"
  18. #include "asmdef.h"
  19. #include "asmsub.h"
  20. #include "asmpars.h"
  21. #include "asmallg.h"
  22. #include "onoff_common.h"
  23. #include "asmrelocs.h"
  24. #include "asmlist.h"
  25. #include "codepseudo.h"
  26. #include "intpseudo.h"
  27. #include "asmitree.h"
  28. #include "codevars.h"
  29. #include "fileformat.h"
  30. #include "errmsg.h"
  31. #include "intformat.h"
  32.  
  33. #include "code51.h"
  34.  
  35. /*-------------------------------------------------------------------------*/
  36. /* Daten */
  37.  
  38. typedef struct
  39. {
  40.   CPUVar MinCPU;
  41.   Word Code;
  42. } FixedOrder;
  43.  
  44. enum
  45. {
  46.   ModNone = -1,
  47.   ModReg = 1,
  48.   ModIReg8 = 2,
  49.   ModIReg = 3,
  50.   ModInd = 5,
  51.   ModImm = 7,
  52.   ModImmEx = 8,
  53.   ModDir8 = 9,
  54.   ModDir16 = 10,
  55.   ModAcc = 11,
  56.   ModBit51 = 12,
  57.   ModBit251 = 13
  58. };
  59.  
  60. #define MModReg (1 << ModReg)
  61. #define MModIReg8 (1 << ModIReg8)
  62. #define MModIReg (1 << ModIReg)
  63. #define MModInd (1 << ModInd)
  64. #define MModImm (1 << ModImm)
  65. #define MModImmEx (1 << ModImmEx)
  66. #define MModDir8 (1 << ModDir8)
  67. #define MModDir16 (1 << ModDir16)
  68. #define MModAcc (1 << ModAcc)
  69. #define MModBit51 (1 << ModBit51)
  70. #define MModBit251 (1 << ModBit251)
  71.  
  72. #define MMod51 (MModReg | MModIReg8 | MModImm | MModAcc | MModDir8)
  73. #define MMod251 (MModIReg | MModInd | MModImmEx | MModDir16)
  74.  
  75. #define AccReg 11
  76. #define DPXValue 14
  77. #define SPXValue 15
  78.  
  79. static FixedOrder *FixedOrders;
  80. static FixedOrder *AccOrders;
  81. static FixedOrder *CondOrders;
  82. static FixedOrder *BCondOrders;
  83.  
  84. static Byte AdrVals[5];
  85. static Byte AdrPart, AdrSize;
  86. static ShortInt AdrMode,OpSize;
  87. static Boolean MinOneIs0;
  88.  
  89. static Boolean SrcMode;
  90.  
  91. static CPUVar CPU87C750, CPU8051, CPU8052, CPU80C320,
  92.        CPU80501, CPU80502, CPU80504, CPU80515, CPU80517,
  93.        CPU80C390,
  94.        CPU80251, CPU80251T;
  95.  
  96. static PRelocEntry AdrRelocInfo, BackupAdrRelocInfo;
  97. static LongWord AdrOffset, AdrRelocType,
  98.                 BackupAdrOffset, BackupAdrRelocType;
  99.  
  100. /*-------------------------------------------------------------------------*/
  101. /* Adressparser */
  102.  
  103. static void SetOpSize(ShortInt NewSize)
  104. {
  105.   if (OpSize == -1)
  106.     OpSize = NewSize;
  107.   else if (OpSize != NewSize)
  108.   {
  109.     WrError(ErrNum_ConfOpSizes);
  110.     AdrMode = ModNone;
  111.     AdrCnt = 0;
  112.   }
  113. }
  114.  
  115. /*!------------------------------------------------------------------------
  116.  * \fn     DecodeRegCore(const char *pAsc, tRegInt *pValue, tSymbolSize *pSize)
  117.  * \brief  check whether argument describes a CPU register
  118.  * \param  pAsc argument
  119.  * \param  pValue resulting register # if yes
  120.  * \param  pSize resulting register size if yes
  121.  * \return true if yes
  122.  * ------------------------------------------------------------------------ */
  123.  
  124. static Boolean DecodeRegCore(const char *pAsc, tRegInt *pValue, tSymbolSize *pSize)
  125. {
  126.   static Byte Masks[3] = { 0, 1, 3 };
  127.  
  128.   const char *Start;
  129.   int alen = strlen(pAsc);
  130.   Boolean IO;
  131.  
  132.   if (!as_strcasecmp(pAsc, "DPX"))
  133.   {
  134.     *pValue = DPXValue;
  135.     *pSize = eSymbolSize32Bit;
  136.     return True;
  137.   }
  138.  
  139.   if (!as_strcasecmp(pAsc, "SPX"))
  140.   {
  141.     *pValue = SPXValue;
  142.     *pSize = eSymbolSize32Bit;
  143.     return True;
  144.   }
  145.  
  146.   if ((alen >= 2) && (as_toupper(*pAsc) == 'R'))
  147.   {
  148.     Start = pAsc + 1;
  149.     *pSize = eSymbolSize8Bit;
  150.   }
  151.   else if ((MomCPU >= CPU80251) && (alen >= 3) && (as_toupper(*pAsc) == 'W') && (as_toupper(pAsc[1]) == 'R'))
  152.   {
  153.     Start = pAsc + 2;
  154.     *pSize = eSymbolSize16Bit;
  155.   }
  156.   else if ((MomCPU >= CPU80251) && (alen >= 3) && (as_toupper(*pAsc) == 'D') && (as_toupper(pAsc[1]) == 'R'))
  157.   {
  158.     Start = pAsc + 2;
  159.     *pSize = eSymbolSize32Bit;
  160.   }
  161.   else
  162.     return False;
  163.  
  164.   *pValue = ConstLongInt(Start, &IO, 10);
  165.   if (!IO) return False;
  166.   else if (*pValue & Masks[*pSize]) return False;
  167.   else
  168.   {
  169.     *pValue >>= *pSize;
  170.     switch (*pSize)
  171.     {
  172.       case eSymbolSize8Bit:
  173.         return ((*pValue < 8) || ((MomCPU >= CPU80251) && (*pValue < 16)));
  174.       case eSymbolSize16Bit:
  175.         return (*pValue < 16);
  176.       case eSymbolSize32Bit:
  177.         return ((*pValue < 8) || (*pValue == DPXValue) || (*pValue == SPXValue));
  178.       default:
  179.         return False;
  180.     }
  181.   }
  182. }
  183.  
  184. /*!------------------------------------------------------------------------
  185.  * \fn     DissectReg_51(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  186.  * \brief  dissect register symbols - 80(2)51 variant
  187.  * \param  pDest destination buffer
  188.  * \param  DestSize destination buffer size
  189.  * \param  Value numeric register value
  190.  * \param  InpSize register size
  191.  * ------------------------------------------------------------------------ */
  192.  
  193. static void DissectReg_51(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  194. {
  195.   switch (InpSize)
  196.   {
  197.     case eSymbolSize8Bit:
  198.       as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
  199.       break;
  200.     case eSymbolSize16Bit:
  201.       as_snprintf(pDest, DestSize, "WR%u", (unsigned)Value << 1);
  202.       break;
  203.     case eSymbolSize32Bit:
  204.       if (SPXValue == Value)
  205.         strmaxcpy(pDest, "SPX", DestSize);
  206.       else if (DPXValue == Value)
  207.         strmaxcpy(pDest, "DPX", DestSize);
  208.       else
  209.         as_snprintf(pDest, DestSize, "DR%u", (unsigned)Value << 2);
  210.       break;
  211.     default:
  212.       as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
  213.   }
  214. }
  215.  
  216. /*!------------------------------------------------------------------------
  217.  * \fn     DecodeReg(const tStrComp *pArg, Byte *pValue, tSymbolSize *pSize, Boolean MustBeReg)
  218.  * \brief  check whether argument is a CPU register or user-defined register alias
  219.  * \param  pArg argument
  220.  * \param  pValue resulting register # if yes
  221.  * \param  pSize resulting register size if yes
  222.  * \param  MustBeReg operand must be a register
  223.  * \return reg eval result
  224.  * ------------------------------------------------------------------------ */
  225.  
  226. static tRegEvalResult DecodeReg(const tStrComp *pArg, Byte *pValue, tSymbolSize *pSize, Boolean MustBeReg)
  227. {
  228.   tRegDescr RegDescr;
  229.   tEvalResult EvalResult;
  230.   tRegEvalResult RegEvalResult;
  231.  
  232.   if (DecodeRegCore(pArg->str.p_str, &RegDescr.Reg, pSize))
  233.   {
  234.     *pValue = RegDescr.Reg;
  235.     return eIsReg;
  236.   }
  237.  
  238.   RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
  239.   *pValue = RegDescr.Reg;
  240.   *pSize = EvalResult.DataSize;
  241.   return RegEvalResult;
  242. }
  243.  
  244. static void SaveAdrRelocs(LongWord Type, LongWord Offset)
  245. {
  246.   AdrOffset = Offset;
  247.   AdrRelocType = Type;
  248.   AdrRelocInfo = LastRelocs;
  249.   LastRelocs = NULL;
  250. }
  251.  
  252. static void SaveBackupAdrRelocs(void)
  253. {
  254.   BackupAdrOffset = AdrOffset;
  255.   BackupAdrRelocType = AdrRelocType;
  256.   BackupAdrRelocInfo = AdrRelocInfo;
  257.   AdrRelocInfo = NULL;
  258. }
  259.  
  260. static void TransferAdrRelocs(LongWord Offset)
  261. {
  262.   TransferRelocs2(AdrRelocInfo, ProgCounter() + AdrOffset + Offset, AdrRelocType);
  263.   AdrRelocInfo = NULL;
  264. }
  265.  
  266. static void TransferBackupAdrRelocs(LargeWord Offset)
  267. {
  268.   TransferRelocs2(BackupAdrRelocInfo, ProgCounter() + BackupAdrOffset + Offset, BackupAdrRelocType);
  269.   AdrRelocInfo = NULL;
  270. }
  271.  
  272. static void DecodeAdr(tStrComp *pArg, Word Mask)
  273. {
  274.   Boolean OK, FirstFlag;
  275.   tEvalResult EvalResult;
  276.   tSymbolSize HSize;
  277.   Word H16;
  278.   LongWord H32;
  279.   tStrComp SegComp, AddrComp, *pAddrComp;
  280.   int SegType;
  281.   char Save = '\0', *pSegSepPos;
  282.   Word ExtMask;
  283.  
  284.   AdrMode = ModNone; AdrCnt = 0;
  285.  
  286.   ExtMask = MMod251 & Mask;
  287.   if (MomCPU < CPU80251) Mask &= MMod51;
  288.  
  289.   if (!*pArg->str.p_str)
  290.      return;
  291.  
  292.   if (!as_strcasecmp(pArg->str.p_str, "A"))
  293.   {
  294.     if (!(Mask & MModAcc))
  295.     {
  296.       AdrMode = ModReg;
  297.       AdrPart = AccReg;
  298.     }
  299.     else
  300.       AdrMode = ModAcc;
  301.     SetOpSize(0);
  302.     goto chk;
  303.   }
  304.  
  305.   if (*pArg->str.p_str == '#')
  306.   {
  307.     tStrComp Comp;
  308.  
  309.     StrCompRefRight(&Comp, pArg, 1);
  310.     if ((OpSize == -1) && (MinOneIs0)) OpSize = 0;
  311.     switch (OpSize)
  312.     {
  313.       case -1:
  314.         WrError(ErrNum_UndefOpSizes);
  315.         break;
  316.       case 0:
  317.         AdrVals[0] = EvalStrIntExpression(&Comp, Int8, &OK);
  318.         if (OK)
  319.         {
  320.           AdrMode = ModImm;
  321.           AdrCnt = 1;
  322.           SaveAdrRelocs(RelocTypeB8, 0);
  323.         }
  324.         break;
  325.       case 1:
  326.         H16 = EvalStrIntExpression(&Comp, Int16, &OK);
  327.         if (OK)
  328.         {
  329.           AdrVals[0] = Hi(H16);
  330.           AdrVals[1] = Lo(H16);
  331.           AdrMode = ModImm;
  332.           AdrCnt = 2;
  333.           SaveAdrRelocs(RelocTypeB16, 0);
  334.         }
  335.         break;
  336.       case 2:
  337.         H32 = EvalStrIntExpressionWithResult(&Comp, Int32, &EvalResult);
  338.         if (mFirstPassUnknown(EvalResult.Flags))
  339.           H32 &= 0xffff;
  340.         if (EvalResult.OK)
  341.         {
  342.           AdrVals[1] = H32 & 0xff;
  343.           AdrVals[0] = (H32 >> 8) & 0xff;
  344.           H32 >>= 16;
  345.           if (H32 == 0)
  346.             AdrMode = ModImm;
  347.           else if ((H32 == 1) || (H32 == 0xffff))
  348.             AdrMode = ModImmEx;
  349.           else
  350.             WrError(ErrNum_UndefOpSizes);
  351.           if (AdrMode != ModNone)
  352.             AdrCnt = 2;
  353.           SaveAdrRelocs(RelocTypeB16, 0);
  354.         }
  355.         break;
  356.       case 3:
  357.         H32 = EvalStrIntExpression(&Comp, Int24, &OK);
  358.         if (OK)
  359.         {
  360.           AdrVals[0] = (H32 >> 16) & 0xff;
  361.           AdrVals[1] = (H32 >> 8) & 0xff;
  362.           AdrVals[2] = H32 & 0xff;
  363.           AdrCnt = 3;
  364.           AdrMode = ModImm;
  365.           SaveAdrRelocs(RelocTypeB24, 0);
  366.         }
  367.         break;
  368.     }
  369.     goto chk;
  370.   }
  371.  
  372.   switch (DecodeReg(pArg, &AdrPart, &HSize, False))
  373.   {
  374.     case eIsReg:
  375.       if ((MomCPU >= CPU80251) && ((Mask & MModReg) == 0))
  376.         AdrMode = ((HSize == 0) && (AdrPart == AccReg)) ? ModAcc : ModReg;
  377.       else
  378.         AdrMode = ModReg;
  379.       SetOpSize(HSize);
  380.       goto chk;
  381.     case eIsNoReg:
  382.       break;
  383.     case eRegAbort:
  384.       return;
  385.   }
  386.  
  387.   if (*pArg->str.p_str == '@')
  388.   {
  389.     tStrComp IndirComp;
  390.     char *PPos, *MPos;
  391.  
  392.     StrCompRefRight(&IndirComp, pArg, 1);
  393.     PPos = strchr(IndirComp.str.p_str, '+');
  394.     MPos = strchr(IndirComp.str.p_str, '-');
  395.     if ((MPos) && ((MPos < PPos) || (!PPos)))
  396.       PPos = MPos;
  397.     if (PPos)
  398.     {
  399.       Save = *PPos;
  400.       *PPos = '\0';
  401.       IndirComp.Pos.Len = PPos - IndirComp.str.p_str;
  402.     }
  403.     switch (DecodeReg(&IndirComp, &AdrPart, &HSize, False))
  404.     {
  405.       case eIsReg:
  406.       {
  407.         if (!PPos)
  408.         {
  409.           H32 = 0;
  410.           OK = True;
  411.         }
  412.         else
  413.         {
  414.           tStrComp DispComp;
  415.  
  416.           *PPos = Save;
  417.           StrCompRefRight(&DispComp, &IndirComp, PPos - IndirComp.str.p_str + !!(Save == '+'));
  418.           H32 = EvalStrIntExpression(&DispComp, SInt16, &OK);
  419.         }
  420.         if (OK)
  421.           switch (HSize)
  422.           {
  423.             case eSymbolSize8Bit:
  424.               if ((AdrPart>1) || (H32 != 0)) WrError(ErrNum_InvAddrMode);
  425.               else
  426.                 AdrMode = ModIReg8;
  427.               break;
  428.             case eSymbolSize16Bit:
  429.               if (H32 == 0)
  430.               {
  431.                 AdrMode = ModIReg;
  432.                 AdrSize = 0;
  433.               }
  434.               else
  435.               {
  436.                 AdrMode = ModInd;
  437.                 AdrSize = 0;
  438.                 AdrVals[1] = H32 & 0xff;
  439.                 AdrVals[0] = (H32 >> 8) & 0xff;
  440.                 AdrCnt = 2;
  441.               }
  442.               break;
  443.             case eSymbolSize32Bit:
  444.               if (H32 == 0)
  445.               {
  446.                 AdrMode = ModIReg;
  447.                 AdrSize = 2;
  448.               }
  449.               else
  450.               {
  451.                 AdrMode = ModInd;
  452.                 AdrSize = 2;
  453.                 AdrVals[1] = H32 & 0xff;
  454.                 AdrVals[0] = (H32 >> 8) & 0xff;
  455.                 AdrCnt = 2;
  456.               }
  457.               break;
  458.             default:
  459.               break;
  460.           }
  461.         break;
  462.       }
  463.       case eIsNoReg:
  464.         WrStrErrorPos(ErrNum_InvReg, &IndirComp);
  465.         break;
  466.       case eRegAbort:
  467.         /* will go to function end anyway after restoring separator */
  468.         break;
  469.     }
  470.     if (PPos)
  471.       *PPos = Save;
  472.     goto chk;
  473.   }
  474.  
  475.   FirstFlag = False;
  476.   SegType = -1;
  477.   pSegSepPos = QuotPos(pArg->str.p_str, ':');
  478.   if (pSegSepPos)
  479.   {
  480.     StrCompSplitRef(&SegComp, &AddrComp, pArg, pSegSepPos);
  481.     if (MomCPU < CPU80251)
  482.     {
  483.       WrError(ErrNum_InvAddrMode);
  484.       return;
  485.     }
  486.     else
  487.     {
  488.       if (!as_strcasecmp(SegComp.str.p_str, "S"))
  489.         SegType = -2;
  490.       else
  491.       {
  492.         SegType = EvalStrIntExpressionWithResult(&SegComp, UInt8, &EvalResult);
  493.         if (!EvalResult.OK)
  494.           return;
  495.         if (mFirstPassUnknown(EvalResult.Flags))
  496.           FirstFlag = True;
  497.       }
  498.     }
  499.     pAddrComp = &AddrComp;
  500.   }
  501.   else
  502.     pAddrComp = pArg;
  503.  
  504.   switch (SegType)
  505.   {
  506.     case -2:
  507.       H32 = EvalStrIntExpressionWithResult(pAddrComp, UInt9, &EvalResult);
  508.       ChkSpace(SegIO, EvalResult.AddrSpaceMask);
  509.       if (mFirstPassUnknown(EvalResult.Flags))
  510.         H32 = (H32 & 0xff) | 0x80;
  511.       break;
  512.     case -1:
  513.       H32 = EvalStrIntExpressionWithResult(pAddrComp, UInt24, &EvalResult);
  514.       break;
  515.     default:
  516.       H32 = EvalStrIntExpressionWithResult(pAddrComp, UInt16, &EvalResult);
  517.   }
  518.   if (mFirstPassUnknown(EvalResult.Flags))
  519.     FirstFlag = True;
  520.   if (!EvalResult.OK)
  521.     return;
  522.  
  523.   if ((SegType == -2) || ((SegType == -1) && (EvalResult.AddrSpaceMask & (1 << SegIO))))
  524.   {
  525.     if (ChkRange(H32, 0x80, 0xff))
  526.     {
  527.       SaveAdrRelocs(RelocTypeB8, 0);
  528.       AdrMode = ModDir8;
  529.       AdrVals[0] = H32 & 0xff;
  530.       AdrCnt = 1;
  531.     }
  532.   }
  533.  
  534.   else
  535.   {
  536.     if (SegType >= 0)
  537.       H32 += ((LongWord)SegType) << 16;
  538.     if (FirstFlag)
  539.       H32 &= ((MomCPU < CPU80251) || ((Mask & ModDir16) == 0)) ? 0xff : 0xffff;
  540.  
  541.     if (((H32 < 128) || ((H32 < 256) && (MomCPU < CPU80251))) && ((Mask & MModDir8) != 0))
  542.     {
  543.       if (MomCPU < CPU80251)
  544.         ChkSpace(SegData, EvalResult.AddrSpaceMask);
  545.       SaveAdrRelocs(RelocTypeB8, 0);
  546.       AdrMode = ModDir8;
  547.       AdrVals[0] = H32 &0xff;
  548.       AdrCnt = 1;
  549.     }
  550.     else if ((MomCPU < CPU80251) || (H32 > 0xffff)) WrError(ErrNum_AdrOverflow);
  551.     else
  552.     {
  553.       AdrMode = ModDir16;
  554.       AdrCnt = 2;
  555.       AdrVals[1] = H32 & 0xff;
  556.       AdrVals[0] = (H32 >> 8) & 0xff;
  557.     }
  558.   }
  559.  
  560. chk:
  561.   if ((AdrMode != ModNone) && ((Mask & (1 << AdrMode)) == 0))
  562.   {
  563.     if (ExtMask & (1 << AdrMode))
  564.       (void)ChkMinCPUExt(CPU80251, ErrNum_AddrModeNotSupported);
  565.     else
  566.       WrError(ErrNum_InvAddrMode);
  567.     AdrCnt = 0;
  568.     AdrMode = ModNone;
  569.   }
  570. }
  571.  
  572. static void DissectBit_251(char *pDest, size_t DestSize, LargeWord Inp)
  573. {
  574.   as_snprintf(pDest, DestSize, "%~02.*u%s.%u",
  575.               ListRadixBase, (unsigned)(Inp & 0xff), GetIntConstIntelSuffix(ListRadixBase),
  576.               (unsigned)(Inp >> 24));
  577. }
  578.  
  579. static ShortInt DecodeBitAdr(tStrComp *pArg, LongInt *Erg, Boolean MayShorten)
  580. {
  581.   tEvalResult EvalResult;
  582.   char *pPos, Save = '\0';
  583.   tStrComp RegPart, BitPart;
  584.  
  585.   pPos = RQuotPos(pArg->str.p_str, '.');
  586.   if (pPos)
  587.     Save = StrCompSplitRef(&RegPart, &BitPart, pArg, pPos);
  588.   if (MomCPU < CPU80251)
  589.   {
  590.     if (!pPos)
  591.     {
  592.       *Erg = EvalStrIntExpressionWithResult(pArg, UInt8, &EvalResult);
  593.       if (EvalResult.OK)
  594.       {
  595.         ChkSpace(SegBData, EvalResult.AddrSpaceMask);
  596.         return ModBit51;
  597.       }
  598.       else
  599.         return ModNone;
  600.     }
  601.     else
  602.     {
  603.       *Erg = EvalStrIntExpressionWithResult(&RegPart, UInt8, &EvalResult);
  604.       if (mFirstPassUnknown(EvalResult.Flags))
  605.         *Erg = 0x20;
  606.       *pPos = Save;
  607.       if (!EvalResult.OK) return ModNone;
  608.       else
  609.       {
  610.         ChkSpace(SegData, EvalResult.AddrSpaceMask);
  611.         Save = EvalStrIntExpressionWithResult(&BitPart, UInt3, &EvalResult);
  612.         if (!EvalResult.OK) return ModNone;
  613.         else
  614.         {
  615.           if (*Erg > 0x7f)
  616.           {
  617.             if ((*Erg) & 7)
  618.               WrError(ErrNum_NotBitAddressable);
  619.           }
  620.           else
  621.           {
  622.             if (((*Erg) & 0xe0) != 0x20)
  623.               WrError(ErrNum_NotBitAddressable);
  624.             *Erg = (*Erg - 0x20) << 3;
  625.           }
  626.           *Erg += Save;
  627.           return ModBit51;
  628.         }
  629.       }
  630.     }
  631.   }
  632.   else
  633.   {
  634.     if (!pPos)
  635.     {
  636.       static const LongWord ValidBits = 0x070000fful;
  637.  
  638.       *Erg = EvalStrIntExpressionWithResult(pArg, Int32, &EvalResult);
  639.       if (mFirstPassUnknown(EvalResult.Flags))
  640.         *Erg &= ValidBits;
  641.       if (*Erg & ~ValidBits)
  642.       {
  643.         WrError(ErrNum_InvBitPos);
  644.         EvalResult.OK = False;
  645.       }
  646.     }
  647.     else
  648.     {
  649.       DecodeAdr(&RegPart, MModDir8);
  650.       *pPos = Save;
  651.       if (AdrMode == ModNone)
  652.         EvalResult.OK = False;
  653.       else
  654.       {
  655.         *Erg = EvalStrIntExpressionWithResult(&BitPart, UInt3, &EvalResult) << 24;
  656.         if (EvalResult.OK)
  657.           (*Erg) += AdrVals[0];
  658.       }
  659.     }
  660.     if (!EvalResult.OK)
  661.       return ModNone;
  662.     else if (MayShorten)
  663.     {
  664.       if (((*Erg) & 0x87) == 0x80)
  665.       {
  666.         *Erg = ((*Erg) & 0xf8) + ((*Erg) >> 24);
  667.         return ModBit51;
  668.       }
  669.       else if (((*Erg) & 0xf0) == 0x20)
  670.       {
  671.         *Erg = (((*Erg) & 0x0f) << 3) + ((*Erg) >> 24);
  672.         return ModBit51;
  673.       }
  674.       else
  675.         return ModBit251;
  676.     }
  677.     else
  678.       return ModBit251;
  679.   }
  680. }
  681.  
  682. static Boolean Chk504(LongInt Adr)
  683. {
  684.   return ((MomCPU == CPU80504) && ((Adr & 0x7ff) == 0x7fe));
  685. }
  686.  
  687. static Boolean NeedsPrefix(Word Opcode)
  688. {
  689.   return (((Opcode&0x0f) >= 6) && ((SrcMode != 0) != ((Hi(Opcode) != 0) != 0)));
  690. }
  691.  
  692. static void PutCode(Word Opcode)
  693. {
  694.   if (((Opcode&0x0f) < 6) || ((SrcMode != 0) != ((Hi(Opcode) == 0) != 0)))
  695.   {
  696.     BAsmCode[0] = Lo(Opcode);
  697.     CodeLen = 1;
  698.   }
  699.   else
  700.   {
  701.     BAsmCode[0] = 0xa5;
  702.     BAsmCode[1] = Lo(Opcode);
  703.     CodeLen = 2;
  704.   }
  705. }
  706.  
  707. static Boolean IsCarry(const char *pArg)
  708. {
  709.   return (!as_strcasecmp(pArg, "C")) || (!as_strcasecmp(pArg, "CY"));
  710. }
  711.  
  712. /*-------------------------------------------------------------------------*/
  713. /* Einzelfaelle */
  714.  
  715. static void DecodeMOV(Word Index)
  716. {
  717.   LongInt AdrLong;
  718.   Byte HSize, HReg;
  719.   Integer AdrInt;
  720.   UNUSED(Index);
  721.  
  722.   if (!ChkArgCnt(2, 2));
  723.   else if (IsCarry(ArgStr[1].str.p_str))
  724.   {
  725.     switch (DecodeBitAdr(&ArgStr[2], &AdrLong, True))
  726.     {
  727.       case ModBit51:
  728.         PutCode(0xa2);
  729.         BAsmCode[CodeLen] = AdrLong & 0xff;
  730.         CodeLen++;
  731.         break;
  732.       case ModBit251:
  733.         PutCode(0x1a9);
  734.         BAsmCode[CodeLen  ] = 0xa0 + (AdrLong >> 24);
  735.         BAsmCode[CodeLen + 1] = AdrLong & 0xff;
  736.         CodeLen+=2;
  737.         break;
  738.     }
  739.   }
  740.   else if ((!as_strcasecmp(ArgStr[2].str.p_str, "C")) || (!as_strcasecmp(ArgStr[2].str.p_str, "CY")))
  741.   {
  742.     switch (DecodeBitAdr(&ArgStr[1], &AdrLong, True))
  743.     {
  744.       case ModBit51:
  745.         PutCode(0x92);
  746.         BAsmCode[CodeLen] = AdrLong & 0xff;
  747.         CodeLen++;
  748.         break;
  749.       case ModBit251:
  750.         PutCode(0x1a9);
  751.         BAsmCode[CodeLen] = 0x90 + (AdrLong >> 24);
  752.         BAsmCode[CodeLen + 1] = AdrLong & 0xff;
  753.         CodeLen+=2;
  754.         break;
  755.     }
  756.   }
  757.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "DPTR"))
  758.   {
  759.     SetOpSize((MomCPU == CPU80C390) ? 3 : 1);
  760.     DecodeAdr(&ArgStr[2], MModImm);
  761.     switch (AdrMode)
  762.     {
  763.       case ModImm:
  764.         PutCode(0x90);
  765.         memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  766.         TransferAdrRelocs(CodeLen);
  767.         CodeLen += AdrCnt;
  768.         break;
  769.     }
  770.   }
  771.   else
  772.   {
  773.     DecodeAdr(&ArgStr[1], MModAcc | MModReg | MModIReg8 | MModIReg | MModInd | MModDir8 | MModDir16);
  774.     switch (AdrMode)
  775.     {
  776.       case ModAcc:
  777.         DecodeAdr(&ArgStr[2], MModReg | MModIReg8 | MModIReg | MModInd | MModDir8 | MModDir16 | MModImm);
  778.         switch (AdrMode)
  779.         {
  780.           case ModReg:
  781.             if ((AdrPart < 8) && (!SrcMode))
  782.               PutCode(0xe8 + AdrPart);
  783.             else if (ChkMinCPUExt(CPU80251, ErrNum_AddrModeNotSupported))
  784.             {
  785.               PutCode(0x17c);
  786.               BAsmCode[CodeLen++] = (AccReg << 4) + AdrPart;
  787.             }
  788.             break;
  789.           case ModIReg8:
  790.             PutCode(0xe6 + AdrPart);
  791.             break;
  792.           case ModIReg:
  793.             PutCode(0x17e);
  794.             BAsmCode[CodeLen++] = (AdrPart << 4) + 0x09 + AdrSize;
  795.             BAsmCode[CodeLen++] = (AccReg << 4);
  796.             break;
  797.           case ModInd:
  798.             PutCode(0x109 + (AdrSize << 4));
  799.             BAsmCode[CodeLen++] = (AccReg << 4) + AdrPart;
  800.             memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  801.             CodeLen += AdrCnt;
  802.             break;
  803.           case ModDir8:
  804.             PutCode(0xe5);
  805.             TransferAdrRelocs(CodeLen);
  806.             BAsmCode[CodeLen++] = AdrVals[0];
  807.             break;
  808.           case ModDir16:
  809.             PutCode(0x17e);
  810.             BAsmCode[CodeLen++] = (AccReg << 4) + 0x03;
  811.             memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  812.             CodeLen += AdrCnt;
  813.             break;
  814.           case ModImm:
  815.             PutCode(0x74);
  816.             TransferAdrRelocs(CodeLen);
  817.             BAsmCode[CodeLen++] = AdrVals[0];
  818.             break;
  819.         }
  820.         break;
  821.       case ModReg:
  822.         HReg = AdrPart;
  823.         DecodeAdr(&ArgStr[2], MModReg | MModIReg8 | MModIReg | MModInd | MModDir8 | MModDir16 | MModImm | MModImmEx);
  824.         switch (AdrMode)
  825.         {
  826.           case ModReg:
  827.             if ((OpSize == 0) && (AdrPart == AccReg) && (HReg < 8))
  828.               PutCode(0xf8 + HReg);
  829.             else if ((OpSize == 0) && (HReg == AccReg) && (AdrPart < 8))
  830.               PutCode(0xe8 + AdrPart);
  831.             else if (ChkMinCPUExt(CPU80251, ErrNum_AddrModeNotSupported))
  832.             {
  833.               PutCode(0x17c + OpSize);
  834.               if (OpSize == 2)
  835.                 BAsmCode[CodeLen - 1]++;
  836.               BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  837.             }
  838.             break;
  839.           case ModIReg8:
  840.             if ((OpSize != 0) || (HReg != AccReg)) WrError(ErrNum_InvAddrMode);
  841.             else
  842.               PutCode(0xe6 + AdrPart);
  843.             break;
  844.           case ModIReg:
  845.             if (OpSize == 0)
  846.             {
  847.               PutCode(0x17e);
  848.               BAsmCode[CodeLen++] = (AdrPart << 4) + 0x09 + AdrSize;
  849.               BAsmCode[CodeLen++] = HReg << 4;
  850.             }
  851.             else if (OpSize == 1)
  852.             {
  853.               PutCode(0x10b);
  854.               BAsmCode[CodeLen++] = (AdrPart << 4) + 0x08 + AdrSize;
  855.               BAsmCode[CodeLen++] = HReg << 4;
  856.             }
  857.             else
  858.               WrError(ErrNum_InvAddrMode);
  859.             break;
  860.           case ModInd:
  861.             if (OpSize == 2) WrError(ErrNum_InvAddrMode);
  862.             else
  863.             {
  864.               PutCode(0x109 + (AdrSize << 4) + (OpSize << 6));
  865.               BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  866.               memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  867.               CodeLen += AdrCnt;
  868.             }
  869.             break;
  870.           case ModDir8:
  871.             if ((OpSize == 0) && (HReg == AccReg))
  872.             {
  873.               PutCode(0xe5);
  874.               TransferAdrRelocs(CodeLen);
  875.               BAsmCode[CodeLen++] = AdrVals[0];
  876.             }
  877.             else if ((OpSize == 0) && (HReg < 8) && (!SrcMode))
  878.             {
  879.               PutCode(0xa8 + HReg);
  880.               TransferAdrRelocs(CodeLen);
  881.               BAsmCode[CodeLen++] = AdrVals[0];
  882.             }
  883.             else if (ChkMinCPUExt(CPU80251, ErrNum_AddrModeNotSupported))
  884.             {
  885.               PutCode(0x17e);
  886.               BAsmCode[CodeLen++] = 0x01 + (HReg << 4) + (OpSize << 2);
  887.               if (OpSize == 2)
  888.                 BAsmCode[CodeLen - 1] += 4;
  889.               TransferAdrRelocs(CodeLen);
  890.               BAsmCode[CodeLen++] = AdrVals[0];
  891.             }
  892.             break;
  893.           case ModDir16:
  894.             PutCode(0x17e);
  895.             BAsmCode[CodeLen++] = 0x03 + (HReg << 4) + (OpSize << 2);
  896.             if (OpSize == 2)
  897.               BAsmCode[CodeLen - 1] += 4;
  898.             memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  899.             CodeLen += AdrCnt;
  900.             break;
  901.           case ModImm:
  902.             if ((OpSize == 0) && (HReg == AccReg))
  903.             {
  904.               PutCode(0x74);
  905.               TransferAdrRelocs(CodeLen);
  906.               BAsmCode[CodeLen++] = AdrVals[0];
  907.             }
  908.             else if ((OpSize == 0) && (HReg < 8) && (!SrcMode))
  909.             {
  910.               PutCode(0x78 + HReg);
  911.               TransferAdrRelocs(CodeLen);
  912.               BAsmCode[CodeLen++] = AdrVals[0];
  913.             }
  914.             else if (ChkMinCPUExt(CPU80251, ErrNum_AddrModeNotSupported))
  915.             {
  916.               PutCode(0x17e);
  917.               BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2);
  918.               memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  919.               CodeLen += AdrCnt;
  920.             }
  921.             break;
  922.           case ModImmEx:
  923.             PutCode(0x17e);
  924.             TransferAdrRelocs(CodeLen);
  925.             BAsmCode[CodeLen++] = 0x0c + (HReg << 4);
  926.             memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  927.             CodeLen += AdrCnt;
  928.             break;
  929.         }
  930.         break;
  931.       case ModIReg8:
  932.         SetOpSize(0); HReg = AdrPart;
  933.         DecodeAdr(&ArgStr[2], MModAcc | MModDir8 | MModImm);
  934.         switch (AdrMode)
  935.         {
  936.           case ModAcc:
  937.             PutCode(0xf6 + HReg);
  938.             break;
  939.           case ModDir8:
  940.             PutCode(0xa6 + HReg);
  941.             TransferAdrRelocs(CodeLen);
  942.             BAsmCode[CodeLen++] = AdrVals[0];
  943.             break;
  944.           case ModImm:
  945.             PutCode(0x76 + HReg);
  946.             TransferAdrRelocs(CodeLen);
  947.             BAsmCode[CodeLen++] = AdrVals[0];
  948.             break;
  949.         }
  950.         break;
  951.       case ModIReg:
  952.         HReg = AdrPart; HSize = AdrSize;
  953.         DecodeAdr(&ArgStr[2], MModReg);
  954.         switch (AdrMode)
  955.         {
  956.           case ModReg:
  957.             if (OpSize == 0)
  958.             {
  959.               PutCode(0x17a);
  960.               BAsmCode[CodeLen++] = (HReg << 4) + 0x09 + HSize;
  961.               BAsmCode[CodeLen++] = AdrPart << 4;
  962.             }
  963.             else if (OpSize == 1)
  964.             {
  965.               PutCode(0x11b);
  966.               BAsmCode[CodeLen++] = (HReg << 4) + 0x08 + HSize;
  967.               BAsmCode[CodeLen++] = AdrPart << 4;
  968.             }
  969.             else
  970.               WrError(ErrNum_InvAddrMode);
  971.         }
  972.         break;
  973.       case ModInd:
  974.         HReg = AdrPart; HSize = AdrSize;
  975.         AdrInt = (((Word)AdrVals[0]) << 8) + AdrVals[1];
  976.         DecodeAdr(&ArgStr[2], MModReg);
  977.         switch (AdrMode)
  978.         {
  979.           case ModReg:
  980.             if (OpSize == 2) WrError(ErrNum_InvAddrMode);
  981.             else
  982.             {
  983.               PutCode(0x119 + (HSize << 4) + (OpSize << 6));
  984.               BAsmCode[CodeLen++] = (AdrPart << 4) + HReg;
  985.               BAsmCode[CodeLen++] = Hi(AdrInt);
  986.               BAsmCode[CodeLen++] = Lo(AdrInt);
  987.             }
  988.         }
  989.         break;
  990.       case ModDir8:
  991.         MinOneIs0 = True;
  992.         HReg = AdrVals[0];
  993.         SaveBackupAdrRelocs();
  994.         DecodeAdr(&ArgStr[2], MModReg | MModIReg8 | MModDir8 | MModImm);
  995.         switch (AdrMode)
  996.         {
  997.           case ModReg:
  998.             if ((OpSize == 0) && (AdrPart == AccReg))
  999.             {
  1000.               PutCode(0xf5);
  1001.               TransferBackupAdrRelocs(CodeLen);
  1002.               BAsmCode[CodeLen++] = HReg;
  1003.             }
  1004.             else if ((OpSize == 0) && (AdrPart < 8) && (!SrcMode))
  1005.             {
  1006.               PutCode(0x88 + AdrPart);
  1007.               TransferBackupAdrRelocs(CodeLen);
  1008.               BAsmCode[CodeLen++] = HReg;
  1009.             }
  1010.             else if (ChkMinCPUExt(CPU80251, ErrNum_AddrModeNotSupported))
  1011.             {
  1012.               PutCode(0x17a);
  1013.               BAsmCode[CodeLen++] = 0x01 + (AdrPart << 4) + (OpSize << 2);
  1014.               if (OpSize == 2)
  1015.                 BAsmCode[CodeLen - 1] += 4;
  1016.               BAsmCode[CodeLen++] = HReg;
  1017.             }
  1018.             break;
  1019.           case ModIReg8:
  1020.             PutCode(0x86 + AdrPart);
  1021.             TransferBackupAdrRelocs(CodeLen);
  1022.             BAsmCode[CodeLen++] = HReg;
  1023.             break;
  1024.           case ModDir8:
  1025.             PutCode(0x85);
  1026.             TransferAdrRelocs(CodeLen);
  1027.             BAsmCode[CodeLen++] = AdrVals[0];
  1028.             TransferBackupAdrRelocs(CodeLen);
  1029.             BAsmCode[CodeLen++] = HReg;
  1030.             break;
  1031.           case ModImm:
  1032.             PutCode(0x75);
  1033.             TransferBackupAdrRelocs(CodeLen);
  1034.             BAsmCode[CodeLen++] = HReg;
  1035.             TransferAdrRelocs(CodeLen);
  1036.             BAsmCode[CodeLen++] = AdrVals[0];
  1037.             break;
  1038.         }
  1039.         break;
  1040.       case ModDir16:
  1041.         AdrInt = (((Word)AdrVals[0]) << 8) + AdrVals[1];
  1042.         DecodeAdr(&ArgStr[2], MModReg);
  1043.         switch (AdrMode)
  1044.         {
  1045.           case ModReg:
  1046.             PutCode(0x17a);
  1047.             BAsmCode[CodeLen++] = 0x03 + (AdrPart << 4) + (OpSize << 2);
  1048.             if (OpSize == 2) BAsmCode[CodeLen - 1] += 4;
  1049.             BAsmCode[CodeLen++] = Hi(AdrInt);
  1050.             BAsmCode[CodeLen++] = Lo(AdrInt);
  1051.             break;
  1052.         }
  1053.         break;
  1054.     }
  1055.   }
  1056. }
  1057.  
  1058. static void DecodeLogic(Word Index)
  1059. {
  1060.   Byte HReg;
  1061.   LongInt AdrLong;
  1062.   int z;
  1063.  
  1064.   /* Index: ORL=0 ANL=1 XRL=2 */
  1065.  
  1066.   if (!ChkArgCnt(2, 2));
  1067.   else if (IsCarry(ArgStr[1].str.p_str))
  1068.   {
  1069.     if (Index == 2) WrError(ErrNum_InvAddrMode);
  1070.     else
  1071.     {
  1072.       Boolean InvFlag;
  1073.       ShortInt Result;
  1074.  
  1075.       HReg = Index << 4;
  1076.       InvFlag = *ArgStr[2].str.p_str == '/';
  1077.       if (InvFlag)
  1078.       {
  1079.         tStrComp Comp;
  1080.  
  1081.         StrCompRefRight(&Comp, &ArgStr[2], 1);
  1082.         Result = DecodeBitAdr(&Comp, &AdrLong, True);
  1083.       }
  1084.       else
  1085.         Result = DecodeBitAdr(&ArgStr[2], &AdrLong, True);
  1086.       switch (Result)
  1087.       {
  1088.         case ModBit51:
  1089.           PutCode((InvFlag) ? 0xa0 + HReg : 0x72 + HReg);
  1090.           BAsmCode[CodeLen++] = AdrLong & 0xff;
  1091.           break;
  1092.         case ModBit251:
  1093.           PutCode(0x1a9);
  1094.           BAsmCode[CodeLen++] = ((InvFlag) ? 0xe0 : 0x70) + HReg + (AdrLong >> 24);
  1095.           BAsmCode[CodeLen++] = AdrLong & 0xff;
  1096.           break;
  1097.       }
  1098.     }
  1099.   }
  1100.   else
  1101.   {
  1102.     z = (Index << 4) + 0x40;
  1103.     DecodeAdr(&ArgStr[1], MModAcc | MModReg | MModDir8);
  1104.     switch (AdrMode)
  1105.     {
  1106.       case ModAcc:
  1107.         DecodeAdr(&ArgStr[2], MModReg | MModIReg8 | MModIReg | MModDir8 | MModDir16 | MModImm);
  1108.         switch (AdrMode)
  1109.         {
  1110.           case ModReg:
  1111.             if ((AdrPart < 8) && (!SrcMode)) PutCode(z + 8 + AdrPart);
  1112.             else
  1113.             {
  1114.               PutCode(z + 0x10c);
  1115.               BAsmCode[CodeLen++] = AdrPart + (AccReg << 4);
  1116.             }
  1117.             break;
  1118.           case ModIReg8:
  1119.             PutCode(z + 6 + AdrPart);
  1120.             break;
  1121.           case ModIReg:
  1122.             PutCode(z + 0x10e);
  1123.             BAsmCode[CodeLen++] = 0x09 + AdrSize + (AdrPart << 4);
  1124.             BAsmCode[CodeLen++] = AccReg << 4;
  1125.             break;
  1126.           case ModDir8:
  1127.             PutCode(z + 0x05);
  1128.             TransferAdrRelocs(CodeLen);
  1129.             BAsmCode[CodeLen++] = AdrVals[0];
  1130.             break;
  1131.           case ModDir16:
  1132.             PutCode(0x10e + z);
  1133.             BAsmCode[CodeLen++] = 0x03 + (AccReg << 4);
  1134.             memcpy(BAsmCode+CodeLen, AdrVals, AdrCnt);
  1135.             CodeLen += AdrCnt;
  1136.             break;
  1137.           case ModImm:
  1138.             PutCode(z + 0x04);
  1139.             TransferAdrRelocs(CodeLen);
  1140.             BAsmCode[CodeLen++] = AdrVals[0];
  1141.             break;
  1142.         }
  1143.         break;
  1144.       case ModReg:
  1145.         if (MomCPU < CPU80251) WrError(ErrNum_InvAddrMode);
  1146.         else
  1147.         {
  1148.           HReg = AdrPart;
  1149.           DecodeAdr(&ArgStr[2], MModReg | MModIReg8 | MModIReg | MModDir8 | MModDir16 | MModImm);
  1150.           switch (AdrMode)
  1151.           {
  1152.             case ModReg:
  1153.               if (OpSize == 2) WrError(ErrNum_InvAddrMode);
  1154.               else
  1155.               {
  1156.                 PutCode(z + 0x10c + OpSize);
  1157.                 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  1158.               }
  1159.               break;
  1160.             case ModIReg8:
  1161.               if ((OpSize != 0) || (HReg != AccReg)) WrError(ErrNum_InvAddrMode);
  1162.               else
  1163.                 PutCode(z + 0x06 + AdrPart);
  1164.               break;
  1165.             case ModIReg:
  1166.               if (OpSize != 0) WrError(ErrNum_InvAddrMode);
  1167.               else
  1168.               {
  1169.                 PutCode(0x10e + z);
  1170.                 BAsmCode[CodeLen++] = 0x09 + AdrSize + (AdrPart << 4);
  1171.                 BAsmCode[CodeLen++] = HReg << 4;
  1172.               }
  1173.               break;
  1174.             case ModDir8:
  1175.               if ((OpSize == 0) && (HReg == AccReg))
  1176.               {
  1177.                 PutCode(0x05 + z);
  1178.                 TransferAdrRelocs(CodeLen);
  1179.                 BAsmCode[CodeLen++] = AdrVals[0];
  1180.               }
  1181.               else if (OpSize == 2) WrError(ErrNum_InvAddrMode);
  1182.               else
  1183.               {
  1184.                 PutCode(0x10e + z);
  1185.                 BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2) + 1;
  1186.                 BAsmCode[CodeLen++] = AdrVals[0];
  1187.               }
  1188.               break;
  1189.             case ModDir16:
  1190.               if (OpSize == 2) WrError(ErrNum_InvAddrMode);
  1191.               else
  1192.               {
  1193.                 PutCode(0x10e + z);
  1194.                 BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2) + 3;
  1195.                 memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  1196.                 CodeLen += AdrCnt;
  1197.               }
  1198.               break;
  1199.             case ModImm:
  1200.               if ((OpSize == 0) && (HReg == AccReg))
  1201.               {
  1202.                 PutCode(0x04 + z);
  1203.                 TransferAdrRelocs(CodeLen);
  1204.                 BAsmCode[CodeLen++] = AdrVals[0];
  1205.               }
  1206.               else if (OpSize == 2) WrError(ErrNum_InvAddrMode);
  1207.               else
  1208.               {
  1209.                 PutCode(0x10e + z);
  1210.                 BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2);
  1211.                 TransferAdrRelocs(CodeLen);
  1212.                 memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  1213.                 CodeLen += AdrCnt;
  1214.               }
  1215.               break;
  1216.           }
  1217.         }
  1218.         break;
  1219.       case ModDir8:
  1220.         HReg = AdrVals[0];
  1221.         SaveBackupAdrRelocs();
  1222.         SetOpSize(0);
  1223.         DecodeAdr(&ArgStr[2], MModAcc | MModImm);
  1224.         switch (AdrMode)
  1225.         {
  1226.           case ModAcc:
  1227.             PutCode(z + 0x02);
  1228.             TransferBackupAdrRelocs(CodeLen);
  1229.             BAsmCode[CodeLen++] = HReg;
  1230.             break;
  1231.           case ModImm:
  1232.             PutCode(z + 0x03);
  1233.             TransferBackupAdrRelocs(CodeLen);
  1234.             BAsmCode[CodeLen++] = HReg;
  1235.             TransferAdrRelocs(CodeLen);
  1236.             BAsmCode[CodeLen++] = AdrVals[0];
  1237.             break;
  1238.         }
  1239.         break;
  1240.     }
  1241.   }
  1242. }
  1243.  
  1244. static void DecodeMOVC(Word Index)
  1245. {
  1246.   UNUSED(Index);
  1247.  
  1248.   if (ChkArgCnt(2, 2))
  1249.   {
  1250.     DecodeAdr(&ArgStr[1], MModAcc);
  1251.     switch (AdrMode)
  1252.     {
  1253.       case ModAcc:
  1254.         if (!as_strcasecmp(ArgStr[2].str.p_str, "@A+DPTR"))
  1255.           PutCode(0x93);
  1256.         else if (!as_strcasecmp(ArgStr[2].str.p_str, "@A+PC"))
  1257.           PutCode(0x83);
  1258.         else
  1259.           WrError(ErrNum_InvAddrMode);
  1260.         break;
  1261.     }
  1262.   }
  1263. }
  1264.  
  1265. static void DecodeMOVH(Word Index)
  1266. {
  1267.   Byte HReg;
  1268.   UNUSED(Index);
  1269.  
  1270.   if (ChkArgCnt(2, 2)
  1271.    && ChkMinCPU(CPU80251))
  1272.   {
  1273.     DecodeAdr(&ArgStr[1], MModReg);
  1274.     switch (AdrMode)
  1275.     {
  1276.       case ModReg:
  1277.         if (OpSize != 2) WrError(ErrNum_InvAddrMode);
  1278.         else
  1279.         {
  1280.           HReg = AdrPart;
  1281.           OpSize--;
  1282.           DecodeAdr(&ArgStr[2], MModImm);
  1283.           switch (AdrMode)
  1284.           {
  1285.             case ModImm:
  1286.               PutCode(0x17a);
  1287.               BAsmCode[CodeLen++] = 0x0c + (HReg << 4);
  1288.               TransferAdrRelocs(CodeLen);
  1289.               memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  1290.               CodeLen += AdrCnt;
  1291.               break;
  1292.           }
  1293.         }
  1294.         break;
  1295.     }
  1296.   }
  1297. }
  1298.  
  1299. static void DecodeMOVZS(Word Index)
  1300. {
  1301.   Byte HReg;
  1302.   int z;
  1303.   UNUSED(Index);
  1304.  
  1305.   z = Ord(Memo("MOVS")) << 4;
  1306.   if (ChkArgCnt(2, 2)
  1307.    && ChkMinCPU(CPU80251))
  1308.   {
  1309.     DecodeAdr(&ArgStr[1], MModReg);
  1310.     switch (AdrMode)
  1311.     {
  1312.       case ModReg:
  1313.         if (OpSize != 1) WrError(ErrNum_InvAddrMode);
  1314.         else
  1315.         {
  1316.           HReg = AdrPart;
  1317.           OpSize--;
  1318.           DecodeAdr(&ArgStr[2], MModReg);
  1319.           switch (AdrMode)
  1320.           {
  1321.             case ModReg:
  1322.              PutCode(0x10a + z);
  1323.              BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  1324.              break;
  1325.           }
  1326.         }
  1327.         break;
  1328.     }
  1329.   }
  1330. }
  1331.  
  1332. static void DecodeMOVX(Word Index)
  1333. {
  1334.   int z;
  1335.   UNUSED(Index);
  1336.  
  1337.   if (ChkArgCnt(2, 2))
  1338.   {
  1339.     z = 0;
  1340.     if ((!as_strcasecmp(ArgStr[2].str.p_str, "A")) || ((MomCPU >= CPU80251) && (!as_strcasecmp(ArgStr[2].str.p_str, "R11"))))
  1341.     {
  1342.       z = 0x10;
  1343.       strcpy(ArgStr[2].str.p_str, ArgStr[1].str.p_str);
  1344.       strmaxcpy(ArgStr[1].str.p_str, "A", STRINGSIZE);
  1345.     }
  1346.     if ((as_strcasecmp(ArgStr[1].str.p_str, "A")) && ((MomCPU < CPU80251) || (!as_strcasecmp(ArgStr[2].str.p_str, "R11")))) WrError(ErrNum_InvAddrMode);
  1347.     else if (!as_strcasecmp(ArgStr[2].str.p_str, "@DPTR"))
  1348.       PutCode(0xe0 + z);
  1349.     else
  1350.     {
  1351.       DecodeAdr(&ArgStr[2], MModIReg8);
  1352.       switch (AdrMode)
  1353.       {
  1354.         case ModIReg8:
  1355.           PutCode(0xe2 + AdrPart + z);
  1356.           break;
  1357.       }
  1358.     }
  1359.   }
  1360. }
  1361.  
  1362. static void DecodeStack(Word Index)
  1363. {
  1364.   int z;
  1365.  
  1366.   /* Index: PUSH=0 POP=1 PUSHW=2 */
  1367.  
  1368.   z = (Index & 1) << 4;
  1369.   if (ChkArgCnt(1, 1))
  1370.   {
  1371.     if (*ArgStr[1].str.p_str == '#')
  1372.       SetOpSize(Ord(Index == 2));
  1373.     DecodeAdr(&ArgStr[1], MModDir8 | MModReg | ((z == 0x10) ? 0 : MModImm));
  1374.     switch (AdrMode)
  1375.     {
  1376.       case ModDir8:
  1377.         PutCode(0xc0 + z);
  1378.         TransferAdrRelocs(CodeLen);
  1379.         BAsmCode[CodeLen++] = AdrVals[0];
  1380.         break;
  1381.       case ModReg:
  1382.         if (ChkMinCPUExt(CPU80251, ErrNum_AddrModeNotSupported))
  1383.         {
  1384.           PutCode(0x1ca + z);
  1385.           BAsmCode[CodeLen++] = 0x08 + (AdrPart << 4) + OpSize + (Ord(OpSize == 2));
  1386.         }
  1387.         break;
  1388.       case ModImm:
  1389.         if (ChkMinCPUExt(CPU80251, ErrNum_AddrModeNotSupported))
  1390.         {
  1391.           PutCode(0x1ca);
  1392.           BAsmCode[CodeLen++] = 0x02 + (OpSize << 2);
  1393.           TransferAdrRelocs(CodeLen);
  1394.           memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  1395.           CodeLen += AdrCnt;
  1396.         }
  1397.         break;
  1398.     }
  1399.   }
  1400. }
  1401.  
  1402. static void DecodeXCH(Word Index)
  1403. {
  1404.   Byte HReg;
  1405.   UNUSED(Index);
  1406.  
  1407.   if (ChkArgCnt(2, 2))
  1408.   {
  1409.     DecodeAdr(&ArgStr[1], MModAcc | MModReg | MModIReg8 | MModDir8);
  1410.     switch (AdrMode)
  1411.     {
  1412.       case ModAcc:
  1413.         DecodeAdr(&ArgStr[2], MModReg | MModIReg8 | MModDir8);
  1414.         switch (AdrMode)
  1415.         {
  1416.           case ModReg:
  1417.             if (AdrPart > 7) WrError(ErrNum_InvAddrMode);
  1418.             else
  1419.               PutCode(0xc8 + AdrPart);
  1420.             break;
  1421.           case ModIReg8:
  1422.             PutCode(0xc6 + AdrPart);
  1423.             break;
  1424.           case ModDir8:
  1425.             PutCode(0xc5);
  1426.             TransferAdrRelocs(CodeLen);
  1427.             BAsmCode[CodeLen++] = AdrVals[0];
  1428.             break;
  1429.         }
  1430.         break;
  1431.       case ModReg:
  1432.         if ((OpSize != 0) || (AdrPart > 7)) WrError(ErrNum_InvAddrMode);
  1433.         else
  1434.         {
  1435.           HReg = AdrPart;
  1436.           DecodeAdr(&ArgStr[2], MModAcc);
  1437.           switch (AdrMode)
  1438.           {
  1439.             case ModAcc:
  1440.               PutCode(0xc8 + HReg);
  1441.               break;
  1442.           }
  1443.         }
  1444.         break;
  1445.       case ModIReg8:
  1446.         HReg = AdrPart;
  1447.         DecodeAdr(&ArgStr[2], MModAcc);
  1448.         switch (AdrMode)
  1449.         {
  1450.           case ModAcc:
  1451.             PutCode(0xc6 + HReg);
  1452.             break;
  1453.         }
  1454.         break;
  1455.       case ModDir8:
  1456.         HReg = AdrVals[0]; SaveBackupAdrRelocs();
  1457.         DecodeAdr(&ArgStr[2], MModAcc);
  1458.         switch (AdrMode)
  1459.         {
  1460.           case ModAcc:
  1461.             PutCode(0xc5);
  1462.             TransferBackupAdrRelocs(CodeLen);
  1463.             BAsmCode[CodeLen++] = HReg;
  1464.             break;
  1465.         }
  1466.         break;
  1467.     }
  1468.   }
  1469. }
  1470.  
  1471. static void DecodeXCHD(Word Index)
  1472. {
  1473.   Byte HReg;
  1474.   UNUSED(Index);
  1475.  
  1476.   if (ChkArgCnt(2, 2))
  1477.   {
  1478.     DecodeAdr(&ArgStr[1], MModAcc | MModIReg8);
  1479.     switch (AdrMode)
  1480.     {
  1481.       case ModAcc:
  1482.         DecodeAdr(&ArgStr[2], MModIReg8);
  1483.         switch (AdrMode)
  1484.         {
  1485.           case ModIReg8:
  1486.             PutCode(0xd6 + AdrPart);
  1487.             break;
  1488.         }
  1489.         break;
  1490.       case ModIReg8:
  1491.         HReg = AdrPart;
  1492.         DecodeAdr(&ArgStr[2], MModAcc);
  1493.         switch (AdrMode)
  1494.         {
  1495.           case ModAcc:
  1496.             PutCode(0xd6 + HReg);
  1497.             break;
  1498.         }
  1499.         break;
  1500.     }
  1501.   }
  1502. }
  1503.  
  1504. #define RelocTypeABranch11 (11 | RelocFlagBig | RelocFlagPage | (5 << 8) | (3 << 12)) | (0 << 16)
  1505. #define RelocTypeABranch19 (19 | RelocFlagBig | RelocFlagPage | (5 << 8) | (3 << 12)) | (0 << 16)
  1506.  
  1507. static void DecodeABranch(Word Index)
  1508. {
  1509.   /* Index: AJMP = 0 ACALL = 1 */
  1510.  
  1511.   if (ChkArgCnt(1, 1))
  1512.   {
  1513.     tEvalResult EvalResult;
  1514.     LongInt AdrLong = EvalStrIntExpressionWithResult(&ArgStr[1], Int24, &EvalResult);
  1515.  
  1516.     if (EvalResult.OK)
  1517.     {
  1518.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1519.       if (MomCPU == CPU80C390)
  1520.       {
  1521.         if (ChkSamePage(EProgCounter() + 3, AdrLong, 19, EvalResult.Flags))
  1522.         {
  1523.           PutCode(0x01 + (Index << 4) + (((AdrLong >> 16) & 7) << 5));
  1524.           BAsmCode[CodeLen++] = Hi(AdrLong);
  1525.           BAsmCode[CodeLen++] = Lo(AdrLong);
  1526.           TransferRelocs(ProgCounter() - 3, RelocTypeABranch19);
  1527.         }
  1528.       }
  1529.       else
  1530.       {
  1531.         if (!ChkSamePage(EProgCounter(), AdrLong, 11, EvalResult.Flags));
  1532.         else if (Chk504(EProgCounter())) WrError(ErrNum_NotOnThisAddress);
  1533.         else
  1534.         {
  1535.           PutCode(0x01 + (Index << 4) + ((Hi(AdrLong) & 7) << 5));
  1536.           BAsmCode[CodeLen++] = Lo(AdrLong);
  1537.           TransferRelocs(ProgCounter() - 2, RelocTypeABranch11);
  1538.         }
  1539.       }
  1540.     }
  1541.   }
  1542. }
  1543.  
  1544. static void DecodeLBranch(Word Index)
  1545. {
  1546.   /* Index: LJMP=0 LCALL=1 */
  1547.  
  1548.   if (!ChkArgCnt(1, 1));
  1549.   else if (!ChkMinCPU(CPU8051));
  1550.   else if (*ArgStr[1].str.p_str == '@')
  1551.   {
  1552.     DecodeAdr(&ArgStr[1], MModIReg);
  1553.     switch (AdrMode)
  1554.     {
  1555.       case ModIReg:
  1556.         if (AdrSize != 0) WrError(ErrNum_InvAddrMode);
  1557.         else
  1558.         {
  1559.           PutCode(0x189 + (Index << 4));
  1560.           BAsmCode[CodeLen++] = 0x04 + (AdrPart << 4);
  1561.         }
  1562.         break;
  1563.     }
  1564.   }
  1565.   else
  1566.   {
  1567.     tEvalResult EvalResult;
  1568.     LongInt AdrLong = EvalStrIntExpressionWithResult(&ArgStr[1], (MomCPU < CPU80C390) ? Int16 : Int24, &EvalResult);
  1569.  
  1570.     if (EvalResult.OK)
  1571.     {
  1572.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1573.       if (MomCPU == CPU80C390)
  1574.       {
  1575.         PutCode(0x02 + (Index << 4));
  1576.         BAsmCode[CodeLen++] = (AdrLong >> 16) & 0xff;
  1577.         BAsmCode[CodeLen++] = (AdrLong >> 8) & 0xff;
  1578.         BAsmCode[CodeLen++] = AdrLong & 0xff;
  1579.         TransferRelocs(ProgCounter() + 1, RelocTypeB24);
  1580.       }
  1581.       else
  1582.       {
  1583.         if ((MomCPU >= CPU80251) && !ChkSamePage(EProgCounter() + 3, AdrLong, 16, EvalResult.Flags));
  1584.         else
  1585.         {
  1586.           PutCode(0x02 + (Index << 4));
  1587.           BAsmCode[CodeLen++] = (AdrLong >> 8) & 0xff;
  1588.           BAsmCode[CodeLen++] = AdrLong & 0xff;
  1589.           TransferRelocs(ProgCounter() + 1, RelocTypeB16);
  1590.         }
  1591.       }
  1592.     }
  1593.   }
  1594. }
  1595.  
  1596. static void DecodeEBranch(Word Index)
  1597. {
  1598.   /* Index: AJMP=0 ACALL=1 */
  1599.  
  1600.   if (!ChkArgCnt(1, 1));
  1601.   else if (!ChkMinCPU(CPU80251));
  1602.   else if (*ArgStr[1].str.p_str == '@')
  1603.   {
  1604.     DecodeAdr(&ArgStr[1], MModIReg);
  1605.     switch (AdrMode)
  1606.     {
  1607.       case ModIReg:
  1608.         if (AdrSize != 2) WrError(ErrNum_InvAddrMode);
  1609.         else
  1610.         {
  1611.           PutCode(0x189 + (Index << 4));
  1612.           BAsmCode[CodeLen++] = 0x08 + (AdrPart << 4);
  1613.         }
  1614.         break;
  1615.     }
  1616.   }
  1617.   else
  1618.   {
  1619.     tEvalResult EvalResult;
  1620.     LongInt AdrLong = EvalStrIntExpressionWithResult(&ArgStr[1], UInt24, &EvalResult);
  1621.  
  1622.     if (EvalResult.OK)
  1623.     {
  1624.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1625.       PutCode(0x18a + (Index << 4));
  1626.       BAsmCode[CodeLen++] = (AdrLong >> 16) & 0xff;
  1627.       BAsmCode[CodeLen++] = (AdrLong >>  8) & 0xff;
  1628.       BAsmCode[CodeLen++] =  AdrLong        & 0xff;
  1629.     }
  1630.   }
  1631. }
  1632.  
  1633. static void DecodeJMP(Word Index)
  1634. {
  1635.   LongInt AdrLong, Dist;
  1636.   Boolean OK;
  1637.   UNUSED(Index);
  1638.  
  1639.   if (!ChkArgCnt(1, 1));
  1640.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "@A+DPTR"))
  1641.     PutCode(0x73);
  1642.   else if (*ArgStr[1].str.p_str == '@')
  1643.   {
  1644.     DecodeAdr(&ArgStr[1], MModIReg);
  1645.     switch (AdrMode)
  1646.     {
  1647.       case ModIReg:
  1648.         PutCode(0x189);
  1649.         BAsmCode[CodeLen++] = 0x04 + (AdrSize << 1) + (AdrPart << 4);
  1650.         break;
  1651.     }
  1652.   }
  1653.   else
  1654.   {
  1655.     AdrLong = EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
  1656.     if (OK)
  1657.     {
  1658.       Dist = AdrLong - (EProgCounter() + 2);
  1659.       if ((Dist<=127) && (Dist >= -128))
  1660.       {
  1661.         PutCode(0x80);
  1662.         BAsmCode[CodeLen++] = Dist & 0xff;
  1663.       }
  1664.       else if ((!Chk504(EProgCounter())) && ((AdrLong >> 11) == ((((long)EProgCounter()) + 2) >> 11)))
  1665.       {
  1666.         PutCode(0x01 + ((Hi(AdrLong) & 7) << 5));
  1667.         BAsmCode[CodeLen++] = Lo(AdrLong);
  1668.       }
  1669.       else if (MomCPU < CPU8051) WrError(ErrNum_JmpTargOnDiffPage);
  1670.       else if (((((long)EProgCounter()) + 3) >> 16) == (AdrLong >> 16))
  1671.       {
  1672.         PutCode(0x02);
  1673.         BAsmCode[CodeLen++] = Hi(AdrLong);
  1674.         BAsmCode[CodeLen++] = Lo(AdrLong);
  1675.       }
  1676.       else if (MomCPU < CPU80251) WrError(ErrNum_JmpTargOnDiffPage);
  1677.       else
  1678.       {
  1679.         PutCode(0x18a);
  1680.         BAsmCode[CodeLen++] = (AdrLong >> 16) & 0xff;
  1681.         BAsmCode[CodeLen++] = (AdrLong >>  8) & 0xff;
  1682.         BAsmCode[CodeLen++] =  AdrLong        & 0xff;
  1683.       }
  1684.     }
  1685.   }
  1686. }
  1687.  
  1688. static void DecodeCALL(Word Index)
  1689. {
  1690.   LongInt AdrLong;
  1691.   Boolean OK;
  1692.   tSymbolFlags Flags;
  1693.  
  1694.   UNUSED(Index);
  1695.  
  1696.   if (!ChkArgCnt(1, 1));
  1697.   else if (*ArgStr[1].str.p_str == '@')
  1698.   {
  1699.     DecodeAdr(&ArgStr[1], MModIReg);
  1700.     switch (AdrMode)
  1701.     {
  1702.       case ModIReg:
  1703.         PutCode(0x199);
  1704.         BAsmCode[CodeLen++] = 0x04 + (AdrSize << 1) + (AdrPart << 4);
  1705.         break;
  1706.     }
  1707.   }
  1708.   else
  1709.   {
  1710.     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt24, &OK, &Flags);
  1711.     if (OK)
  1712.     {
  1713.       if ((!Chk504(EProgCounter())) && ((AdrLong >> 11) == ((((long)EProgCounter()) + 2) >> 11)))
  1714.       {
  1715.         PutCode(0x11 + ((Hi(AdrLong) & 7) << 5));
  1716.         BAsmCode[CodeLen++] = Lo(AdrLong);
  1717.       }
  1718.       else if (MomCPU < CPU8051) WrError(ErrNum_JmpTargOnDiffPage);
  1719.       else if (ChkSamePage(AdrLong, EProgCounter() + 3, 16, Flags))
  1720.       {
  1721.         PutCode(0x12);
  1722.         BAsmCode[CodeLen++] = Hi(AdrLong);
  1723.         BAsmCode[CodeLen++] = Lo(AdrLong);
  1724.       }
  1725.     }
  1726.   }
  1727. }
  1728.  
  1729. static void DecodeDJNZ(Word Index)
  1730. {
  1731.   LongInt AdrLong;
  1732.   Boolean OK;
  1733.   tSymbolFlags Flags;
  1734.  
  1735.   UNUSED(Index);
  1736.  
  1737.   if (ChkArgCnt(2, 2))
  1738.   {
  1739.     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt24, &OK, &Flags);
  1740.     SubPCRefReloc();
  1741.     if (OK)
  1742.     {
  1743.       DecodeAdr(&ArgStr[1], MModReg | MModDir8);
  1744.       switch (AdrMode)
  1745.       {
  1746.         case ModReg:
  1747.           if ((OpSize != 0) || (AdrPart > 7)) WrError(ErrNum_InvAddrMode);
  1748.           else
  1749.           {
  1750.             AdrLong -= EProgCounter() + 2 + Ord(NeedsPrefix(0xd8 + AdrPart));
  1751.             if (((AdrLong < -128) || (AdrLong > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  1752.             else
  1753.             {
  1754.               PutCode(0xd8 + AdrPart);
  1755.               BAsmCode[CodeLen++] = AdrLong & 0xff;
  1756.             }
  1757.           }
  1758.           break;
  1759.         case ModDir8:
  1760.           AdrLong -= EProgCounter() + 3 + Ord(NeedsPrefix(0xd5));
  1761.           if (((AdrLong < -128) || (AdrLong > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  1762.           else
  1763.           {
  1764.             PutCode(0xd5);
  1765.             TransferAdrRelocs(CodeLen);
  1766.             BAsmCode[CodeLen++] = AdrVals[0];
  1767.             BAsmCode[CodeLen++] = Lo(AdrLong);
  1768.           }
  1769.           break;
  1770.       }
  1771.     }
  1772.   }
  1773. }
  1774.  
  1775. static void DecodeCJNE(Word Index)
  1776. {
  1777.   LongInt AdrLong;
  1778.   Boolean OK;
  1779.   tSymbolFlags Flags;
  1780.   Byte HReg;
  1781.   UNUSED(Index);
  1782.  
  1783.   if (ChkArgCnt(3, 3))
  1784.   {
  1785.     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[3], UInt24, &OK, &Flags);
  1786.     SubPCRefReloc();
  1787.     if (OK)
  1788.     {
  1789.       DecodeAdr(&ArgStr[1], MModAcc | MModIReg8 | MModReg);
  1790.       switch (AdrMode)
  1791.       {
  1792.         case ModAcc:
  1793.           DecodeAdr(&ArgStr[2], MModDir8 | MModImm);
  1794.           switch (AdrMode)
  1795.           {
  1796.             case ModDir8:
  1797.               AdrLong -= EProgCounter() + 3 + Ord(NeedsPrefix(0xb5));
  1798.               if (((AdrLong < -128) || (AdrLong > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  1799.               else
  1800.               {
  1801.                 PutCode(0xb5);
  1802.                 TransferAdrRelocs(CodeLen);
  1803.                 BAsmCode[CodeLen++] = AdrVals[0];
  1804.                 BAsmCode[CodeLen++] = AdrLong & 0xff;
  1805.               }
  1806.               break;
  1807.             case ModImm:
  1808.               AdrLong -= EProgCounter() + 3 + Ord(NeedsPrefix(0xb5));
  1809.               if (((AdrLong < -128) || (AdrLong > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  1810.               else
  1811.               {
  1812.                 PutCode(0xb4);
  1813.                 TransferAdrRelocs(CodeLen);
  1814.                 BAsmCode[CodeLen++] = AdrVals[0];
  1815.                 BAsmCode[CodeLen++] = AdrLong & 0xff;
  1816.               }
  1817.               break;
  1818.           }
  1819.           break;
  1820.         case ModReg:
  1821.           if ((OpSize != 0) || (AdrPart > 7)) WrError(ErrNum_InvAddrMode);
  1822.           else
  1823.           {
  1824.             HReg = AdrPart;
  1825.             DecodeAdr(&ArgStr[2], MModImm);
  1826.             switch (AdrMode)
  1827.             {
  1828.               case ModImm:
  1829.                 AdrLong -= EProgCounter() + 3 + Ord(NeedsPrefix(0xb8 + HReg));
  1830.                 if (((AdrLong < -128) || (AdrLong > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  1831.                 else
  1832.                 {
  1833.                   PutCode(0xb8 + HReg);
  1834.                   TransferAdrRelocs(CodeLen);
  1835.                   BAsmCode[CodeLen++] = AdrVals[0];
  1836.                   BAsmCode[CodeLen++] = AdrLong & 0xff;
  1837.                 }
  1838.                 break;
  1839.             }
  1840.           }
  1841.           break;
  1842.         case ModIReg8:
  1843.           HReg = AdrPart; SetOpSize(0);
  1844.           DecodeAdr(&ArgStr[2], MModImm);
  1845.           switch (AdrMode)
  1846.           {
  1847.             case ModImm:
  1848.               AdrLong -= EProgCounter() + 3 + Ord(NeedsPrefix(0xb6 + HReg));
  1849.               if (((AdrLong < -128) || (AdrLong > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  1850.               else
  1851.               {
  1852.                 PutCode(0xb6 + HReg);
  1853.                 TransferAdrRelocs(CodeLen);
  1854.                 BAsmCode[CodeLen++] = AdrVals[0];
  1855.                 BAsmCode[CodeLen++] = AdrLong & 0xff;
  1856.               }
  1857.               break;
  1858.           }
  1859.           break;
  1860.       }
  1861.     }
  1862.   }
  1863. }
  1864.  
  1865. static void DecodeADD(Word Index)
  1866. {
  1867.   Byte HReg;
  1868.   UNUSED(Index);
  1869.  
  1870.   if (ChkArgCnt(2, 2))
  1871.   {
  1872.     DecodeAdr(&ArgStr[1], MModAcc | MModReg);
  1873.     switch (AdrMode)
  1874.     {
  1875.       case ModAcc:
  1876.         DecodeAdr(&ArgStr[2], MModImm | MModDir8 | MModDir16 | MModIReg8 | MModIReg | MModReg);
  1877.         switch (AdrMode)
  1878.         {
  1879.           case ModImm:
  1880.             PutCode(0x24);
  1881.             TransferAdrRelocs(CodeLen);
  1882.             BAsmCode[CodeLen++] = AdrVals[0];
  1883.             break;
  1884.           case ModDir8:
  1885.             PutCode(0x25);
  1886.             TransferAdrRelocs(CodeLen);
  1887.             BAsmCode[CodeLen++] = AdrVals[0];
  1888.             break;
  1889.           case ModDir16:
  1890.             PutCode(0x12e);
  1891.             BAsmCode[CodeLen++] = (AccReg << 4) + 3;
  1892.             memcpy(BAsmCode + CodeLen, AdrVals, 2);
  1893.             CodeLen += 2;
  1894.             break;
  1895.           case ModIReg8:
  1896.             PutCode(0x26 + AdrPart);
  1897.             break;
  1898.           case ModIReg:
  1899.             PutCode(0x12e);
  1900.             BAsmCode[CodeLen++] = 0x09 + AdrSize + (AdrPart << 4);
  1901.             BAsmCode[CodeLen++] = AccReg << 4;
  1902.             break;
  1903.           case ModReg:
  1904.             if ((AdrPart < 8) && (!SrcMode)) PutCode(0x28 + AdrPart);
  1905.             else if (ChkMinCPUExt(CPU80251, ErrNum_AddrModeNotSupported))
  1906.             {
  1907.               PutCode(0x12c);
  1908.               BAsmCode[CodeLen++] = AdrPart + (AccReg << 4);
  1909.             }
  1910.             break;
  1911.         }
  1912.         break;
  1913.       case ModReg:
  1914.         if (ChkMinCPUExt(CPU80251, ErrNum_AddrModeNotSupported))
  1915.         {
  1916.           HReg = AdrPart;
  1917.           DecodeAdr(&ArgStr[2], MModImm | MModReg | MModDir8 | MModDir16 | MModIReg8 | MModIReg);
  1918.           switch (AdrMode)
  1919.           {
  1920.             case ModImm:
  1921.               if ((OpSize == 0) && (HReg == AccReg))
  1922.               {
  1923.                 PutCode(0x24);
  1924.                 TransferAdrRelocs(CodeLen);
  1925.                 BAsmCode[CodeLen++] = AdrVals[0];
  1926.               }
  1927.               else
  1928.               {
  1929.                 PutCode(0x12e);
  1930.                 BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2);
  1931.                 memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  1932.                 CodeLen += AdrCnt;
  1933.               }
  1934.               break;
  1935.             case ModReg:
  1936.               PutCode(0x12c + OpSize);
  1937.               if (OpSize == 2) BAsmCode[CodeLen - 1]++;
  1938.               BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  1939.               break;
  1940.             case ModDir8:
  1941.               if (OpSize == 2) WrError(ErrNum_InvAddrMode);
  1942.               else if ((OpSize == 0) && (HReg == AccReg))
  1943.               {
  1944.                 PutCode(0x25);
  1945.                 TransferAdrRelocs(CodeLen);
  1946.                 BAsmCode[CodeLen++] = AdrVals[0];
  1947.               }
  1948.               else
  1949.               {
  1950.                 PutCode(0x12e);
  1951.                 BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2) + 1;
  1952.                 BAsmCode[CodeLen++] = AdrVals[0];
  1953.               }
  1954.               break;
  1955.             case ModDir16:
  1956.               if (OpSize == 2) WrError(ErrNum_InvAddrMode);
  1957.               else
  1958.               {
  1959.                 PutCode(0x12e);
  1960.                 BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2) + 3;
  1961.                 memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  1962.                 CodeLen += AdrCnt;
  1963.               }
  1964.               break;
  1965.             case ModIReg8:
  1966.               if ((OpSize != 0) || (HReg != AccReg)) WrError(ErrNum_InvAddrMode);
  1967.               else PutCode(0x26 + AdrPart);
  1968.               break;
  1969.             case ModIReg:
  1970.               if (OpSize != 0) WrError(ErrNum_InvAddrMode);
  1971.               else
  1972.               {
  1973.                 PutCode(0x12e);
  1974.                 BAsmCode[CodeLen++] = 0x09 + AdrSize + (AdrPart << 4);
  1975.                 BAsmCode[CodeLen++] = HReg << 4;
  1976.               }
  1977.               break;
  1978.           }
  1979.         }
  1980.         break;
  1981.     }
  1982.   }
  1983. }
  1984.  
  1985. static void DecodeSUBCMP(Word Index)
  1986. {
  1987.   int z;
  1988.   Byte HReg;
  1989.  
  1990.   /* Index: SUB=0 CMP=1 */
  1991.  
  1992.   z = 0x90 + (Index << 5);
  1993.   if (ChkArgCnt(2, 2)
  1994.    && ChkMinCPU(CPU80251))
  1995.   {
  1996.     DecodeAdr(&ArgStr[1], MModReg);
  1997.     switch (AdrMode)
  1998.     {
  1999.       case ModReg:
  2000.         HReg = AdrPart;
  2001.         DecodeAdr(&ArgStr[2], MModImm | MModReg | MModDir8 | MModDir16 | MModIReg | (Index ? MModImmEx : 0));
  2002.         switch (AdrMode)
  2003.         {
  2004.           case ModImm:
  2005.             PutCode(0x10e + z);
  2006.             BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2);
  2007.             TransferAdrRelocs(CodeLen);
  2008.             memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  2009.             CodeLen += AdrCnt;
  2010.             break;
  2011.           case ModImmEx:
  2012.             PutCode(0x10e + z);
  2013.             BAsmCode[CodeLen++] = (HReg << 4) + 0x0c;
  2014.             TransferAdrRelocs(CodeLen);
  2015.             memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  2016.             CodeLen += AdrCnt;
  2017.             break;
  2018.           case ModReg:
  2019.             PutCode(0x10c + z + OpSize);
  2020.             if (OpSize == 2)
  2021.               BAsmCode[CodeLen - 1]++;
  2022.             BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  2023.             break;
  2024.           case ModDir8:
  2025.             if (OpSize == 2) WrError(ErrNum_InvAddrMode);
  2026.             else
  2027.             {
  2028.               PutCode(0x10e + z);
  2029.               BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2) + 1;
  2030.               TransferAdrRelocs(CodeLen);
  2031.               BAsmCode[CodeLen++] = AdrVals[0];
  2032.             }
  2033.             break;
  2034.           case ModDir16:
  2035.             if (OpSize == 2) WrError(ErrNum_InvAddrMode);
  2036.             else
  2037.             {
  2038.               PutCode(0x10e + z);
  2039.               BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2) + 3;
  2040.               memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  2041.               CodeLen += AdrCnt;
  2042.             }
  2043.             break;
  2044.           case ModIReg:
  2045.             if (OpSize != 0) WrError(ErrNum_InvAddrMode);
  2046.             else
  2047.             {
  2048.               PutCode(0x10e + z);
  2049.               BAsmCode[CodeLen++] = 0x09 + AdrSize + (AdrPart << 4);
  2050.               BAsmCode[CodeLen++] = HReg << 4;
  2051.             }
  2052.             break;
  2053.         }
  2054.         break;
  2055.     }
  2056.   }
  2057. }
  2058.  
  2059. static void DecodeADDCSUBB(Word Index)
  2060. {
  2061.   Byte HReg;
  2062.  
  2063.   /* Index: ADDC=0 SUBB=1 */
  2064.  
  2065.   if (ChkArgCnt(2, 2))
  2066.   {
  2067.     DecodeAdr(&ArgStr[1], MModAcc);
  2068.     switch (AdrMode)
  2069.     {
  2070.       case ModAcc:
  2071.         HReg = 0x30 + (Index*0x60);
  2072.         DecodeAdr(&ArgStr[2], MModReg | MModIReg8 | MModDir8 | MModImm);
  2073.         switch (AdrMode)
  2074.         {
  2075.           case ModReg:
  2076.             if (AdrPart > 7) WrError(ErrNum_InvAddrMode);
  2077.             else
  2078.               PutCode(HReg + 0x08 + AdrPart);
  2079.             break;
  2080.           case ModIReg8:
  2081.             PutCode(HReg + 0x06 + AdrPart);
  2082.             break;
  2083.           case ModDir8:
  2084.             PutCode(HReg + 0x05);
  2085.             TransferAdrRelocs(CodeLen);
  2086.             BAsmCode[CodeLen++] = AdrVals[0];
  2087.             break;
  2088.           case ModImm:
  2089.             PutCode(HReg + 0x04);
  2090.             TransferAdrRelocs(CodeLen);
  2091.             BAsmCode[CodeLen++] = AdrVals[0];
  2092.             break;
  2093.         }
  2094.         break;
  2095.     }
  2096.   }
  2097. }
  2098.  
  2099. static void DecodeINCDEC(Word Index)
  2100. {
  2101.   Byte HReg;
  2102.   int z;
  2103.   Boolean OK;
  2104.   tSymbolFlags Flags;
  2105.  
  2106.   /* Index: INC=0 DEC=1 */
  2107.  
  2108.   z = Index << 4;
  2109.   if (!ChkArgCnt(1, 2));
  2110.   else if ((ArgCnt == 2) && (*ArgStr[2].str.p_str != '#')) WrError(ErrNum_InvAddrMode);
  2111.   else
  2112.   {
  2113.     if (1 == ArgCnt)
  2114.     {
  2115.       HReg = 1;
  2116.       OK = True;
  2117.       Flags = eSymbolFlag_None;
  2118.     }
  2119.     else
  2120.       HReg = EvalStrIntExpressionOffsWithFlags(&ArgStr[2], 1, UInt3, &OK, &Flags);
  2121.     if (mFirstPassUnknown(Flags))
  2122.       HReg = 1;
  2123.     if (OK)
  2124.     {
  2125.       OK = True;
  2126.       if (HReg == 1)
  2127.         HReg = 0;
  2128.       else if (HReg == 2)
  2129.         HReg = 1;
  2130.       else if (HReg == 4)
  2131.         HReg = 2;
  2132.       else
  2133.         OK = False;
  2134.       if (!OK) WrError(ErrNum_OverRange);
  2135.       else if (!as_strcasecmp(ArgStr[1].str.p_str, "DPTR"))
  2136.       {
  2137.         if (Index == 1) WrError(ErrNum_InvAddrMode);
  2138.         else if (HReg != 0) WrError(ErrNum_OverRange);
  2139.         else
  2140.           PutCode(0xa3);
  2141.       }
  2142.       else
  2143.       {
  2144.         DecodeAdr(&ArgStr[1], MModAcc | MModReg | MModDir8 | MModIReg8);
  2145.         switch (AdrMode)
  2146.         {
  2147.           case ModAcc:
  2148.             if (HReg == 0)
  2149.               PutCode(0x04 + z);
  2150.             else if (MomCPU < CPU80251) WrError(ErrNum_OverRange);
  2151.             else
  2152.             {
  2153.               PutCode(0x10b + z);
  2154.               BAsmCode[CodeLen++] = (AccReg << 4) + HReg;
  2155.             }
  2156.             break;
  2157.           case ModReg:
  2158.             if ((OpSize == 0) && (AdrPart == AccReg) && (HReg == 0))
  2159.               PutCode(0x04 + z);
  2160.             else if ((AdrPart < 8) && (OpSize == 0) && (HReg == 0) && (!SrcMode))
  2161.               PutCode(0x08 + z + AdrPart);
  2162.             else if (ChkMinCPUExt(CPU80251, ErrNum_AddrModeNotSupported))
  2163.             {
  2164.               PutCode(0x10b + z);
  2165.               BAsmCode[CodeLen++] = (AdrPart << 4) + (OpSize << 2) + HReg;
  2166.               if (OpSize == 2)
  2167.                 BAsmCode[CodeLen - 1] += 4;
  2168.             }
  2169.             break;
  2170.           case ModDir8:
  2171.             if (HReg != 0) WrError(ErrNum_OverRange);
  2172.             else
  2173.             {
  2174.               PutCode(0x05 + z);
  2175.               TransferAdrRelocs(CodeLen);
  2176.               BAsmCode[CodeLen++] = AdrVals[0];
  2177.             }
  2178.             break;
  2179.           case ModIReg8:
  2180.             if (HReg != 0) WrError(ErrNum_OverRange);
  2181.             else
  2182.               PutCode(0x06 + z + AdrPart);
  2183.             break;
  2184.         }
  2185.       }
  2186.     }
  2187.   }
  2188. }
  2189.  
  2190. static void DecodeMULDIV(Word Index)
  2191. {
  2192.   int z;
  2193.   Byte HReg;
  2194.  
  2195.   /* Index: DIV=0 MUL=1 */
  2196.  
  2197.   z = Index << 5;
  2198.   if (!ChkArgCnt(1, 2));
  2199.   else if (ArgCnt == 1)
  2200.   {
  2201.     if (as_strcasecmp(ArgStr[1].str.p_str, "AB")) WrError(ErrNum_InvAddrMode);
  2202.     else
  2203.       PutCode(0x84 + z);
  2204.   }
  2205.   else
  2206.   {
  2207.     DecodeAdr(&ArgStr[1], MModReg);
  2208.     switch (AdrMode)
  2209.     {
  2210.       case ModReg:
  2211.         HReg = AdrPart;
  2212.         DecodeAdr(&ArgStr[2], MModReg);
  2213.         switch (AdrMode)
  2214.         {
  2215.           case ModReg:
  2216.             if (!ChkMinCPUExt(CPU80251, ErrNum_AddrModeNotSupported));
  2217.             else if (OpSize == 2) WrError(ErrNum_InvAddrMode);
  2218.             else
  2219.             {
  2220.               PutCode(0x18c + z + OpSize);
  2221.               BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
  2222.             }
  2223.             break;
  2224.         }
  2225.         break;
  2226.     }
  2227.   }
  2228. }
  2229.  
  2230. static void DecodeBits(Word Index)
  2231. {
  2232.   LongInt AdrLong;
  2233.   int z;
  2234.  
  2235.   /* Index: CPL=0 CLR=1 SETB=2 */
  2236.  
  2237.   z = Index << 4;
  2238.   if (!ChkArgCnt(1, 1));
  2239.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "A"))
  2240.   {
  2241.     if (Memo("SETB")) WrError(ErrNum_InvAddrMode);
  2242.     else
  2243.       PutCode(0xf4 - z);
  2244.   }
  2245.   else if (IsCarry(ArgStr[1].str.p_str))
  2246.     PutCode(0xb3 + z);
  2247.   else
  2248.     switch (DecodeBitAdr(&ArgStr[1], &AdrLong, True))
  2249.     {
  2250.       case ModBit51:
  2251.         PutCode(0xb2 + z);
  2252.         BAsmCode[CodeLen++] = AdrLong & 0xff;
  2253.         break;
  2254.       case ModBit251:
  2255.         PutCode(0x1a9);
  2256.         BAsmCode[CodeLen++] = 0xb0 + z + (AdrLong >> 24);
  2257.         BAsmCode[CodeLen++] = AdrLong & 0xff;
  2258.         break;
  2259.     }
  2260. }
  2261.  
  2262. static void DecodeShift(Word Index)
  2263. {
  2264.   int z;
  2265.  
  2266.   /* Index: SRA=0 SRL=1 SLL=3 */
  2267.  
  2268.   if (ChkArgCnt(1, 1)
  2269.    && ChkMinCPU(CPU80251))
  2270.   {
  2271.     z = Index << 4;
  2272.     DecodeAdr(&ArgStr[1], MModReg);
  2273.     switch (AdrMode)
  2274.     {
  2275.       case ModReg:
  2276.         if (OpSize == 2) WrError(ErrNum_InvAddrMode);
  2277.         else
  2278.         {
  2279.           PutCode(0x10e + z);
  2280.           BAsmCode[CodeLen++] = (AdrPart << 4) + (OpSize << 2);
  2281.         }
  2282.         break;
  2283.     }
  2284.   }
  2285. }
  2286.  
  2287. static void DecodeCond(Word Index)
  2288. {
  2289.   FixedOrder *FixedZ = CondOrders + Index;
  2290.  
  2291.   if (ChkArgCnt(1, 1)
  2292.    && ChkMinCPU(FixedZ->MinCPU))
  2293.   {
  2294.     tEvalResult EvalResult;
  2295.     LongInt AdrLong = EvalStrIntExpressionWithResult(&ArgStr[1], UInt24, &EvalResult);
  2296.  
  2297.     SubPCRefReloc();
  2298.     if (EvalResult.OK)
  2299.     {
  2300.       AdrLong -= EProgCounter() + 2 + Ord(NeedsPrefix(FixedZ->Code));
  2301.       if (((AdrLong < -128) || (AdrLong > 127)) && !mSymbolQuestionable(EvalResult.Flags)) WrError(ErrNum_JmpDistTooBig);
  2302.       else
  2303.       {
  2304.         ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  2305.         PutCode(FixedZ->Code);
  2306.         BAsmCode[CodeLen++] = AdrLong & 0xff;
  2307.       }
  2308.     }
  2309.   }
  2310. }
  2311.  
  2312. static void DecodeBCond(Word Index)
  2313. {
  2314.   FixedOrder *FixedZ = BCondOrders + Index;
  2315.   LongInt AdrLong, BitLong;
  2316.   tEvalResult EvalResult;
  2317.  
  2318.   if (ChkArgCnt(2, 2))
  2319.   {
  2320.     AdrLong = EvalStrIntExpressionWithResult(&ArgStr[2], UInt24, &EvalResult);
  2321.     SubPCRefReloc();
  2322.     if (EvalResult.OK)
  2323.     {
  2324.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  2325.       switch (DecodeBitAdr(&ArgStr[1], &BitLong, True))
  2326.       {
  2327.         case ModBit51:
  2328.           AdrLong -= EProgCounter() + 3 + Ord(NeedsPrefix(FixedZ->Code));
  2329.           if (((AdrLong < -128) || (AdrLong > 127)) && !mSymbolQuestionable(EvalResult.Flags)) WrError(ErrNum_JmpDistTooBig);
  2330.           else
  2331.           {
  2332.             PutCode(FixedZ->Code);
  2333.             BAsmCode[CodeLen++] = BitLong & 0xff;
  2334.             BAsmCode[CodeLen++] = AdrLong & 0xff;
  2335.           }
  2336.           break;
  2337.         case ModBit251:
  2338.           AdrLong -= EProgCounter() + 4 + Ord(NeedsPrefix(0x1a9));
  2339.           if (((AdrLong < -128) || (AdrLong > 127)) && !mSymbolQuestionable(EvalResult.Flags)) WrError(ErrNum_JmpDistTooBig);
  2340.           else
  2341.           {
  2342.             PutCode(0x1a9);
  2343.             BAsmCode[CodeLen++] = FixedZ->Code + (BitLong >> 24);
  2344.             BAsmCode[CodeLen++] = BitLong & 0xff;
  2345.             BAsmCode[CodeLen++] = AdrLong & 0xff;
  2346.           }
  2347.           break;
  2348.       }
  2349.     }
  2350.   }
  2351. }
  2352.  
  2353. static void DecodeAcc(Word Index)
  2354. {
  2355.   FixedOrder *FixedZ = AccOrders + Index;
  2356.  
  2357.   if (ChkArgCnt(1, 1)
  2358.    && ChkMinCPU(FixedZ->MinCPU))
  2359.   {
  2360.     DecodeAdr(&ArgStr[1], MModAcc);
  2361.     switch (AdrMode)
  2362.     {
  2363.       case ModAcc:
  2364.         PutCode(FixedZ->Code);
  2365.         break;
  2366.     }
  2367.   }
  2368. }
  2369.  
  2370. static void DecodeFixed(Word Index)
  2371. {
  2372.   FixedOrder *FixedZ = FixedOrders + Index;
  2373.  
  2374.   if (ChkArgCnt(0, 0)
  2375.    && ChkMinCPU(FixedZ->MinCPU))
  2376.     PutCode(FixedZ->Code);
  2377. }
  2378.  
  2379.  
  2380. static void DecodeSFR(Word Index)
  2381. {
  2382.   Word AdrByte;
  2383.   Boolean OK;
  2384.   tSymbolFlags Flags;
  2385.   as_addrspace_t DSeg;
  2386.   UNUSED(Index);
  2387.  
  2388.   if (!ChkArgCnt(1, 1));
  2389.   else if (Memo("SFRB") && !ChkMaxCPU(CPU80C390));
  2390.   else
  2391.   {
  2392.     AdrByte = EvalStrIntExpressionWithFlags(&ArgStr[1], (MomCPU >= CPU80251) ? UInt9 : UInt8, &OK, &Flags);
  2393.     if (OK && !mFirstPassUnknown(Flags))
  2394.     {
  2395.       PushLocHandle(-1);
  2396.       DSeg = (MomCPU >= CPU80251) ? SegIO : SegData;
  2397.       EnterIntSymbol(&LabPart, AdrByte, DSeg, False);
  2398.       if (MakeUseList)
  2399.       {
  2400.         if (AddChunk(SegChunks + DSeg, AdrByte, 1, False))
  2401.           WrError(ErrNum_Overlap);
  2402.       }
  2403.       if (Memo("SFRB"))
  2404.       {
  2405.         Byte BitStart;
  2406.  
  2407.         if (AdrByte > 0x7f)
  2408.         {
  2409.           if ((AdrByte & 7) != 0) WrError(ErrNum_NotBitAddressable);
  2410.           BitStart = AdrByte;
  2411.         }
  2412.         else
  2413.         {
  2414.           if ((AdrByte & 0xe0) != 0x20) WrError(ErrNum_NotBitAddressable);
  2415.           BitStart = (AdrByte - 0x20) << 3;
  2416.         }
  2417.         if (MakeUseList)
  2418.           if (AddChunk(SegChunks + SegBData, BitStart, 8, False)) WrError(ErrNum_Overlap);
  2419.         as_snprintf(ListLine, STRINGSIZE, "=%~02.*u%s-%~02.*u%s",
  2420.                     ListRadixBase, (unsigned)BitStart, GetIntConstIntelSuffix(ListRadixBase),
  2421.                     ListRadixBase, (unsigned)BitStart + 7, GetIntConstIntelSuffix(ListRadixBase));
  2422.       }
  2423.       else
  2424.         as_snprintf(ListLine, STRINGSIZE, "=%~02.*u%s",
  2425.                     ListRadixBase, (unsigned)AdrByte, GetIntConstIntelSuffix(ListRadixBase));
  2426.       PopLocHandle();
  2427.     }
  2428.   }
  2429. }
  2430.  
  2431. static void DecodeBIT(Word Index)
  2432. {
  2433.   LongInt AdrLong;
  2434.   UNUSED(Index);
  2435.  
  2436.   if (!ChkArgCnt(1, 1));
  2437.   else if (MomCPU >= CPU80251)
  2438.   {
  2439.     if (DecodeBitAdr(&ArgStr[1], &AdrLong, False) == ModBit251)
  2440.     {
  2441.       PushLocHandle(-1);
  2442.       EnterIntSymbol(&LabPart, AdrLong, SegBData, False);
  2443.       PopLocHandle();
  2444.       *ListLine = '=';
  2445.       DissectBit_251(ListLine + 1, STRINGSIZE - 1, AdrLong);
  2446.     }
  2447.   }
  2448.   else
  2449.   {
  2450.     if (DecodeBitAdr(&ArgStr[1], &AdrLong, False) == ModBit51)
  2451.     {
  2452.       PushLocHandle(-1);
  2453.       EnterIntSymbol(&LabPart, AdrLong, SegBData, False);
  2454.       PopLocHandle();
  2455.       as_snprintf(ListLine, STRINGSIZE, "=%~02.*u%s",
  2456.                   ListRadixBase, (unsigned)AdrLong, GetIntConstIntelSuffix(ListRadixBase));
  2457.     }
  2458.   }
  2459. }
  2460.  
  2461. static void DecodePORT(Word Index)
  2462. {
  2463.   UNUSED(Index);
  2464.  
  2465.   if (ChkMinCPU(CPU80251))
  2466.     CodeEquate(SegIO, 0, 0x1ff);
  2467. }
  2468.  
  2469. /*-------------------------------------------------------------------------*/
  2470. /* dynamische Codetabellenverwaltung */
  2471.  
  2472. static void AddFixed(const char *NName, Word NCode, CPUVar NCPU)
  2473. {
  2474.   order_array_rsv_end(FixedOrders, FixedOrder);
  2475.   FixedOrders[InstrZ].Code = NCode;
  2476.   FixedOrders[InstrZ].MinCPU = NCPU;
  2477.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
  2478. }
  2479.  
  2480. static void AddAcc(const char *NName, Word NCode, CPUVar NCPU)
  2481. {
  2482.   order_array_rsv_end(AccOrders, FixedOrder);
  2483.   AccOrders[InstrZ].Code = NCode;
  2484.   AccOrders[InstrZ].MinCPU = NCPU;
  2485.   AddInstTable(InstTable, NName, InstrZ++, DecodeAcc);
  2486. }
  2487.  
  2488. static void AddCond(const char *NName, Word NCode, CPUVar NCPU)
  2489. {
  2490.   order_array_rsv_end(CondOrders, FixedOrder);
  2491.   CondOrders[InstrZ].Code = NCode;
  2492.   CondOrders[InstrZ].MinCPU = NCPU;
  2493.   AddInstTable(InstTable, NName, InstrZ++, DecodeCond);
  2494. }
  2495.  
  2496. static void AddBCond(const char *NName, Word NCode, CPUVar NCPU)
  2497. {
  2498.   order_array_rsv_end(BCondOrders, FixedOrder);
  2499.   BCondOrders[InstrZ].Code = NCode;
  2500.   BCondOrders[InstrZ].MinCPU = NCPU;
  2501.   AddInstTable(InstTable, NName, InstrZ++, DecodeBCond);
  2502. }
  2503.  
  2504. static void InitFields(void)
  2505. {
  2506.   InstTable = CreateInstTable(203);
  2507.   AddInstTable(InstTable, "MOV"  , 0, DecodeMOV);
  2508.   AddInstTable(InstTable, "ANL"  , 1, DecodeLogic);
  2509.   AddInstTable(InstTable, "ORL"  , 0, DecodeLogic);
  2510.   AddInstTable(InstTable, "XRL"  , 2, DecodeLogic);
  2511.   AddInstTable(InstTable, "MOVC" , 0, DecodeMOVC);
  2512.   AddInstTable(InstTable, "MOVH" , 0, DecodeMOVH);
  2513.   AddInstTable(InstTable, "MOVZ" , 0, DecodeMOVZS);
  2514.   AddInstTable(InstTable, "MOVS" , 0, DecodeMOVZS);
  2515.   AddInstTable(InstTable, "MOVX" , 0, DecodeMOVX);
  2516.   AddInstTable(InstTable, "POP"  , 1, DecodeStack);
  2517.   AddInstTable(InstTable, "PUSH" , 0, DecodeStack);
  2518.   AddInstTable(InstTable, "PUSHW", 2, DecodeStack);
  2519.   AddInstTable(InstTable, "XCH"  , 0, DecodeXCH);
  2520.   AddInstTable(InstTable, "XCHD" , 0, DecodeXCHD);
  2521.   AddInstTable(InstTable, "AJMP" , 0, DecodeABranch);
  2522.   AddInstTable(InstTable, "ACALL", 1, DecodeABranch);
  2523.   AddInstTable(InstTable, "LJMP" , 0, DecodeLBranch);
  2524.   AddInstTable(InstTable, "LCALL", 1, DecodeLBranch);
  2525.   AddInstTable(InstTable, "EJMP" , 0, DecodeEBranch);
  2526.   AddInstTable(InstTable, "ECALL", 1, DecodeEBranch);
  2527.   AddInstTable(InstTable, "JMP"  , 0, DecodeJMP);
  2528.   AddInstTable(InstTable, "CALL" , 0, DecodeCALL);
  2529.   AddInstTable(InstTable, "DJNZ" , 0, DecodeDJNZ);
  2530.   AddInstTable(InstTable, "CJNE" , 0, DecodeCJNE);
  2531.   AddInstTable(InstTable, "ADD"  , 0, DecodeADD);
  2532.   AddInstTable(InstTable, "SUB"  , 0, DecodeSUBCMP);
  2533.   AddInstTable(InstTable, "CMP"  , 1, DecodeSUBCMP);
  2534.   AddInstTable(InstTable, "ADDC" , 0, DecodeADDCSUBB);
  2535.   AddInstTable(InstTable, "SUBB" , 1, DecodeADDCSUBB);
  2536.   AddInstTable(InstTable, "INC"  , 0, DecodeINCDEC);
  2537.   AddInstTable(InstTable, "DEC"  , 1, DecodeINCDEC);
  2538.   AddInstTable(InstTable, "MUL"  , 1, DecodeMULDIV);
  2539.   AddInstTable(InstTable, "DIV"  , 0, DecodeMULDIV);
  2540.   AddInstTable(InstTable, "CLR"  , 1, DecodeBits);
  2541.   AddInstTable(InstTable, "CPL"  , 0, DecodeBits);
  2542.   AddInstTable(InstTable, "SETB" , 2, DecodeBits);
  2543.   AddInstTable(InstTable, "SRA"  , 0, DecodeShift);
  2544.   AddInstTable(InstTable, "SRL"  , 1, DecodeShift);
  2545.   AddInstTable(InstTable, "SLL"  , 3, DecodeShift);
  2546.   AddInstTable(InstTable, "SFR"  , 0, DecodeSFR);
  2547.   AddInstTable(InstTable, "SFRB" , 1, DecodeSFR);
  2548.   AddInstTable(InstTable, "BIT"  , 0, DecodeBIT);
  2549.   AddInstTable(InstTable, "PORT" , 0, DecodePORT);
  2550.  
  2551.   InstrZ = 0;
  2552.   AddFixed("NOP" , 0x0000, CPU87C750);
  2553.   AddFixed("RET" , 0x0022, CPU87C750);
  2554.   AddFixed("RETI", 0x0032, CPU87C750);
  2555.   AddFixed("ERET", 0x01aa, CPU80251);
  2556.   AddFixed("TRAP", 0x01b9, CPU80251);
  2557.  
  2558.   InstrZ = 0;
  2559.   AddAcc("DA"  , 0x00d4, CPU87C750);
  2560.   AddAcc("RL"  , 0x0023, CPU87C750);
  2561.   AddAcc("RLC" , 0x0033, CPU87C750);
  2562.   AddAcc("RR"  , 0x0003, CPU87C750);
  2563.   AddAcc("RRC" , 0x0013, CPU87C750);
  2564.   AddAcc("SWAP", 0x00c4, CPU87C750);
  2565.  
  2566.   InstrZ = 0;
  2567.   AddCond("JC"  , 0x0040, CPU87C750);
  2568.   AddCond("JE"  , 0x0168, CPU80251);
  2569.   AddCond("JG"  , 0x0138, CPU80251);
  2570.   AddCond("JLE" , 0x0128, CPU80251);
  2571.   AddCond("JNC" , 0x0050, CPU87C750);
  2572.   AddCond("JNE" , 0x0178, CPU80251);
  2573.   AddCond("JNZ" , 0x0070, CPU87C750);
  2574.   AddCond("JSG" , 0x0118, CPU80251);
  2575.   AddCond("JSGE", 0x0158, CPU80251);
  2576.   AddCond("JSL" , 0x0148, CPU80251);
  2577.   AddCond("JSLE", 0x0108, CPU80251);
  2578.   AddCond("JZ"  , 0x0060, CPU87C750);
  2579.   AddCond("SJMP", 0x0080, CPU87C750);
  2580.  
  2581.   InstrZ = 0;
  2582.   AddBCond("JB" , 0x0020, CPU87C750);
  2583.   AddBCond("JBC", 0x0010, CPU87C750);
  2584.   AddBCond("JNB", 0x0030, CPU87C750);
  2585.  
  2586.   AddInstTable(InstTable, "REG"  , 0, CodeREG);
  2587. }
  2588.  
  2589. static void DeinitFields(void)
  2590. {
  2591.   DestroyInstTable(InstTable);
  2592.   order_array_free(FixedOrders);
  2593.   order_array_free(AccOrders);
  2594.   order_array_free(CondOrders);
  2595.   order_array_free(BCondOrders);
  2596. }
  2597.  
  2598. /*-------------------------------------------------------------------------*/
  2599. /* Instruktionsdecoder */
  2600.  
  2601. static void MakeCode_51(void)
  2602. {
  2603.   CodeLen = 0;
  2604.   DontPrint = False;
  2605.   OpSize = -1;
  2606.   MinOneIs0 = False;
  2607.  
  2608.   /* zu ignorierendes */
  2609.  
  2610.   if (*OpPart.str.p_str == '\0') return;
  2611.  
  2612.   /* Pseudoanweisungen */
  2613.  
  2614.   if (DecodeIntelPseudo(TargetBigEndian))
  2615.     return;
  2616.  
  2617.   /* suchen */
  2618.  
  2619.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  2620.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  2621. }
  2622.  
  2623. static Boolean IsDef_51(void)
  2624. {
  2625.   switch (*OpPart.str.p_str)
  2626.   {
  2627.     case 'B':
  2628.       return Memo("BIT");
  2629.     case 'S':
  2630.       if (Memo("SFR")) return True;
  2631.       if (MomCPU >= CPU80251) return False;
  2632.       return Memo("SFRB");
  2633.     case 'P':
  2634.       return (MomCPU >= CPU80251) ? Memo("PORT") : False;
  2635.     case 'R':
  2636.       return Memo("REG");
  2637.     default:
  2638.       return False;
  2639.   }
  2640. }
  2641.  
  2642. /*!------------------------------------------------------------------------
  2643.  * \fn     InternSymbol_51(char *pArg, TempResult *pResult)
  2644.  * \brief  handle built-in symbols on 80x51
  2645.  * \param  pArg source argument
  2646.  * \param  pResult destination buffer
  2647.  * ------------------------------------------------------------------------ */
  2648.  
  2649. static void InternSymbol_51(char *pArg, TempResult *pResult)
  2650. {
  2651.   tRegInt Erg;
  2652.   tSymbolSize Size;
  2653.  
  2654.   if (DecodeRegCore(pArg, &Erg, &Size))
  2655.   {
  2656.     pResult->Typ = TempReg;
  2657.     pResult->DataSize = (tSymbolSize)Size;
  2658.     pResult->Contents.RegDescr.Reg = Erg;
  2659.     pResult->Contents.RegDescr.Dissect = DissectReg_51;
  2660.     pResult->Contents.RegDescr.compare = NULL;
  2661.   }
  2662. }
  2663.  
  2664. static void SwitchTo_51(void)
  2665. {
  2666.   TurnWords = False;
  2667.   SetIntConstMode(eIntConstModeIntel);
  2668.  
  2669.   PCSymbol = "$";
  2670.   HeaderID = 0x31;
  2671.   NOPCode = 0x00;
  2672.   DivideChars = ",";
  2673.   HasAttrs = False;
  2674.  
  2675.   /* C251 is entirely different... */
  2676.  
  2677.   if (MomCPU >= CPU80251)
  2678.   {
  2679.     ValidSegs = (1 << SegCode) | (1 << SegIO);
  2680.     Grans[SegCode ] = 1; ListGrans[SegCode ] = 1; SegInits[SegCode ] = 0;
  2681.     SegLimits[SegCode ] = 0xffffffl;
  2682.     Grans[SegIO   ] = 1; ListGrans[SegIO   ] = 1; SegInits[SegIO   ] = 0;
  2683.     SegLimits[SegIO   ] = 0x1ff;
  2684.     DissectBit = DissectBit_251;
  2685.   }
  2686.  
  2687.   /* rest of the pack... */
  2688.  
  2689.   else
  2690.   {
  2691.     ValidSegs=(1 << SegCode) | (1 << SegData) | (1 << SegIData) | (1 << SegXData) | (1 << SegBData);
  2692.  
  2693.     Grans[SegCode ] = 1; ListGrans[SegCode ] = 1; SegInits[SegCode ] = 0;
  2694.     if (MomCPU == CPU80C390)
  2695.       SegLimits[SegCode ] = 0xffffff;
  2696.     else if (MomCPU == CPU87C750)
  2697.       SegLimits[SegCode ] = 0x7ff;
  2698.     else
  2699.       SegLimits[SegCode ] = 0xffff;
  2700.  
  2701.  
  2702.     Grans[SegXData] = 1; ListGrans[SegXData] = 1; SegInits[SegXData] = 0;
  2703.     if (MomCPU == CPU80C390)
  2704.       SegLimits[SegXData] = 0xffffff;
  2705.     else
  2706.       SegLimits[SegXData] = 0xffff;
  2707.  
  2708.     Grans[SegData ] = 1; ListGrans[SegData ] = 1; SegInits[SegData ] = 0x30;
  2709.     SegLimits[SegData ] = 0xff;
  2710.     Grans[SegIData] = 1; ListGrans[SegIData] = 1; SegInits[SegIData] = 0x80;
  2711.     SegLimits[SegIData] = 0xff;
  2712.     Grans[SegBData] = 1; ListGrans[SegBData] = 1; SegInits[SegBData] = 0;
  2713.     SegLimits[SegBData] = 0xff;
  2714.   }
  2715.  
  2716.   MakeCode = MakeCode_51;
  2717.   IsDef = IsDef_51;
  2718.   InternSymbol = InternSymbol_51;
  2719.   DissectReg = DissectReg_51;
  2720.  
  2721.   InitFields();
  2722.   SwitchFrom = DeinitFields;
  2723.   if (!onoff_test_and_set(e_onoff_reg_srcmode))
  2724.     SetFlag(&SrcMode, SrcModeSymName, False);
  2725.   AddONOFF(SrcModeCmdName, &SrcMode, SrcModeSymName, False);
  2726.   onoff_bigendian_add();
  2727. }
  2728.  
  2729. void code51_init(void)
  2730. {
  2731.   CPU87C750 = AddCPU("87C750", SwitchTo_51);
  2732.   CPU8051   = AddCPU("8051"  , SwitchTo_51);
  2733.   CPU8052   = AddCPU("8052"  , SwitchTo_51);
  2734.   CPU80C320 = AddCPU("80C320", SwitchTo_51);
  2735.   CPU80501  = AddCPU("80C501", SwitchTo_51);
  2736.   CPU80502  = AddCPU("80C502", SwitchTo_51);
  2737.   CPU80504  = AddCPU("80C504", SwitchTo_51);
  2738.   CPU80515  = AddCPU("80515" , SwitchTo_51);
  2739.   CPU80517  = AddCPU("80517" , SwitchTo_51);
  2740.   CPU80C390 = AddCPU("80C390", SwitchTo_51);
  2741.   CPU80251  = AddCPU("80C251", SwitchTo_51);
  2742.   CPU80251T = AddCPU("80C251T", SwitchTo_51);
  2743. }
  2744.