Subversion Repositories pentevo

Rev

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

  1. /* codest7.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator SGS-Thomson ST7/STM8                                        */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12.  
  13. #include <ctype.h>
  14. #include <string.h>
  15. #include <assert.h>
  16.  
  17. #include "bpemu.h"
  18. #include "strutil.h"
  19. #include "nls.h"
  20. #include "asmdef.h"
  21. #include "asmsub.h"
  22. #include "asmpars.h"
  23. #include "asmitree.h"
  24. #include "asmstructs.h"
  25. #include "asmallg.h"
  26. #include "codepseudo.h"
  27. #include "motpseudo.h"
  28. #include "codevars.h"
  29. #include "errmsg.h"
  30.  
  31. #include "codest7.h"
  32.  
  33. #if (defined __GNUC__) && (__GNUC__==14)
  34. # warning You are using GCC 14.  This version has known issues in higher optimization levels that break compilation of this module. Assure you are using an optimization below -O2 or consider using a different compiler.
  35. #endif
  36.  
  37. typedef enum
  38. {
  39.   eModNone = -1,
  40.   eModImm = 0,        /* #byte */
  41.   eModAbs8,           /* shortmem */
  42.   eModAbs16,          /* longmem */
  43.   eModAbs24,          /* extmem */
  44.   eModIX,             /* (X) */
  45.   eModIX8,            /* (shortoff,X) */
  46.   eModIX16,           /* (longoff,X) */
  47.   eModIX24,           /* (extoff,X) */
  48.   eModIY,             /* (Y) */
  49.   eModIY8,            /* (shortoff,Y) */
  50.   eModIY16,           /* (longoff,Y) */
  51.   eModIY24,           /* (extoff,Y) */
  52.   eModISP8,           /* (shortoff,SP) (STM8 only) */
  53.   eModIAbs8,          /* [shortptr.b] (ST7 only) */
  54.   eModIAbs16,         /* [shortptr.w] */
  55.   eModI16Abs16,       /* [longptr.w] (STM8 only) */
  56.   eModI16Abs24,       /* [longptr.e] (STM8 only) */
  57.   eModIXAbs8,         /* ([shortptr.b],X) */
  58.   eModIXAbs16,        /* ([<longptr.w],X) */
  59.   eModI16XAbs16,      /* ([>longptr.w],X) (STM8 only) */
  60.   eModI16XAbs24,      /* ([>longptr.e],X) (STM8 only) */
  61.   eModIYAbs8,         /* ([shortptr.b],Y) */
  62.   eModIYAbs16,        /* ([<longptr.w],Y) */
  63.   eModI16YAbs24,      /* ([>longptr.e],Y) (STM8 only) */
  64.   eModA,              /* A */
  65.   eModX,              /* X */
  66.   eModXL,             /* XL (STM8 only) */
  67.   eModXH,             /* XH (STM8 only) */
  68.   eModY,              /* Y */
  69.   eModYL,             /* YL (STM8 only) */
  70.   eModYH,             /* YH (STM8 only) */
  71.   eModS               /* SP */
  72.   /* bit mask is full, 32 modes! */
  73. } tAdrMode;
  74.  
  75. #define MModImm (1ul << eModImm)
  76. #define MModAbs8 (1ul << eModAbs8)
  77. #define MModAbs16 (1ul << eModAbs16)
  78. #define MModAbs24 (1ul << eModAbs24)
  79. #define MModIX (1ul << eModIX)
  80. #define MModIX8 (1ul << eModIX8)
  81. #define MModIX16 (1ul << eModIX16)
  82. #define MModIX24 (1ul << eModIX24)
  83. #define MModIY (1ul << eModIY)
  84. #define MModIY8 (1ul << eModIY8)
  85. #define MModIY16 (1ul << eModIY16)
  86. #define MModIY24 (1ul << eModIY24)
  87. #define MModISP8 (1ul << eModISP8)
  88. #define MModIAbs8 (1ul << eModIAbs8)
  89. #define MModIAbs16 (1ul << eModIAbs16)
  90. #define MModI16Abs16 (1ul << eModI16Abs16)
  91. #define MModI16Abs24 (1ul << eModI16Abs24)
  92. #define MModIXAbs8 (1ul << eModIXAbs8)
  93. #define MModIXAbs16 (1ul << eModIXAbs16)
  94. #define MModI16XAbs16 (1ul << eModI16XAbs16)
  95. #define MModI16XAbs24 (1ul << eModI16XAbs24)
  96. #define MModIYAbs8 (1ul << eModIYAbs8)
  97. #define MModIYAbs16 (1ul << eModIYAbs16)
  98. #define MModI16YAbs24 (1ul << eModI16YAbs24)
  99. #define MModA (1ul << eModA)
  100. #define MModX (1ul << eModX)
  101. #define MModXL (1ul << eModXL)
  102. #define MModXH (1ul << eModXH)
  103. #define MModY (1ul << eModY)
  104. #define MModYL (1ul << eModYL)
  105. #define MModYH (1ul << eModYH)
  106. #define MModS (1ul << eModS)
  107.  
  108. typedef enum
  109. {
  110.   eCoreST7,
  111.   eCoreSTM8
  112. } tCPUCore;
  113.  
  114. typedef struct
  115. {
  116.   const char *pName;
  117.   IntType AddrIntType;
  118.   tCPUCore Core;
  119. } tCPUProps;
  120.  
  121. typedef struct
  122. {
  123.   tAdrMode Mode;
  124.   Byte Part;
  125.   unsigned Cnt;
  126.   Byte Vals[3];
  127. } tAdrVals;
  128.  
  129. static const tCPUProps *pCurrCPUProps;
  130. static tSymbolSize OpSize;
  131. static Byte PrefixCnt;
  132.  
  133. /*--------------------------------------------------------------------------*/
  134.  
  135. /*!------------------------------------------------------------------------
  136.  * \fn     ResetAdrVals(tAdrVals *pAdrVals)
  137.  * \brief  clear AdrVals structure
  138.  * \param  pAdrVals struct to clear/reset
  139.  * ------------------------------------------------------------------------ */
  140.  
  141. static void ResetAdrVals(tAdrVals *pAdrVals)
  142. {
  143.   pAdrVals->Mode = eModNone;
  144.   pAdrVals->Part = 0;
  145.   pAdrVals->Cnt = 0;
  146. }
  147.  
  148. static void FillAdrVals(tAdrVals *pAdrVals, LongWord Value, tSymbolSize Size)
  149. {
  150.   pAdrVals->Cnt = 0;
  151.   switch (Size)
  152.   {
  153.     case eSymbolSize24Bit:
  154.       pAdrVals->Vals[pAdrVals->Cnt++] = (Value >> 16) & 255;
  155.       /* fall-through */
  156.     case eSymbolSize16Bit:
  157.       pAdrVals->Vals[pAdrVals->Cnt++] = (Value >> 8) & 255;
  158.       /* fall-through */
  159.     case eSymbolSize8Bit:
  160.       pAdrVals->Vals[pAdrVals->Cnt++] = Value & 255;
  161.       /* fall-through */
  162.     default:
  163.       break;
  164.   }
  165. }
  166.  
  167. static void ExtendAdrVals(tAdrVals *pAdrVals)
  168. {
  169.   switch (pAdrVals->Mode)
  170.   {
  171.     case eModAbs8:
  172.       pAdrVals->Mode = eModAbs16;
  173.       pAdrVals->Vals[1] = pAdrVals->Vals[0];
  174.       pAdrVals->Vals[0] = 0;
  175.       pAdrVals->Cnt = 2;
  176.       break;
  177.     default:
  178.       break;
  179.   }
  180. }
  181.  
  182. /*!------------------------------------------------------------------------
  183.  * \fn     AddPrefix(Byte Pref)
  184.  * \brief  add another prefix byte
  185.  * \param  Pref prefix to add
  186.  * ------------------------------------------------------------------------ */
  187.  
  188. static void AddPrefix(Byte Pref)
  189. {
  190.   BAsmCode[PrefixCnt++] = Pref;
  191. }
  192.  
  193. /*!------------------------------------------------------------------------
  194.  * \fn     ModeInMask(LongWord Mask, tAdrMode Mode)
  195.  * \brief  check whether certain addressing mode is set in mask
  196.  * \param  Mask list of allowed modes
  197.  * \param  Mode addressing mode to check
  198.  * ------------------------------------------------------------------------ */
  199.  
  200. static Boolean ModeInMask(LongWord Mask, tAdrMode Mode)
  201. {
  202.   return !!((Mask >> Mode) & 1);
  203. }
  204.  
  205. /*!------------------------------------------------------------------------
  206.  * \fn     CutSizeSuffix(tStrComp *pArg)
  207.  * \brief  cut off possible size suffix (.b .w .e) from argument
  208.  * \param  pArg argument
  209.  * \return deduced size or unknown if no known suffix
  210.  * ------------------------------------------------------------------------ */
  211.  
  212. static tSymbolSize CutSizeSuffix(const tStrComp *pArg)
  213. {
  214.   int l = strlen(pArg->str.p_str);
  215.  
  216.   if ((l >= 3) && (pArg->str.p_str[l - 2] == '.'))
  217.   {
  218.     switch (as_toupper(pArg->str.p_str[l - 1]))
  219.     {
  220.       case 'B':
  221.         pArg->str.p_str[l - 2] = '\0';
  222.         return eSymbolSize8Bit;
  223.       case 'W':
  224.         pArg->str.p_str[l - 2] = '\0';
  225.         return eSymbolSize16Bit;
  226.       case 'E':
  227.         pArg->str.p_str[l - 2] = '\0';
  228.         return eSymbolSize24Bit;
  229.       default:
  230.         break;
  231.     }
  232.   }
  233.   return eSymbolSizeUnknown;
  234. }
  235.  
  236. /*!------------------------------------------------------------------------
  237.  * \fn     DecideSize(LongWord Mask, const tStrComp *pArg, tAdrMode Mode8, tAdrMode Mode16, tAdrMode Mode24, Byte Part8, Byte Part16, Byte Part24, Boolean IsCode, tAdrVals *pAdrVals)
  238.  * \brief  decide about length of absolute or indexed operand
  239.  * \param  Mask bit mask of allowed modes
  240.  * \param  pArg address argument
  241.  * \param  Mode8 AdrMode for 8-bit address/displacement
  242.  * \param  Mode16 AdrMode for 16-bit address/displacement
  243.  * \param  Mode24 AdrMode for 24-bit address/displacement
  244.  * \param  Part8 AdrPart for 8-bit address/displacement
  245.  * \param  Part16 AdrPart for 16-bit address/displacement
  246.  * \param  Part24 AdrPart for 24-bit address/displacement
  247.  * \param  IsCode Address is in code space (check for same page)
  248.  * \param  pAdrVals destination to fill out
  249.  * ------------------------------------------------------------------------ */
  250.  
  251. static void DecideSize(LongWord Mask, const tStrComp *pArg, tAdrMode Mode8, tAdrMode Mode16, tAdrMode Mode24, Byte Part8, Byte Part16, Byte Part24, Boolean IsCode, tAdrVals *pAdrVals)
  252. {
  253.   tSymbolSize Size = eSymbolSizeUnknown;
  254.   IntType SizeType;
  255.   LongWord Value;
  256.   Boolean OK;
  257.   tSymbolFlags Flags;
  258.  
  259.   if ((Mode8 != eModNone) && !ModeInMask(Mask, Mode8))
  260.     Mode8 = eModNone;
  261.   if ((Mode16 != eModNone) && !ModeInMask(Mask, Mode16))
  262.     Mode16 = eModNone;
  263.   if ((Mode24 != eModNone) && !ModeInMask(Mask, Mode24))
  264.     Mode24 = eModNone;
  265.  
  266.   Size = CutSizeSuffix(pArg);
  267.   switch (Size)
  268.   {
  269.     case eSymbolSize8Bit:
  270.       if (Mode8 == eModNone)
  271.         goto InvSize;
  272.       break;
  273.     case eSymbolSize16Bit:
  274.       if (Mode16 == eModNone)
  275.         goto InvSize;
  276.       break;
  277.     case eSymbolSize24Bit:
  278.       if (Mode24 == eModNone)
  279.         goto InvSize;
  280.       break;
  281.     default:
  282.       break;
  283.     InvSize:
  284.       WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  285.       return;
  286.   }
  287.  
  288.   if (IsCode)
  289.     SizeType = pCurrCPUProps->AddrIntType;
  290.   else switch (Size)
  291.   {
  292.     case eSymbolSize24Bit:
  293.       SizeType = Int24;
  294.       break;
  295.     case eSymbolSize16Bit:
  296.       SizeType = Int16;
  297.       break;
  298.     case eSymbolSize8Bit:
  299.       SizeType = Int8;
  300.       break;
  301.     default:
  302.       if (Mode24 != eModNone)
  303.         SizeType = Int24;
  304.       else if (Mode16 != eModNone)
  305.         SizeType = Int16;
  306.       else
  307.         SizeType = Int8;
  308.       break;
  309.   }
  310.   Value = EvalStrIntExpressionWithFlags(pArg, SizeType, &OK, &Flags);
  311.  
  312.   if (OK)
  313.   {
  314.     LongWord SrcAddress = IsCode ? EProgCounter() + 3 : 0;
  315.  
  316.     if (Size == eSymbolSizeUnknown)
  317.     {
  318.       if ((Value <= 0xff) && (Mode8 != eModNone))
  319.         Size = eSymbolSize8Bit;
  320.       else if (((Value >> 16) == (SrcAddress >> 16)) && (Mode16 != eModNone))
  321.         Size = eSymbolSize16Bit;
  322.       else
  323.         Size = eSymbolSize24Bit;
  324.     }
  325.  
  326.     /* this may only happen if SizeTypes was forced to 24 Bit because of code addessing: */
  327.  
  328.     if ((Size == eSymbolSize24Bit) && (Mode24 == eModNone) && !mSymbolQuestionable(Flags))
  329.     {
  330.       WrStrErrorPos(ErrNum_TargOnDiffSection, pArg);
  331.       return;
  332.     }
  333.  
  334.     FillAdrVals(pAdrVals, Value, Size);
  335.     switch (Size)
  336.     {
  337.       case eSymbolSize8Bit:
  338.         pAdrVals->Part = Part8;
  339.         pAdrVals->Mode = Mode8;
  340.         break;
  341.       case eSymbolSize16Bit:
  342.         pAdrVals->Part = Part16;
  343.         pAdrVals->Mode = Mode16;
  344.         break;
  345.       case eSymbolSize24Bit:
  346.         pAdrVals->Part = Part24;
  347.         pAdrVals->Mode = Mode24;
  348.         break;
  349.       default:
  350.         assert(0);
  351.     }
  352.   }
  353. }
  354.  
  355. /*!------------------------------------------------------------------------
  356.  * \fn     DecideIndirectSize(LongWord Mask, const tStrComp *pArg,
  357.                               tAdrMode Mode8_8, tAdrMode Mode8_16, tAdrMode Mode16_16, tAdrMode Mode16_24,
  358.                               Byte Part8_8, Byte Part8_16, Byte Part16_16, Byte Part16_24,
  359.                               tAdrVals *pAdrVals)
  360.  * \brief  address mode decision for indirect operands []
  361.  * \param  Mask bit mask of allowed modes
  362.  * \param  pArg expression
  363.  * \param  Mode8_8 requested mode for 8-bit pointer on 8-bit address
  364.  * \param  Mode8_16 requested mode for 16-bit pointer on 8-bit address
  365.  * \param  Mode16_16 requested mode for 16-bit pointer on 16-bit address
  366.  * \param  Mode16_24 requested mode for 24-bit pointer on 16-bit address
  367.  * \param  Part8_8 Address part for 8-bit pointer on 8-bit address
  368.  * \param  Part8_16 Address part for 16-bit pointer on 8-bit address
  369.  * \param  Part16_16 Address part for 16-bit pointer on 16-bit address
  370.  * \param  Part16_24 Address part for 24-bit pointer on 16-bit address
  371.  * \param  pAdrVals destination to fill out
  372.  * \return True if successfully parsed
  373.  * ------------------------------------------------------------------------ */
  374.  
  375. static Boolean DecideIndirectSize(LongWord Mask, const tStrComp *pArg,
  376.                                   tAdrMode Mode8_8, tAdrMode Mode8_16, tAdrMode Mode16_16, tAdrMode Mode16_24,
  377.                                   Byte Part8_8, Byte Part8_16, Byte Part16_16, Byte Part16_24,
  378.                                   tAdrVals *pAdrVals)
  379. {
  380.   Boolean OK;
  381.   int Offset;
  382.   tSymbolSize AddrSize = eSymbolSizeUnknown,
  383.               PtrSize = eSymbolSizeUnknown;
  384.   IntType SizeType;
  385.   Word Address;
  386.   tSymbolFlags Flags;
  387.  
  388.   if ((Mode8_8 != eModNone) && !ModeInMask(Mask, Mode8_8))
  389.     Mode8_8 = eModNone;
  390.   if ((Mode8_16 != eModNone) && !ModeInMask(Mask, Mode8_16))
  391.     Mode8_16 = eModNone;
  392.   if ((Mode16_16 != eModNone) && !ModeInMask(Mask, Mode16_16))
  393.     Mode16_16 = eModNone;
  394.   if ((Mode16_24 != eModNone) && !ModeInMask(Mask, Mode16_24))
  395.     Mode16_24 = eModNone;
  396.  
  397.   /* Cut off address byte size, signified by leading '<' or '>': */
  398.  
  399.   switch (*pArg->str.p_str)
  400.   {
  401.     case '>':
  402.       Offset = 1;
  403.       AddrSize = eSymbolSize16Bit;
  404.       break;
  405.     case '<':
  406.       Offset = 1;
  407.       AddrSize = eSymbolSize8Bit;
  408.       break;
  409.     default:
  410.       Offset = 0;
  411.       AddrSize = eSymbolSizeUnknown;
  412.   }
  413.  
  414.   /* Cut off pointer size, signified by trailing '.w/.e' if 16/24 bit: */
  415.  
  416.   PtrSize = CutSizeSuffix(pArg);
  417.  
  418.   /* if no pointer size given, assume the smallest possible one: */
  419.  
  420.   if (PtrSize == eSymbolSizeUnknown)
  421.   {
  422.     if (Mode8_8 != eModNone)
  423.       PtrSize = eSymbolSize8Bit;
  424.     else if ((Mode8_16 != eModNone) || (Mode16_16 != eModNone))
  425.       PtrSize = eSymbolSize16Bit;
  426.     else
  427.       PtrSize = eSymbolSize24Bit;
  428.   }
  429.  
  430.   switch (AddrSize)
  431.   {
  432.     case eSymbolSize16Bit:
  433.       SizeType = Int16;
  434.       break;
  435.     case eSymbolSize8Bit:
  436.       SizeType = Int8;
  437.       break;
  438.     default:
  439.       if ((Mode16_16 != eModNone) || (Mode16_24 != eModNone))
  440.         SizeType = Int16;
  441.       else
  442.         SizeType = Int8;
  443.       break;
  444.   }
  445.  
  446.   Address = EvalStrIntExpressionOffsWithFlags(pArg, Offset, SizeType, &OK, &Flags);
  447.   if (mFirstPassUnknown(Flags) && (Mode16_16 == eModNone) && (Mode16_24 == eModNone))
  448.     Address &= 0xff;
  449.  
  450.   if (OK)
  451.   {
  452.     /* Finally decide about address size: */
  453.  
  454.     if (eSymbolSizeUnknown == AddrSize)
  455.     {
  456.       if ((Address <= 0xff) && (PtrSize == eSymbolSize8Bit) && (Mode8_8 != eModNone))
  457.         AddrSize = eSymbolSize8Bit;
  458.       else if ((Address <= 0xff) && (PtrSize == eSymbolSize16Bit) && (Mode8_16 != eModNone))
  459.         AddrSize = eSymbolSize8Bit;
  460.       else
  461.         AddrSize = eSymbolSize16Bit;
  462.     }
  463.  
  464.     FillAdrVals(pAdrVals, Address, AddrSize);
  465.     if (eSymbolSize16Bit == AddrSize)
  466.     {
  467.       if (PtrSize == eSymbolSize24Bit)
  468.       {
  469.         pAdrVals->Part = Part16_24;
  470.         pAdrVals->Mode = Mode16_24;
  471.       }
  472.       else
  473.       {
  474.         pAdrVals->Part = Part16_16;
  475.         pAdrVals->Mode = Mode16_16;
  476.       }
  477.     }
  478.     else
  479.     {
  480.       if (PtrSize == eSymbolSize16Bit)
  481.       {
  482.         pAdrVals->Part = Part8_16;
  483.         pAdrVals->Mode = Mode8_16;
  484.       }
  485.       else
  486.       {
  487.         pAdrVals->Part = Part8_8;
  488.         pAdrVals->Mode = Mode8_8;
  489.       }
  490.     }
  491.   }
  492.   return OK;
  493. }
  494.  
  495. /*!------------------------------------------------------------------------
  496.  * \fn     ChkAdrMode(tAdrMode *pAdrMode, LongWord Mask, tErrorNum ErrorNum, const tStrComp *pArg)
  497.  * \brief  check for allowed addressing mode
  498.  * \param  pAdrMode parsed addressing mode (in/out)
  499.  * \param  Mask list of allowed modes
  500.  * \param  ErrorNum error message to emit if not allowed
  501.  * \param  pArg offending arg
  502.  * \return True if mode is OK
  503.  * ------------------------------------------------------------------------ */
  504.  
  505. static Boolean ChkAdrMode(tAdrMode *pAdrMode, LongWord Mask, tErrorNum ErrorNum, const tStrComp *pArg)
  506. {
  507.   if ((*pAdrMode != eModNone) && (!(Mask & (1ul << *pAdrMode))))
  508.   {
  509.     WrStrErrorPos(ErrorNum, pArg);
  510.     *pAdrMode = eModNone;
  511.     return False;
  512.   }
  513.   return True;
  514. }
  515.  
  516. /*!------------------------------------------------------------------------
  517.  * \fn     ChkAdrValsMode(tAdrVals *pAdrVals, LongWord Mask, tErrorNum ErrorNum, const tStrComp *pArg)
  518.  * \brief  check for allowed addressing mode
  519.  * \param  pAdrVals parsed addressing mode (in/out)
  520.  * \param  Mask list of allowed modes
  521.  * \param  ErrorNum error message to emit if not allowed
  522.  * \param  pArg offending arg
  523.  * \return True if mode is OK
  524.  * ------------------------------------------------------------------------ */
  525.  
  526. static Boolean ChkAdrValsMode(tAdrVals *pAdrVals, LongWord Mask, tErrorNum ErrorNum, const tStrComp *pArg)
  527. {
  528.   if (!ChkAdrMode(&pAdrVals->Mode, Mask, ErrorNum, pArg))
  529.   {
  530.     pAdrVals->Cnt = 0;
  531.     return False;
  532.   }
  533.   return True;
  534. }
  535.  
  536. /*!------------------------------------------------------------------------
  537.  * \fn     DecodeRegCore(const tStrComp *pArg, tAdrMode *pResult)
  538.  * \brief  check whether argument is a CPU register
  539.  * \param  pArg argument to check
  540.  * \param  pResult resulting mode if it is a register
  541.  * \return True if argument is a register
  542.  * ------------------------------------------------------------------------ */
  543.  
  544. static Boolean DecodeRegCore(const tStrComp *pArg, tAdrMode *pResult)
  545. {
  546.   *pResult = eModNone;
  547.  
  548.   if (!as_strcasecmp(pArg->str.p_str, "A"))
  549.   {
  550.     *pResult = eModA;
  551.     return True;
  552.   }
  553.  
  554.   if (!as_strcasecmp(pArg->str.p_str, "X"))
  555.   {
  556.     *pResult = eModX;
  557.     return True;
  558.   }
  559.   if (!as_strcasecmp(pArg->str.p_str, "XL"))
  560.   {
  561.     *pResult = eModXL;
  562.     return True;
  563.   }
  564.   if (!as_strcasecmp(pArg->str.p_str, "XH"))
  565.   {
  566.     *pResult = eModXH;
  567.     return True;
  568.   }
  569.  
  570.   if (!as_strcasecmp(pArg->str.p_str, "Y"))
  571.   {
  572.     *pResult = eModY;
  573.     return True;
  574.   }
  575.   if (!as_strcasecmp(pArg->str.p_str, "YL"))
  576.   {
  577.     *pResult = eModYL;
  578.     return True;
  579.   }
  580.   if (!as_strcasecmp(pArg->str.p_str, "YH"))
  581.   {
  582.     *pResult = eModYH;
  583.     return True;
  584.   }
  585.  
  586.   if ((!as_strcasecmp(pArg->str.p_str, "S"))
  587.    || ((pCurrCPUProps->Core == eCoreSTM8) && !as_strcasecmp(pArg->str.p_str, "SP")))
  588.   {
  589.     *pResult = eModS;
  590.     return True;
  591.   }
  592.  
  593.   return False;
  594. }
  595.  
  596. /*!------------------------------------------------------------------------
  597.  * \fn     DecodeReg(const tStrComp *pArg, tAdrMode *pResult, LongWord Mask)
  598.  * \brief  decode addressing expression, registers-only
  599.  * \param  pArg argument
  600.  * \param  pResult resulting mode
  601.  * \param  Mask list of allowed modes
  602.  * \return True if argument is a CPU register
  603.  * ------------------------------------------------------------------------ */
  604.  
  605. static Boolean DecodeReg(const tStrComp *pArg, tAdrMode *pResult, LongWord Mask)
  606. {
  607.   return DecodeRegCore(pArg, pResult)
  608.       && ChkAdrMode(pResult, Mask, ErrNum_InvReg, pArg);
  609. }
  610.  
  611. /*!------------------------------------------------------------------------
  612.  * \fn     DecodeAdr(const tStrComp *pArg, LongWord Mask, Boolean IsCode, tAdrVals *pAdrVals)
  613.  * \brief  decode addressing expression
  614.  * \param  pArg argument
  615.  * \param  Mask list of allowed masks
  616.  * \param  IsCode is expression a jump/call address?
  617.  * \param  pAdrVals destination to fill out
  618.  * \return True if successfully parsed
  619.  * ------------------------------------------------------------------------ */
  620.  
  621. static Boolean DecodeAdr(const tStrComp *pArg, LongWord Mask, Boolean IsCode, tAdrVals *pAdrVals)
  622. {
  623.   Boolean OK;
  624.   int ArgLen;
  625.  
  626.   ArgLen = strlen(pArg->str.p_str);
  627.  
  628.   ResetAdrVals(pAdrVals);
  629.  
  630.   /* Register ? */
  631.  
  632.   if (DecodeRegCore(pArg, &pAdrVals->Mode))
  633.   {
  634.     switch (pAdrVals->Mode)
  635.     {
  636.       case eModY:
  637.       case eModYL:
  638.       case eModYH:
  639.         AddPrefix(0x90);
  640.         break;
  641.       default:
  642.         break;
  643.     }
  644.     goto chk;
  645.   }
  646.  
  647.   /* immediate ? */
  648.  
  649.   if (*pArg->str.p_str == '#')
  650.   {
  651.     Word Value = EvalStrIntExpressionOffs(pArg, 1, (OpSize == eSymbolSize16Bit) ? Int16 : Int8, &OK);
  652.     if (OK)
  653.     {
  654.       pAdrVals->Mode = eModImm;
  655.       pAdrVals->Part = 0xa;
  656.       FillAdrVals(pAdrVals, Value, OpSize);
  657.     }
  658.     goto chk;
  659.   }
  660.  
  661.   /* speicherindirekt ? */
  662.  
  663.   if ((*pArg->str.p_str == '[') && (pArg->str.p_str[ArgLen - 1] == ']'))
  664.   {
  665.     tStrComp Comp;
  666.     Boolean OK;
  667.  
  668.     StrCompRefRight(&Comp, pArg, 1);
  669.     Comp.str.p_str[ArgLen - 2] = '\0'; Comp.Pos.Len--;
  670.     OK = DecideIndirectSize(Mask, &Comp, eModIAbs8, eModIAbs16, eModI16Abs16, eModI16Abs24, 0xb, 0xc, 0xc, 0xb, pAdrVals);
  671.     Comp.str.p_str[ArgLen - 2] = ']';
  672.     if (OK)
  673.       AddPrefix((pAdrVals->Mode == eModI16Abs16) ? 0x72: 0x92);
  674.     goto chk;
  675.   }
  676.  
  677.   /* sonstwie indirekt ? */
  678.  
  679.   if (IsIndirect(pArg->str.p_str))
  680.   {
  681.     tStrComp Comp, Left, Right;
  682.     Boolean YReg = False, SPReg = False;
  683.     char *p;
  684.  
  685.     StrCompRefRight(&Comp, pArg, 1);
  686.     StrCompShorten(&Comp, 1);
  687.  
  688.     /* ein oder zwei Argumente ? */
  689.  
  690.     p = QuotPos(Comp.str.p_str, ',');
  691.     if (!p)
  692.     {
  693.       pAdrVals->Part = 0xf;
  694.       if (!as_strcasecmp(Comp.str.p_str, "X")) pAdrVals->Mode = eModIX;
  695.       else if (!as_strcasecmp(Comp.str.p_str, "Y"))
  696.       {
  697.         pAdrVals->Mode = eModIY;
  698.         AddPrefix(0x90);
  699.       }
  700.       else WrStrErrorPos(ErrNum_InvReg, &Comp);
  701.       goto chk;
  702.     }
  703.  
  704.     StrCompSplitRef(&Left, &Right, &Comp, p);
  705.  
  706.     if (!as_strcasecmp(Left.str.p_str, "X"))
  707.       Left = Right;
  708.     else if (!as_strcasecmp(Right.str.p_str, "X"));
  709.     else if (!as_strcasecmp(Left.str.p_str, "Y"))
  710.     {
  711.       Left = Right;
  712.       YReg = True;
  713.     }
  714.     else if (!as_strcasecmp(Right.str.p_str, "Y"))
  715.       YReg = True;
  716.     else if (!as_strcasecmp(Left.str.p_str, "SP"))
  717.     {
  718.       Left = Right;
  719.       SPReg = True;
  720.     }
  721.     else if (!as_strcasecmp(Right.str.p_str, "SP"))
  722.       SPReg = True;
  723.     else
  724.     {
  725.       WrStrErrorPos(ErrNum_InvAddrMode, &Comp);
  726.       return False;
  727.     }
  728.  
  729.     /* speicherindirekt ? */
  730.  
  731.     ArgLen = strlen(Left.str.p_str);
  732.     if ((*Left.str.p_str == '[') && (Left.str.p_str[ArgLen - 1] == ']'))
  733.     {
  734.       StrCompRefRight(&Right, &Left, 1);
  735.       StrCompShorten(&Right, 1);
  736.       if (YReg)
  737.       {
  738.         if (DecideIndirectSize(Mask, &Right, eModIYAbs8, eModIYAbs16, eModNone, eModI16YAbs24, 0xe, 0xd, 0x0, 0xa, pAdrVals))
  739.           AddPrefix(0x91);
  740.       }
  741.       else
  742.       {
  743.         if (DecideIndirectSize(Mask, &Right, eModIXAbs8, eModIXAbs16, eModI16XAbs16, eModI16YAbs24, 0xe, 0xd, 0xd, 0xa, pAdrVals))
  744.           AddPrefix((pAdrVals->Mode == eModI16XAbs16) ? 0x72 : 0x92);
  745.       }
  746.     }
  747.     else
  748.     {
  749.       if (YReg) DecideSize(Mask, &Left, eModIY8, eModIY16, eModIY24, 0xe, 0xd, 0xa, IsCode, pAdrVals);
  750.       else if (SPReg) DecideSize(Mask, &Left, eModISP8, eModNone, eModNone, 0x1, 0x0, 0x0, IsCode, pAdrVals);
  751.       else DecideSize(Mask, &Left, eModIX8, eModIX16, eModIX24, 0xe, 0xd, 0xa, IsCode, pAdrVals);
  752.       if ((pAdrVals->Mode != eModNone) && YReg) AddPrefix(0x90);
  753.     }
  754.  
  755.     goto chk;
  756.   }
  757.  
  758.   /* dann absolut */
  759.  
  760.   DecideSize(Mask, pArg, eModAbs8, eModAbs16, eModAbs24, 0xb, 0xc, 0xb, IsCode, pAdrVals);
  761.  
  762. chk:
  763.   return ChkAdrValsMode(pAdrVals, Mask, ErrNum_InvAddrMode, pArg);
  764. }
  765.  
  766. /*!------------------------------------------------------------------------
  767.  * \fn     ConstructMask(LongWord TotMask, tSymbolSize OpSize)
  768.  * \brief  construct actual bit mask of allowed addressing modes from overall list
  769.  * \param  TotMask overall list
  770.  * \param  OpSize operand size in use (8/16/unknown)
  771.  * \return actual mask
  772.  * ------------------------------------------------------------------------ */
  773.  
  774. static LongWord ConstructMask(LongWord TotMask, tSymbolSize OpSize)
  775. {
  776.   if (pCurrCPUProps->Core == eCoreST7)
  777.   {
  778.     /* not present on ST7 */
  779.  
  780.     TotMask &= ~(MModISP8 | MModI16Abs16 | MModI16XAbs16 | MModXL | MModYL | MModXH | MModYH);
  781.  
  782.     /* SP/X/Y are 8 bits wide on ST7 */
  783.  
  784.     if (OpSize == eSymbolSize16Bit)
  785.       TotMask &= ~(MModX | MModY | MModS);
  786.   }
  787.  
  788.   if (pCurrCPUProps->Core == eCoreSTM8)
  789.   {
  790.     /* removed on STM8 */
  791.  
  792.     TotMask &= ~(MModIAbs8 | MModIXAbs8 | MModIYAbs8);
  793.  
  794.     /* SP/X/Y changed to 16 bits on STM8 */
  795.  
  796.     if (OpSize == eSymbolSize8Bit)
  797.       TotMask &= ~(MModX | MModY | MModS);
  798.   }
  799.  
  800.   return TotMask;
  801. }
  802.  
  803. /*--------------------------------------------------------------------------*/
  804. /* Bit Symbol Handling */
  805.  
  806. /*
  807.  * Compact representation of bits in symbol table:
  808.  * bits 0..2: bit position
  809.  * bits 3...10/18: register address in memory space (first 256/64K)
  810.  */
  811.  
  812. /*!------------------------------------------------------------------------
  813.  * \fn     EvalBitPosition(const tStrComp *pArg, Boolean *pOK)
  814.  * \brief  evaluate bit position
  815.  * \param  bit position argument (with or without #)
  816.  * \param  pOK parsing OK?
  817.  * \return numeric bit position
  818.  * ------------------------------------------------------------------------ */
  819.  
  820. static LongWord EvalBitPosition(const tStrComp *pArg, Boolean *pOK)
  821. {
  822.   return EvalStrIntExpressionOffs(pArg, !!(*pArg->str.p_str == '#'), UInt3, pOK);
  823. }
  824.  
  825. /*!------------------------------------------------------------------------
  826.  * \fn     AssembleBitSymbol(Byte BitPos, Word Address)
  827.  * \brief  build the compact internal representation of a bit symbol
  828.  * \param  BitPos bit position in word
  829.  * \param  Address register address
  830.  * \return compact representation
  831.  * ------------------------------------------------------------------------ */
  832.  
  833. static LongWord AssembleBitSymbol(Byte BitPos, Word Address)
  834. {
  835.   return (BitPos & 7)
  836.        | (((LongWord)Address & 0xffff) << 3);
  837. }
  838.  
  839. /*!------------------------------------------------------------------------
  840.  * \fn     DecodeBitArg2(LongWord *pResult, const tStrComp *pRegArg, const tStrComp *pBitArg)
  841.  * \brief  encode a bit symbol, address & bit position separated
  842.  * \param  pResult resulting encoded bit
  843.  * \param  pRegArg register argument
  844.  * \param  pBitArg bit argument
  845.  * \return True if success
  846.  * ------------------------------------------------------------------------ */
  847.  
  848. static Boolean DecodeBitArg2(LongWord *pResult, const tStrComp *pRegArg, const tStrComp *pBitArg)
  849. {
  850.   Boolean OK;
  851.   LongWord Addr;
  852.   Byte BitPos;
  853.  
  854.   BitPos = EvalBitPosition(pBitArg, &OK);
  855.   if (!OK)
  856.     return False;
  857.  
  858.   Addr = EvalStrIntExpression(pRegArg, (pCurrCPUProps->Core == eCoreSTM8) ? UInt16 : UInt8, &OK);
  859.   if (!OK)
  860.     return False;
  861.  
  862.   *pResult = AssembleBitSymbol(BitPos, Addr);
  863.  
  864.   return True;
  865. }
  866.  
  867. /*!------------------------------------------------------------------------
  868.  * \fn     DecodeBitArg(LongWord *pResult, int Start, int Stop)
  869.  * \brief  encode a bit symbol from instruction argument(s)
  870.  * \param  pResult resulting encoded bit
  871.  * \param  Start first argument
  872.  * \param  Stop last argument
  873.  * \return True if success
  874.  * ------------------------------------------------------------------------ */
  875.  
  876. static Boolean DecodeBitArg(LongWord *pResult, int Start, int Stop)
  877. {
  878.   *pResult = 0;
  879.  
  880.   /* Just one argument -> parse as bit argument */
  881.  
  882.   if (Start == Stop)
  883.   {
  884.     tEvalResult EvalResult;
  885.  
  886.     *pResult = EvalStrIntExpressionWithResult(&ArgStr[Start], (pCurrCPUProps->Core == eCoreSTM8) ? UInt19 : UInt11, &EvalResult);
  887.     if (EvalResult.OK)
  888.       ChkSpace(SegBData, EvalResult.AddrSpaceMask);
  889.     return EvalResult.OK;
  890.   }
  891.  
  892.   /* register & bit position are given as separate arguments */
  893.  
  894.   else if (Stop == Start + 1)
  895.     return DecodeBitArg2(pResult, &ArgStr[Start], &ArgStr[Stop]);
  896.  
  897.   /* other # of arguments not allowed */
  898.  
  899.   else
  900.   {
  901.     WrError(ErrNum_WrongArgCnt);
  902.     return False;
  903.   }
  904. }
  905.  
  906. /*!------------------------------------------------------------------------
  907.  * \fn     DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos)
  908.  * \brief  transform compact representation of bit (field) symbol into components
  909.  * \param  BitSymbol compact storage
  910.  * \param  pAddress (I/O) register address
  911.  * \param  pBitPos (start) bit position
  912.  * \return constant True
  913.  * ------------------------------------------------------------------------ */
  914.  
  915. static Boolean DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos)
  916. {
  917.   *pAddress = (BitSymbol >> 3) & 0xffff;
  918.   *pBitPos = BitSymbol & 7;
  919.   return True;
  920. }
  921.  
  922. /*!------------------------------------------------------------------------
  923.  * \fn     DissectBit_ST7(char *pDest, size_t DestSize, LargeWord Inp)
  924.  * \brief  dissect compact storage of bit (field) into readable form for listing
  925.  * \param  pDest destination for ASCII representation
  926.  * \param  DestSize destination buffer size
  927.  * \param  Inp compact storage
  928.  * ------------------------------------------------------------------------ */
  929.  
  930. static void DissectBit_ST7(char *pDest, size_t DestSize, LargeWord Inp)
  931. {
  932.   Byte BitPos;
  933.   Word Address;
  934.  
  935.   DissectBitSymbol(Inp, &Address, &BitPos);
  936.  
  937.   as_snprintf(pDest, DestSize, "$%x.%u", (unsigned)Address, (unsigned)BitPos);
  938. }
  939.  
  940. /*!------------------------------------------------------------------------
  941.  * \fn     ExpandST7Bit(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
  942.  * \brief  expands bit definition when a structure is instantiated
  943.  * \param  pVarName desired symbol name
  944.  * \param  pStructElem element definition
  945.  * \param  Base base address of instantiated structure
  946.  * ------------------------------------------------------------------------ */
  947.  
  948. static void ExpandST7Bit(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
  949. {
  950.   LongWord Address = Base + pStructElem->Offset;
  951.  
  952.   if (pInnermostNamedStruct)
  953.   {
  954.     PStructElem pElem = CloneStructElem(pVarName, pStructElem);
  955.  
  956.     if (!pElem)
  957.       return;
  958.     pElem->Offset = Address;
  959.     AddStructElem(pInnermostNamedStruct->StructRec, pElem);
  960.   }
  961.   else
  962.   {
  963.     if (!ChkRange(Address, 0, (pCurrCPUProps->Core == eCoreSTM8) ? 0xffff : 0xff)
  964.      || !ChkRange(pStructElem->BitPos, 0, 7))
  965.       return;
  966.  
  967.     PushLocHandle(-1);
  968.     EnterIntSymbol(pVarName, AssembleBitSymbol(pStructElem->BitPos, Address), SegBData, False);
  969.     PopLocHandle();
  970.     /* TODO: MakeUseList? */
  971.   }
  972. }
  973.  
  974. /*!------------------------------------------------------------------------
  975.  * \fn     DecodeBitAdrWithIndir(int Start, int Stop, Byte *pBitPos, tAdrVals *pAdrVals)
  976.  * \brief  decode bit expression, regarding indirect mode on ST7
  977.  * \param  Start 1st argument of bit expression
  978.  * \param  Stop 2nd argument of bit expression
  979.  * \param  pAdrVals result to fill
  980.  * \return True if parsing OK
  981.  * ------------------------------------------------------------------------ */
  982.  
  983. static Boolean DecodeBitAdrWithIndir(int Start, int Stop, Byte *pBitPos, tAdrVals *pAdrVals)
  984. {
  985.   Boolean OK;
  986.  
  987.   if (Start == Stop)
  988.   {
  989.     LongWord BitSym;
  990.     Word Address;
  991.  
  992.     if (!DecodeBitArg(&BitSym, Start, Stop))
  993.       return False;
  994.     DissectBitSymbol(BitSym, &Address, pBitPos);
  995.     if (pCurrCPUProps->Core == eCoreSTM8)
  996.     {
  997.       FillAdrVals(pAdrVals, Address, eSymbolSize16Bit);
  998.       pAdrVals->Mode = eModAbs16;
  999.     }
  1000.     else
  1001.     {
  1002.       FillAdrVals(pAdrVals, Address, eSymbolSize8Bit);
  1003.       pAdrVals->Mode = eModAbs8;
  1004.     }
  1005.     PrefixCnt = 0;
  1006.     return True;
  1007.   }
  1008.   else if (Start + 1 == Stop)
  1009.   {
  1010.     *pBitPos = EvalBitPosition(&ArgStr[Stop], &OK);
  1011.     if (!OK)
  1012.       return False;
  1013.     return DecodeAdr(&ArgStr[Start], (pCurrCPUProps->Core == eCoreSTM8) ? MModAbs16 : (MModAbs8 | MModIAbs8), False, pAdrVals);
  1014.   }
  1015.   else
  1016.     return False;
  1017. }
  1018.  
  1019. /*!------------------------------------------------------------------------
  1020.  * \fn     CompleteCode(const tAdrVals *pAdrVals)
  1021.  * \brief  assemble instruction from prefixes, opcode and address values
  1022.  * \param  pAdrVals values to append to code
  1023.  * ------------------------------------------------------------------------ */
  1024.  
  1025. static void CompleteCode(const tAdrVals *pAdrVals)
  1026. {
  1027.   memcpy(BAsmCode + PrefixCnt + 1, pAdrVals->Vals, pAdrVals->Cnt);
  1028.   CodeLen = PrefixCnt + 1 + pAdrVals->Cnt;
  1029. }
  1030.  
  1031. /*!------------------------------------------------------------------------
  1032.  * \fn     WriteMOV(tAdrVals *pDestAdrVals, tAdrVals *pSrcAdrVals)
  1033.  * \brief  core of writing code of MOV instruction
  1034.  * \param  pDestAdrVals parsed destination operand
  1035.  * \param  pSrcAdrVals parsed source operand
  1036.  * ------------------------------------------------------------------------ */
  1037.  
  1038. static void WriteMOV(tAdrVals *pDestAdrVals, tAdrVals *pSrcAdrVals)
  1039. {
  1040.   if ((pDestAdrVals->Mode == eModAbs16)
  1041.    || (pSrcAdrVals->Mode == eModAbs16)
  1042.    || (pSrcAdrVals->Mode == eModImm))
  1043.   {
  1044.     ExtendAdrVals(pSrcAdrVals);
  1045.     ExtendAdrVals(pDestAdrVals);
  1046.   }
  1047.   switch (pSrcAdrVals->Mode)
  1048.   {
  1049.     case eModImm:
  1050.       BAsmCode[0] = 0x35;
  1051.       break;
  1052.     case eModAbs8:
  1053.       BAsmCode[0] = 0x45;
  1054.       break;
  1055.     case eModAbs16:
  1056.       BAsmCode[0] = 0x55;
  1057.       break;
  1058.     default:
  1059.       break;
  1060.   }
  1061.   memcpy(&BAsmCode[1], pSrcAdrVals->Vals, pSrcAdrVals->Cnt);
  1062.   memcpy(&BAsmCode[1 + pSrcAdrVals->Cnt], pDestAdrVals->Vals, pDestAdrVals->Cnt);
  1063.   CodeLen = 1 + pSrcAdrVals->Cnt + pDestAdrVals->Cnt;
  1064. }
  1065.  
  1066. /*--------------------------------------------------------------------------*/
  1067. /* Code Generators */
  1068.  
  1069. /*!------------------------------------------------------------------------
  1070.  * \fn     DecodeFixed(Word Code)
  1071.  * \brief  decode instructions without argument
  1072.  * \param  per-instruction context
  1073.  * ------------------------------------------------------------------------ */
  1074.  
  1075. static void DecodeFixed(Word Code)
  1076. {
  1077.   if (!ChkArgCnt(0, 0));
  1078.   else if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  1079.   else if (Hi(Code) && (pCurrCPUProps->Core != eCoreSTM8)) WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  1080.   else
  1081.   {
  1082.     if (Hi(Code) >= 2)
  1083.       AddPrefix(Hi(Code));
  1084.     BAsmCode[PrefixCnt] = Lo(Code);
  1085.     CodeLen = PrefixCnt + 1;
  1086.   }
  1087. }
  1088.  
  1089. /*!------------------------------------------------------------------------
  1090.  * \fn     DecodeLD(Word Code)
  1091.  * \brief  decode LD instruction
  1092.  * ------------------------------------------------------------------------ */
  1093.  
  1094. static void DecodeLD(Word Code)
  1095. {
  1096.   LongWord Mask;
  1097.   tAdrVals DestAdrVals, SrcAdrVals;
  1098.  
  1099.   UNUSED(Code);
  1100.  
  1101.   if (!ChkArgCnt(2, 2));
  1102.   else if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  1103.   else
  1104.   {
  1105.     /* NOTE: Set eSymbolSizeUnknown so we get X/Y/S also in STM8 mode.
  1106.              LD will work like LDW in thi case. */
  1107.  
  1108.     Mask = ConstructMask(MModA | MModX | MModY | MModS |  MModXL | MModYL | MModXH | MModYH
  1109.                        | MModImm | MModAbs8 | MModAbs16
  1110.                        | MModIX | MModIX8 | MModIX16 | MModIY | MModIY8 | MModIY16 | MModISP8
  1111.                        | MModIAbs8 | MModIAbs16 | MModI16Abs16
  1112.                        | MModIXAbs8 | MModIXAbs16 | MModI16XAbs16 | MModIYAbs8 | MModIYAbs16, eSymbolSizeUnknown);
  1113.     if (DecodeAdr(&ArgStr[1], Mask, False, &DestAdrVals))
  1114.     switch (DestAdrVals.Mode)
  1115.     {
  1116.       case eModA:
  1117.         Mask = ConstructMask(MModImm | MModX | MModY | MModS | MModXL | MModYL | MModXH | MModYH | MModAbs8 | MModAbs16
  1118.              | MModIX | MModIX8 | MModIX16 | MModIY | MModIY8 | MModIY16 | MModISP8
  1119.              | MModIAbs8 | MModIAbs16 | MModI16Abs16
  1120.              | MModIXAbs8 | MModIXAbs16 | MModI16XAbs16 | MModIYAbs8 | MModIYAbs16, eSymbolSize8Bit);
  1121.         if (DecodeAdr(&ArgStr[2], Mask, False, &SrcAdrVals))
  1122.         switch (SrcAdrVals.Mode)
  1123.         {
  1124.           case eModX: case eModXL:
  1125.           case eModY: case eModYL:
  1126.             BAsmCode[PrefixCnt] = 0x9f;
  1127.             CodeLen = PrefixCnt + 1;
  1128.             break;
  1129.           case eModXH: case eModYH:
  1130.             BAsmCode[PrefixCnt] = 0x9e;
  1131.             CodeLen = PrefixCnt + 1;
  1132.             break;
  1133.           case eModS:
  1134.             BAsmCode[PrefixCnt] = 0x9e;
  1135.             CodeLen = PrefixCnt + 1;
  1136.             break;
  1137.           case eModISP8: /* irregular, cannot use default case */
  1138.             BAsmCode[PrefixCnt] = 0x7b;
  1139.             CompleteCode(&SrcAdrVals);
  1140.             break;
  1141.           default:
  1142.             BAsmCode[PrefixCnt] = 0x06 + (SrcAdrVals.Part << 4);
  1143.             CompleteCode(&SrcAdrVals);
  1144.         }
  1145.         break;
  1146.       case eModX:
  1147.         if (pCurrCPUProps->Core == eCoreSTM8)
  1148.           OpSize = eSymbolSize16Bit;
  1149.         Mask = ConstructMask(MModA | MModY | MModS | MModImm
  1150.                            | MModAbs8 | MModAbs16
  1151.                            | MModIX | MModIX8 | MModIX16 | MModISP8
  1152.                            | MModIAbs8 | MModIAbs16 | MModI16Abs16
  1153.                            | MModIXAbs8 | MModIXAbs16 | MModI16XAbs16, OpSize);
  1154.         if (DecodeAdr(&ArgStr[2], Mask, False, &SrcAdrVals))
  1155.         switch (SrcAdrVals.Mode)
  1156.         {
  1157.           case eModA:
  1158.             BAsmCode[PrefixCnt] = 0x97;
  1159.             CodeLen = PrefixCnt + 1;
  1160.             break;
  1161.           case eModY:
  1162.             BAsmCode[0] = 0x93;
  1163.             CodeLen = 1;
  1164.             break;
  1165.           case eModS:
  1166.             BAsmCode[PrefixCnt] = 0x96;
  1167.             CodeLen = PrefixCnt + 1;
  1168.             break;
  1169.           default:
  1170.             BAsmCode[PrefixCnt] = 0x0e + (SrcAdrVals.Part << 4); /* ANSI :-O */
  1171.             CompleteCode(&SrcAdrVals);
  1172.         }
  1173.         break;
  1174.       case eModXL:
  1175.       case eModYL:
  1176.         if (DecodeAdr(&ArgStr[2], MModA, False, &SrcAdrVals))
  1177.         {
  1178.           BAsmCode[PrefixCnt] = 0x97;
  1179.           CodeLen = PrefixCnt + 1;
  1180.         }
  1181.         break;
  1182.       case eModXH:
  1183.       case eModYH:
  1184.         if (DecodeAdr(&ArgStr[2], MModA, False, &SrcAdrVals))
  1185.         {
  1186.           BAsmCode[PrefixCnt] = 0x95;
  1187.           CodeLen = PrefixCnt + 1;
  1188.         }
  1189.         break;
  1190.       case eModY:
  1191.         PrefixCnt = 0;
  1192.         if (pCurrCPUProps->Core == eCoreSTM8)
  1193.           OpSize = eSymbolSize16Bit;
  1194.         Mask = ConstructMask(MModA | MModX | MModS | MModImm
  1195.                            | MModAbs8 | MModAbs16
  1196.                            | MModIY | MModIY8 | MModIY16 | MModISP8
  1197.                            | MModIAbs8 | MModIAbs16 | MModIYAbs8 | MModIYAbs16, OpSize);
  1198.         if (DecodeAdr(&ArgStr[2], Mask, False, &SrcAdrVals))
  1199.         switch (SrcAdrVals.Mode)
  1200.         {
  1201.           case eModA:
  1202.             AddPrefix(0x90);
  1203.             BAsmCode[PrefixCnt] = 0x97;
  1204.             CodeLen = PrefixCnt + 1;
  1205.             break;
  1206.           case eModX:
  1207.             AddPrefix(0x90);
  1208.             BAsmCode[PrefixCnt] = 0x93;
  1209.             CodeLen = PrefixCnt + 1;
  1210.             break;
  1211.           case eModS:
  1212.             AddPrefix(0x90);
  1213.             BAsmCode[PrefixCnt] = 0x96;
  1214.             CodeLen = PrefixCnt + 1;
  1215.             break;
  1216.           case eModISP8:
  1217.             BAsmCode[PrefixCnt] = 0x16;
  1218.             goto common;
  1219.           default:
  1220.             if (PrefixCnt == 0) AddPrefix(0x90);
  1221.             if (BAsmCode[0] == 0x92) BAsmCode[0]--;
  1222.             BAsmCode[PrefixCnt] = 0x0e + (SrcAdrVals.Part << 4); /* ANSI :-O */
  1223.           common:
  1224.             CompleteCode(&SrcAdrVals);
  1225.         }
  1226.         break;
  1227.       case eModS:
  1228.         if (DecodeAdr(&ArgStr[2], MModA | MModX | MModY, False, &SrcAdrVals))
  1229.         switch (SrcAdrVals.Mode)
  1230.         {
  1231.           case eModA:
  1232.             BAsmCode[PrefixCnt] = 0x95;
  1233.             CodeLen = PrefixCnt + 1;
  1234.             break;
  1235.           case eModX:
  1236.           case eModY:
  1237.             BAsmCode[PrefixCnt] = 0x94;
  1238.             CodeLen = PrefixCnt + 1;
  1239.             break;
  1240.           default:
  1241.             break;
  1242.         }
  1243.         break;
  1244.       default:
  1245.       {
  1246.         Boolean Result;
  1247.         unsigned SavePrefixCnt = PrefixCnt;
  1248.  
  1249.         /* set unknown size to allow X&Y also on STM8 if LD is written instead of LDW */
  1250.         Mask = ConstructMask(MModA | MModX | MModY, eSymbolSizeUnknown);
  1251.         /* aliases for MOV */
  1252.         if (pCurrCPUProps->Core == eCoreSTM8)
  1253.           switch (DestAdrVals.Mode)
  1254.           {
  1255.             case eModAbs16:
  1256.               Mask |= MModAbs16 | MModImm;
  1257.               break;
  1258.             case eModAbs8:
  1259.               Mask |= MModAbs8 | MModAbs16 | MModImm;
  1260.               break;
  1261.             default:
  1262.               break;
  1263.           }
  1264.         Result = DecodeAdr(&ArgStr[2], Mask, False, &SrcAdrVals);
  1265.         PrefixCnt = SavePrefixCnt;
  1266.         if (Result)
  1267.         switch (SrcAdrVals.Mode)
  1268.         {
  1269.           case eModA:
  1270.             Mask = ConstructMask(MModAbs8 | MModAbs16
  1271.                                | MModIX | MModIX8 | MModIX16 | MModIY | MModIY8 | MModIY16 | MModISP8
  1272.                                | MModIAbs8 | MModIAbs16 | MModI16Abs16 | MModIXAbs8 | MModIXAbs16 | MModI16XAbs16 | MModIYAbs8 | MModIYAbs16, eSymbolSize8Bit);
  1273.             if (ChkAdrValsMode(&DestAdrVals, Mask, ErrNum_InvAddrMode, &ArgStr[1]))
  1274.             {
  1275.               BAsmCode[PrefixCnt] = (DestAdrVals.Mode == eModISP8) ? 0x6b : (0x07 + (DestAdrVals.Part << 4));
  1276.               CompleteCode(&DestAdrVals);
  1277.             }
  1278.             break;
  1279.           case eModX:
  1280.             Mask = MModAbs8 | MModAbs16 | MModIAbs16;
  1281.             if (pCurrCPUProps->Core == eCoreST7)
  1282.               Mask |= MModIX | MModIX8 | MModIX16 | MModIAbs8 | MModIXAbs8 | MModIXAbs16;
  1283.             if (pCurrCPUProps->Core == eCoreSTM8)
  1284.               Mask |= MModIY | MModIY8 | MModIY16 | MModIYAbs16 | MModISP8 | MModI16Abs16;
  1285.             if (ChkAdrValsMode(&DestAdrVals, Mask, ErrNum_InvAddrMode, &ArgStr[1]))
  1286.             {
  1287.               BAsmCode[PrefixCnt] = 0x0f + (DestAdrVals.Part << 4);
  1288.               CompleteCode(&DestAdrVals);
  1289.             }
  1290.             break;
  1291.           case eModY:
  1292.             Mask = MModAbs8 | MModAbs16 | MModIAbs16;
  1293.             if (pCurrCPUProps->Core == eCoreST7)
  1294.               Mask |= MModIY | MModIY8 | MModIY16 | MModIAbs8 | MModIYAbs8 | MModIYAbs16;
  1295.             if (pCurrCPUProps->Core == eCoreSTM8)
  1296.               Mask |= MModIX | MModIX8 | MModIX16 | MModIXAbs16 | MModI16XAbs16 | MModISP8;
  1297.             if (ChkAdrValsMode(&DestAdrVals, Mask, ErrNum_InvAddrMode, &ArgStr[1]))
  1298.             switch (DestAdrVals.Mode)
  1299.             {
  1300.               case eModISP8:
  1301.                 PrefixCnt = 0;
  1302.                 BAsmCode[PrefixCnt] = 0x07 + (DestAdrVals.Part << 4);
  1303.                 goto common_ysrc2;
  1304.               case eModIX:
  1305.               case eModIX8:
  1306.               case eModIX16:
  1307.                 PrefixCnt = 0;
  1308.                 goto common_ysrc;
  1309.               case eModIXAbs16:
  1310.                 goto common_ysrc;
  1311.               default:
  1312.                 if (PrefixCnt == 0) AddPrefix(0x90);
  1313.                 if (BAsmCode[0] == 0x92) BAsmCode[0]--;
  1314.               common_ysrc:
  1315.                 BAsmCode[PrefixCnt] = 0x0f + (DestAdrVals.Part << 4);
  1316.               common_ysrc2:
  1317.                 CompleteCode(&DestAdrVals);
  1318.             }
  1319.             break;
  1320.           case eModImm: /* MOV aliases: only possible if Dest = Abs8/16 */
  1321.           case eModAbs8:
  1322.           case eModAbs16:
  1323.             WriteMOV(&DestAdrVals, &SrcAdrVals);
  1324.             break;
  1325.           default:
  1326.             break;
  1327.         }
  1328.       }
  1329.     }
  1330.   }
  1331. }
  1332.  
  1333. /*!------------------------------------------------------------------------
  1334.  * \fn     DecodeLDW(Word Code)
  1335.  * \brief  decode LDW instruction
  1336.  * ------------------------------------------------------------------------ */
  1337.  
  1338. static void DecodeLDW(Word Code)
  1339. {
  1340.   tAdrVals DestAdrVals, SrcAdrVals;
  1341.   LongWord Mask;
  1342.  
  1343.   UNUSED(Code);
  1344.   if (!ChkArgCnt(2, 2));
  1345.   else if (pCurrCPUProps->Core != eCoreSTM8) WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  1346.   else if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  1347.   else
  1348.   {
  1349.     Mask = ConstructMask(MModX | MModY | MModS
  1350.                        | MModAbs8 | MModAbs16
  1351.                        | MModIX | MModIX8 | MModIX16 | MModIY | MModIY8 | MModIY16 | MModISP8
  1352.                        | MModIAbs16 | MModI16Abs16 | MModIXAbs16 | MModI16XAbs16 | MModIYAbs16, OpSize = eSymbolSize16Bit);
  1353.     if (DecodeAdr(&ArgStr[1], Mask, False, &DestAdrVals))
  1354.     switch (DestAdrVals.Mode)
  1355.     {
  1356.       case eModX:
  1357.         Mask = ConstructMask(MModY | MModS | MModImm
  1358.                            | MModAbs8 | MModAbs16
  1359.                            | MModIX | MModIX8 | MModIX16 | MModISP8
  1360.                            | MModIAbs16 | MModI16Abs16 | MModIXAbs16 | MModI16XAbs16, eSymbolSize16Bit);
  1361.         if (DecodeAdr(&ArgStr[2], Mask, False, &SrcAdrVals))
  1362.         switch (SrcAdrVals.Mode)
  1363.         {
  1364.           case eModY:
  1365.             PrefixCnt = 0;
  1366.             BAsmCode[PrefixCnt] = 0x93;
  1367.             CodeLen = PrefixCnt + 1;
  1368.             break;
  1369.           case eModS:
  1370.             BAsmCode[PrefixCnt] = 0x96;
  1371.             CodeLen = PrefixCnt + 1;
  1372.             break;
  1373.           default:
  1374.             BAsmCode[PrefixCnt] = 0x0e | (SrcAdrVals.Part << 4);
  1375.             CompleteCode(&SrcAdrVals);
  1376.             break;
  1377.         }
  1378.         break;
  1379.       case eModY:
  1380.         PrefixCnt = 0;
  1381.         Mask = ConstructMask(MModX | MModS | MModImm
  1382.                            | MModAbs8 | MModAbs16
  1383.                            | MModIY | MModIY8 | MModIY16 | MModISP8
  1384.                            | MModIAbs16 | MModIYAbs16, eSymbolSize16Bit);
  1385.         DecodeAdr(&ArgStr[2], Mask, False, &SrcAdrVals);
  1386.         if (!PrefixCnt)
  1387.           AddPrefix(0x90);
  1388.         if (SrcAdrVals.Mode != eModNone)
  1389.         switch (SrcAdrVals.Mode)
  1390.         {
  1391.           case eModX:
  1392.             BAsmCode[PrefixCnt] = 0x93;
  1393.             CodeLen = PrefixCnt + 1;
  1394.             break;
  1395.           case eModS:
  1396.             BAsmCode[PrefixCnt] = 0x96;
  1397.             CodeLen = PrefixCnt + 1;
  1398.             break;
  1399.           case eModISP8:
  1400.             PrefixCnt = 0;
  1401.             BAsmCode[PrefixCnt] = 0x16;
  1402.             goto common_x;
  1403.           case eModIAbs16:
  1404.             PrefixCnt = 0;
  1405.             AddPrefix(0x91);
  1406.             /* fall-through */
  1407.           default:
  1408.             BAsmCode[PrefixCnt] = 0x0e | (SrcAdrVals.Part << 4);
  1409.           common_x:
  1410.             CompleteCode(&SrcAdrVals);
  1411.             break;
  1412.         }
  1413.         break;
  1414.       case eModS:
  1415.         Mask = ConstructMask(MModX | MModY, eSymbolSize16Bit);
  1416.         if (DecodeAdr(&ArgStr[2], Mask, False, &SrcAdrVals))
  1417.         {
  1418.           BAsmCode[PrefixCnt] = 0x94;
  1419.           CodeLen = PrefixCnt + 1;
  1420.         }
  1421.         break;
  1422.       default:
  1423.       {
  1424.         Mask = ConstructMask(MModX | MModY, eSymbolSize16Bit);
  1425.         if (DecodeReg(&ArgStr[2], &SrcAdrVals.Mode, Mask))
  1426.         switch (DestAdrVals.Mode)
  1427.         {
  1428.           case eModIAbs16:
  1429.             if (eModY == SrcAdrVals.Mode)
  1430.             {
  1431.               PrefixCnt = 0;
  1432.               AddPrefix(0x91);
  1433.             }
  1434.             goto common_y2;
  1435.           case eModISP8:
  1436.             BAsmCode[PrefixCnt] = (eModY == SrcAdrVals.Mode) ? 0x17 : 0x1f;
  1437.             goto common_y;
  1438.           case eModAbs8:
  1439.           case eModAbs16:
  1440.             if (eModY == SrcAdrVals.Mode)
  1441.               AddPrefix(0x90);
  1442.             /* fall-through */
  1443.           default:
  1444.           common_y2:
  1445.             BAsmCode[PrefixCnt] = 0x0f | (DestAdrVals.Part << 4);
  1446.           common_y:
  1447.             CompleteCode(&DestAdrVals);
  1448.             break;
  1449.         }
  1450.         break;
  1451.       }
  1452.     }
  1453.   }
  1454. }
  1455.  
  1456. /*!------------------------------------------------------------------------
  1457.  * \fn     DecodeLDF(Word Code)
  1458.  * \brief  decode LDF instruction
  1459.  * ------------------------------------------------------------------------ */
  1460.  
  1461. static void DecodeLDF(Word Code)
  1462. {
  1463.   tAdrVals AdrVals;
  1464.  
  1465.   UNUSED(Code);
  1466.   if (!ChkArgCnt(2, 2));
  1467.   else if (pCurrCPUProps->Core != eCoreSTM8) WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  1468.   else if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  1469.   else if (DecodeAdr(&ArgStr[1], MModA | MModAbs24 | MModIX24 | MModIY24 | MModI16XAbs24 | MModI16YAbs24 | MModI16Abs24, False, &AdrVals))
  1470.   switch (AdrVals.Mode)
  1471.   {
  1472.     case eModA:
  1473.       if (DecodeAdr(&ArgStr[2], MModAbs24 | MModIX24 | MModIY24 | MModI16XAbs24 | MModI16YAbs24 | MModI16Abs24, False, &AdrVals))
  1474.       {
  1475.         switch (AdrVals.Mode)
  1476.         {
  1477.           case eModAbs24:
  1478.           case eModI16Abs24:
  1479.             BAsmCode[PrefixCnt] = 0x0c | (AdrVals.Part << 4);
  1480.             break;
  1481.           case eModIX24:
  1482.           case eModIY24:
  1483.           case eModI16XAbs24:
  1484.           case eModI16YAbs24:
  1485.             BAsmCode[PrefixCnt] = 0x0f | (AdrVals.Part << 4);
  1486.             break;
  1487.           default:
  1488.             break;
  1489.         }
  1490.         CompleteCode(&AdrVals);
  1491.       }
  1492.       break;
  1493.     default:
  1494.     {
  1495.       tAdrMode RegMode;
  1496.  
  1497.       if (DecodeReg(&ArgStr[2], &RegMode, MModA))
  1498.       {
  1499.         switch (AdrVals.Mode)
  1500.         {
  1501.           case eModAbs24:
  1502.           case eModI16Abs24:
  1503.             BAsmCode[PrefixCnt] = 0x0d | (AdrVals.Part << 4);
  1504.             break;
  1505.           case eModIX24:
  1506.           case eModIY24:
  1507.           case eModI16XAbs24:
  1508.           case eModI16YAbs24:
  1509.             BAsmCode[PrefixCnt] = 0x07 | (AdrVals.Part << 4);
  1510.             break;
  1511.           default:
  1512.             break;
  1513.         }
  1514.         CompleteCode(&AdrVals);
  1515.       }
  1516.       break;
  1517.     }
  1518.   }
  1519. }
  1520.  
  1521. /*!------------------------------------------------------------------------
  1522.  * \fn     DecodeMOV(Word Code)
  1523.  * \brief  decode MOV instruction
  1524.  * ------------------------------------------------------------------------ */
  1525.  
  1526. static void DecodeMOV(Word Code)
  1527. {
  1528.   tAdrVals SrcAdrVals, DestAdrVals;
  1529.  
  1530.   UNUSED(Code);
  1531.   if (!ChkArgCnt(2, 2));
  1532.   else if (pCurrCPUProps->Core != eCoreSTM8) WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  1533.   else if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  1534.   else if (DecodeAdr(&ArgStr[2], MModImm | MModAbs8 | MModAbs16, False, &SrcAdrVals))
  1535.   {
  1536.     if (DecodeAdr(&ArgStr[1], ((SrcAdrVals.Mode == eModAbs8) ? MModAbs8 : 0) | MModAbs16, False, &DestAdrVals))
  1537.       WriteMOV(&DestAdrVals, &SrcAdrVals);
  1538.   }
  1539. }
  1540.  
  1541. /*!------------------------------------------------------------------------
  1542.  * \fn     DecodePUSH_POP(Word Code)
  1543.  * \brief  decode PUSH(W)/POP(W) instructions
  1544.  * \param  Code instruction context
  1545.  * ------------------------------------------------------------------------ */
  1546.  
  1547. static void DecodePUSH_POP(Word Code)
  1548. {
  1549.   if (!ChkArgCnt(1, 1));
  1550.   else if (Hi(Code) && (pCurrCPUProps->Core != eCoreSTM8)) WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  1551.   else if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  1552.   else
  1553.   {
  1554.     LongWord Mask;
  1555.     tAdrVals AdrVals;
  1556.  
  1557.     Mask = MModX | MModY | (Hi(Code) ? 0 : MModA);
  1558.     if (pCurrCPUProps->Core == eCoreSTM8)
  1559.     {
  1560.       Mask |= MModAbs16;
  1561.       if (Lo(Code))
  1562.         Mask |= MModImm;
  1563.     }
  1564.     if (!as_strcasecmp(ArgStr[1].str.p_str, "CC"))
  1565.     {
  1566.       BAsmCode[PrefixCnt] = 0x86 + Lo(Code);
  1567.       CodeLen = PrefixCnt + 1;
  1568.     }
  1569.     else if (DecodeAdr(&ArgStr[1], Mask, False, &AdrVals))
  1570.     {
  1571.       switch (AdrVals.Mode)
  1572.       {
  1573.         case eModA:
  1574.           BAsmCode[PrefixCnt] = 0x84 + Lo(Code);
  1575.           break;
  1576.         case eModX:
  1577.         case eModY:
  1578.           BAsmCode[PrefixCnt] = 0x85 + Lo(Code);
  1579.           break;
  1580.         case eModAbs16:
  1581.           BAsmCode[PrefixCnt] = Lo(Code) ? 0x4b : 0x32;
  1582.           break;
  1583.         case eModImm:
  1584.           BAsmCode[PrefixCnt] = 0x4b;
  1585.           break;
  1586.         default:
  1587.           break;
  1588.       }
  1589.       CompleteCode(&AdrVals);
  1590.     }
  1591.   }
  1592. }
  1593.  
  1594. /*!------------------------------------------------------------------------
  1595.  * \fn     DecodeCP(Word Code)
  1596.  * \brief  decode CP(W) instructions
  1597.  * \param  IsCPW 1 if CPW
  1598.  * ------------------------------------------------------------------------ */
  1599.  
  1600. static void DecodeCP(Word IsCPW)
  1601. {
  1602.   LongWord Mask;
  1603.  
  1604.   if (!ChkArgCnt(2, 2));
  1605.   else if (IsCPW && (pCurrCPUProps->Core != eCoreSTM8)) WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  1606.   else if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  1607.   else
  1608.   {
  1609.     tAdrVals SrcAdrVals;
  1610.     tAdrMode DestMode;
  1611.  
  1612.     if (DecodeReg(&ArgStr[1], &DestMode, (IsCPW ? 0 : MModA) | MModX | MModY))
  1613.     switch (DestMode)
  1614.     {
  1615.       case eModA:
  1616.         Mask = ConstructMask(MModImm | MModAbs8 | MModAbs16
  1617.                            | MModIX | MModIX8 | MModIX16 | MModIY | MModIY8 | MModIY16 | MModISP8
  1618.                            | MModIAbs8 | MModIAbs16 | MModI16Abs16
  1619.                            | MModIXAbs8 | MModIXAbs16 | MModI16XAbs16 | MModIYAbs8 | MModIYAbs16, eSymbolSize8Bit);
  1620.         if (DecodeAdr(&ArgStr[2], Mask, False, &SrcAdrVals))
  1621.         {
  1622.           BAsmCode[PrefixCnt] = 0x01 + (SrcAdrVals.Part << 4);
  1623.           CompleteCode(&SrcAdrVals);
  1624.         }
  1625.         break;
  1626.       case eModX:
  1627.         Mask = MModImm | MModAbs8 | MModAbs16 | MModIAbs16;
  1628.         if (pCurrCPUProps->Core == eCoreST7)
  1629.           Mask |= MModIAbs8 | MModIXAbs8 | MModIX | MModIX8 | MModIX16 | MModIXAbs16;
  1630.         if (pCurrCPUProps->Core == eCoreSTM8)
  1631.         {
  1632.           Mask |= MModIY | MModIY8 | MModIY16 | MModISP8 | MModI16Abs16 | MModIYAbs16;
  1633.           OpSize = eSymbolSize16Bit;
  1634.         }
  1635.         if (DecodeAdr(&ArgStr[2], Mask, False, &SrcAdrVals))
  1636.         {
  1637.           BAsmCode[PrefixCnt] = 0x03 + (SrcAdrVals.Part << 4);
  1638.           CompleteCode(&SrcAdrVals);
  1639.         }
  1640.         break;
  1641.       case eModY:
  1642.         PrefixCnt = 0;
  1643.         Mask = MModImm | MModAbs8 | MModAbs16 | MModIAbs16;
  1644.         if (pCurrCPUProps->Core == eCoreST7)
  1645.           Mask |= MModIAbs8 | MModIYAbs8 | MModIY | MModIY8 | MModIY16 | MModIYAbs16;
  1646.         if (pCurrCPUProps->Core == eCoreSTM8)
  1647.         {
  1648.           Mask |= MModIX | MModIX8 | MModIX16 | MModIXAbs16 | MModI16XAbs16;
  1649.           OpSize = eSymbolSize16Bit;
  1650.         }
  1651.         if (DecodeAdr(&ArgStr[2], Mask, False, &SrcAdrVals))
  1652.         switch (SrcAdrVals.Mode)
  1653.         {
  1654.           case eModIXAbs16:
  1655.           case eModIX:
  1656.           case eModIX8:
  1657.           case eModIX16:
  1658.             goto common;
  1659.           default:
  1660.             if (PrefixCnt == 0) AddPrefix(0x90);
  1661.             if (BAsmCode[0] == 0x92) BAsmCode[0]--;
  1662.           common:
  1663.             BAsmCode[PrefixCnt] = 0x03 + (SrcAdrVals.Part << 4);
  1664.             CompleteCode(&SrcAdrVals);
  1665.         }
  1666.         break;
  1667.       default:
  1668.         break;
  1669.     }
  1670.   }
  1671. }
  1672.  
  1673. /*!------------------------------------------------------------------------
  1674.  * \fn     DecodeAri16(Word Code)
  1675.  * \brief  decode 16-bit arithmetic/logic instructions with two operands
  1676.  * \param  Code instruction code
  1677.  * ------------------------------------------------------------------------ */
  1678.  
  1679. static void DecodeAri16(Word Code)
  1680. {
  1681.   tAdrVals SrcAdrVals, DestAdrVals;
  1682.  
  1683.   if (!ChkArgCnt(2, 2));
  1684.   else if (pCurrCPUProps->Core != eCoreSTM8) WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  1685.   else if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  1686.   else if (DecodeAdr(&ArgStr[1], MModX | MModY | MModS, False, &DestAdrVals))
  1687.   switch (DestAdrVals.Mode)
  1688.   {
  1689.     case eModX:
  1690.     case eModY:
  1691.       OpSize = eSymbolSize16Bit;
  1692.       if (DecodeAdr(&ArgStr[2], MModImm | MModAbs16 | MModISP8, False, &SrcAdrVals))
  1693.       switch (SrcAdrVals.Mode)
  1694.       {
  1695.         case eModImm:
  1696.           if (PrefixCnt)
  1697.           {
  1698.             BAsmCode[PrefixCnt - 1] = 0x72;
  1699.             BAsmCode[PrefixCnt] = 0xa0 | Hi(Code);
  1700.           }
  1701.           else
  1702.             BAsmCode[PrefixCnt] = 0x1d - !!Lo(Code);
  1703.           goto common;
  1704.         case eModAbs16:
  1705.           if (PrefixCnt)
  1706.           {
  1707.             BAsmCode[PrefixCnt - 1] = 0x72;
  1708.             BAsmCode[PrefixCnt] = 0xb0 | Hi(Code);
  1709.           }
  1710.           else
  1711.           {
  1712.             BAsmCode[PrefixCnt++] = 0x72;
  1713.             BAsmCode[PrefixCnt] = 0xb0 | Lo(Code);
  1714.           }
  1715.           goto common;
  1716.         case eModISP8:
  1717.           if (PrefixCnt)
  1718.           {
  1719.             BAsmCode[PrefixCnt - 1] = 0x72;
  1720.             BAsmCode[PrefixCnt] = 0xf0 | Hi(Code);
  1721.           }
  1722.           else
  1723.           {
  1724.             BAsmCode[PrefixCnt++] = 0x72;
  1725.             BAsmCode[PrefixCnt] = 0xf0 | Lo(Code);
  1726.           }
  1727.           goto common;
  1728.         common:
  1729.           CompleteCode(&SrcAdrVals);
  1730.           break;
  1731.         default:
  1732.           break;
  1733.       }
  1734.       break;
  1735.     case eModS:
  1736.       OpSize = eSymbolSize8Bit;
  1737.       if (DecodeAdr(&ArgStr[2], MModImm, False, &SrcAdrVals))
  1738.       {
  1739.         BAsmCode[0] = 0x52 | Lo(Code);
  1740.         BAsmCode[1] = SrcAdrVals.Vals[0];
  1741.         CodeLen = 2;
  1742.       }
  1743.       break;
  1744.     default:
  1745.       break;
  1746.   }
  1747. }
  1748.  
  1749. /*!------------------------------------------------------------------------
  1750.  * \fn     DecodeAri(Word Code)
  1751.  * \brief  decode 8-bit arithmetic/logic instructions with two operands
  1752.  * \param  Code instruction code
  1753.  * ------------------------------------------------------------------------ */
  1754.  
  1755. static void DecodeAri(Word Code)
  1756. {
  1757.   tAdrVals SrcAdrVals, DestAdrVals;
  1758.   LongWord Mask;
  1759.   Word Code16 = 0;
  1760.  
  1761.   if (!ChkArgCnt(2, 2));
  1762.   else if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  1763.   else
  1764.   {
  1765.     Mask = MModA;
  1766.     if (pCurrCPUProps->Core == eCoreSTM8)
  1767.       switch (Lo(Code))
  1768.       {
  1769.         case 0x00: /* SUB->SUBW */
  1770.           Code16 = 0x0200;
  1771.           Mask |= MModS | MModX | MModY;
  1772.           break;
  1773.         case 0x0b: /* ADD->ADDW */
  1774.           Code16 = 0x090b;
  1775.           Mask |= MModS | MModX | MModY;
  1776.           break;
  1777.       }
  1778.     if (DecodeAdr(&ArgStr[1], Mask, False, &DestAdrVals))
  1779.     switch (DestAdrVals.Mode)
  1780.     {
  1781.       case eModA:
  1782.         Mask = MModAbs8 | MModAbs16 | MModIX | MModIX8 | MModIX16 | MModIY |
  1783.                MModIY8 | MModIY16 | MModIAbs16 | MModIXAbs16 | MModIYAbs16;
  1784.         if (pCurrCPUProps->Core == eCoreST7)
  1785.           Mask |= MModIAbs8 | MModIXAbs8 | MModIYAbs8;
  1786.         if (pCurrCPUProps->Core == eCoreSTM8)
  1787.           Mask |= MModISP8 | MModI16Abs16 | MModI16XAbs16;
  1788.         if (Hi(Code)) Mask |= MModImm;
  1789.         if (DecodeAdr(&ArgStr[2], Mask, False, &SrcAdrVals))
  1790.         {
  1791.           BAsmCode[PrefixCnt] = Lo(Code) + (SrcAdrVals.Part << 4);
  1792.           CompleteCode(&SrcAdrVals);
  1793.         }
  1794.         break;
  1795.       case eModS:
  1796.       case eModX:
  1797.       case eModY:
  1798.         PrefixCnt = 0;
  1799.         DecodeAri16(Code16);
  1800.       default:
  1801.         break;
  1802.     }
  1803.   }
  1804. }
  1805.  
  1806. /*!------------------------------------------------------------------------
  1807.  * \fn     DecodeRMW(Word Code)
  1808.  * \brief  decode 8-bit read/modify/write instructions with one operand
  1809.  * \param  Code instruction code
  1810.  * ------------------------------------------------------------------------ */
  1811.  
  1812. static void DecodeRMW(Word Code)
  1813. {
  1814.   Boolean IsW = Hi(Code);
  1815.  
  1816.   Code = Lo(Code);
  1817.   if (!ChkArgCnt(1, 1));
  1818.   else if (IsW && (pCurrCPUProps->Core != eCoreSTM8)) WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  1819.   else if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  1820.   else
  1821.   {
  1822.     LongWord Mask;
  1823.     tAdrVals AdrVals;
  1824.  
  1825.     Mask = MModX | MModY;
  1826.     if (!IsW)
  1827.     {
  1828.       Mask |= MModA |  MModAbs8
  1829.             | MModIX | MModIX8 | MModIY | MModIY8;
  1830.       if (pCurrCPUProps->Core == eCoreST7)
  1831.         Mask |= MModIAbs8 | MModIXAbs8 | MModIYAbs8;
  1832.       if (pCurrCPUProps->Core == eCoreSTM8)
  1833.         Mask |= MModAbs16 | MModIX16 | MModIY16 | MModISP8
  1834.               | MModIAbs16 | MModI16Abs16 | MModIXAbs16 | MModI16XAbs16 | MModIYAbs16;
  1835.     }
  1836.     if (DecodeAdr(&ArgStr[1], Mask, False, &AdrVals))
  1837.     switch (AdrVals.Mode)
  1838.     {
  1839.       case eModA:
  1840.         BAsmCode[PrefixCnt] = 0x40 + Code;
  1841.         CodeLen = PrefixCnt + 1;
  1842.         break;
  1843.       case eModX:
  1844.       case eModY:
  1845.         BAsmCode[PrefixCnt] = 0x50 + Code;
  1846.         CodeLen = PrefixCnt + 1;
  1847.         break;
  1848.       case eModAbs16:
  1849.         BAsmCode[PrefixCnt++] = 0x72;
  1850.         BAsmCode[PrefixCnt] = 0x50 | Code;
  1851.         goto common;
  1852.       case eModIX16:
  1853.         BAsmCode[PrefixCnt++] = 0x72;
  1854.         BAsmCode[PrefixCnt] = 0x40 | Code;
  1855.         goto common;
  1856.       case eModIY16:
  1857.         BAsmCode[PrefixCnt] = 0x40 | Code;
  1858.         goto common;
  1859.       case eModISP8:
  1860.         BAsmCode[PrefixCnt] = 0x00 | Code;
  1861.         goto common;
  1862.       case eModIAbs16:
  1863.       case eModI16Abs16:
  1864.         BAsmCode[PrefixCnt] = 0x30 | Code;
  1865.         goto common;
  1866.       case eModIXAbs16:
  1867.       case eModI16XAbs16:
  1868.       case eModIYAbs16:
  1869.         BAsmCode[PrefixCnt] = 0x60 | Code;
  1870.         goto common;
  1871.       default:
  1872.         BAsmCode[PrefixCnt] = Code + ((AdrVals.Part - 8) << 4);
  1873.         /* fall-through */
  1874.       common:
  1875.         CompleteCode(&AdrVals);
  1876.     }
  1877.   }
  1878. }
  1879.  
  1880. /*!------------------------------------------------------------------------
  1881.  * \fn     DecodeMUL(Word Code)
  1882.  * \brief  decode MUL instruction
  1883.  * ------------------------------------------------------------------------ */
  1884.  
  1885. static void DecodeMUL(Word Code)
  1886. {
  1887.   UNUSED(Code);
  1888.  
  1889.   if (!ChkArgCnt(2, 2));
  1890.   else if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  1891.   else
  1892.   {
  1893.     tAdrMode SrcMode;
  1894.     tAdrVals DestVals;
  1895.  
  1896.     if (DecodeReg(&ArgStr[2], &SrcMode, MModA)
  1897.      && DecodeAdr(&ArgStr[1], MModX | MModY, False, &DestVals))
  1898.     {
  1899.       BAsmCode[PrefixCnt] = 0x42;
  1900.       CodeLen = PrefixCnt + 1;
  1901.     }
  1902.   }
  1903. }
  1904.  
  1905. /*!------------------------------------------------------------------------
  1906.  * \fn     DecodeDIV(Word Code)
  1907.  * \brief  decode DIV(W) instructions
  1908.  * \param  IsW True if DIVW
  1909.  * ------------------------------------------------------------------------ */
  1910.  
  1911. static void DecodeDIV(Word IsW)
  1912. {
  1913.   tAdrVals DestAdrVals, SrcAdrVals;
  1914.  
  1915.   if (!ChkArgCnt(2, 2));
  1916.   else if (pCurrCPUProps->Core != eCoreSTM8) WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  1917.   else if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  1918.   else if (DecodeAdr(&ArgStr[1], MModX | (IsW ? 0 : MModY), False, &DestAdrVals)
  1919.         && DecodeAdr(&ArgStr[2], MModY | (IsW ? 0 : MModA), False, &SrcAdrVals))
  1920.   {
  1921.     BAsmCode[PrefixCnt] = (SrcAdrVals.Mode == eModA) ? 0x62 : 0x65;
  1922.     CodeLen = PrefixCnt + 1;
  1923.   }
  1924. }
  1925.  
  1926. /*!------------------------------------------------------------------------
  1927.  * \fn     DecodeEXG(Word Code)
  1928.  * \brief  decode EXG(W) instructions
  1929.  * \param  IsW True if EXGW
  1930.  * ------------------------------------------------------------------------ */
  1931.  
  1932. static void DecodeEXG(Word IsW)
  1933. {
  1934.   tAdrVals DestAdrVals, SrcAdrVals;
  1935.  
  1936.   if (!ChkArgCnt(2, 2));
  1937.   else if (pCurrCPUProps->Core != eCoreSTM8) WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  1938.   else if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  1939.   else if (DecodeAdr(&ArgStr[1], (IsW ? 0 : (MModA | MModXL | MModYL | MModAbs16)) | MModX | MModY, False, &DestAdrVals))
  1940.   switch (DestAdrVals.Mode)
  1941.   {
  1942.     case eModA:
  1943.       if (DecodeAdr(&ArgStr[2], MModXL | MModYL | MModAbs16, False, &SrcAdrVals))
  1944.       switch (SrcAdrVals.Mode)
  1945.       {
  1946.         case eModXL:
  1947.           BAsmCode[0] = 0x41;
  1948.           CodeLen = 1;
  1949.           break;
  1950.         case eModYL:
  1951.           BAsmCode[0] = 0x61;
  1952.           CodeLen = 1;
  1953.           break;
  1954.         case eModAbs16:
  1955.           BAsmCode[0] = 0x31;
  1956.           CompleteCode(&SrcAdrVals);
  1957.           break;
  1958.         default:
  1959.           break;
  1960.       }
  1961.       break;
  1962.     case eModXL:
  1963.       if (DecodeAdr(&ArgStr[2], MModA, False, &SrcAdrVals))
  1964.       {
  1965.         BAsmCode[0] = 0x41;
  1966.         CodeLen = 1;
  1967.       }
  1968.       break;
  1969.     case eModYL:
  1970.       if (DecodeAdr(&ArgStr[2], MModA, False, &SrcAdrVals))
  1971.       {
  1972.         BAsmCode[0] = 0x61;
  1973.         CodeLen = 1;
  1974.       }
  1975.       break;
  1976.     case eModAbs16:
  1977.       if (DecodeAdr(&ArgStr[2], MModA, False, &SrcAdrVals))
  1978.       {
  1979.         BAsmCode[0] = 0x31;
  1980.         memcpy(&BAsmCode[1], SrcAdrVals.Vals, SrcAdrVals.Cnt);
  1981.         CodeLen = 3;
  1982.       }
  1983.       break;
  1984.     case eModX:
  1985.       if (DecodeAdr(&ArgStr[2], MModY, False, &SrcAdrVals))
  1986.       {
  1987.         BAsmCode[0] = 0x51;
  1988.         CodeLen = 1;
  1989.       }
  1990.       break;
  1991.     case eModY:
  1992.       if (DecodeAdr(&ArgStr[2], MModX, False, &SrcAdrVals))
  1993.       {
  1994.         BAsmCode[0] = 0x51;
  1995.         CodeLen = 1;
  1996.       }
  1997.       break;
  1998.     default:
  1999.       break;
  2000.   }
  2001. }
  2002.  
  2003. /*!------------------------------------------------------------------------
  2004.  * \fn     DecodeBitOp(Word Code)
  2005.  * \brief  decode bit operation instructions
  2006.  * \param  Code instruction code
  2007.  * ------------------------------------------------------------------------ */
  2008.  
  2009. static void DecodeBitOp(Word Code)
  2010. {
  2011.   Byte BitPos;
  2012.   tAdrVals AdrVals;
  2013.  
  2014.   if (!ChkArgCnt(1, 2));
  2015.   else if ((Hi(Code == 0x90)) && (pCurrCPUProps->Core != eCoreSTM8)) WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  2016.   else if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  2017.   else if (DecodeBitAdrWithIndir(1, ArgCnt, &BitPos, &AdrVals))
  2018.   {
  2019.     if (pCurrCPUProps->Core == eCoreSTM8)
  2020.     {
  2021.       PrefixCnt = 0;
  2022.       AddPrefix(Hi(Code));
  2023.       BAsmCode[PrefixCnt] = 0x10 | (BitPos << 1) | (Code & 1);
  2024.     }
  2025.     else
  2026.       BAsmCode[PrefixCnt] = Lo(Code) + (BitPos << 1);
  2027.     CompleteCode(&AdrVals);
  2028.   }
  2029. }
  2030.  
  2031. /*!------------------------------------------------------------------------
  2032.  * \fn     DecodeBTJF_BTJT(Word Code)
  2033.  * \brief  decode BTJF/BTJT instructions
  2034.  * \param  Code instruction code
  2035.  * ------------------------------------------------------------------------ */
  2036.  
  2037. static void DecodeBTJF_BTJT(Word Code)
  2038. {
  2039.   Byte BitPos;
  2040.   tAdrVals AdrVals;
  2041.  
  2042.   if (!ChkArgCnt(2, 3));
  2043.   else if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  2044.   else if (DecodeBitAdrWithIndir(1, ArgCnt - 1, &BitPos, &AdrVals))
  2045.   {
  2046.     Integer AdrInt;
  2047.     Boolean OK;
  2048.     tSymbolFlags Flags;
  2049.  
  2050.     if (pCurrCPUProps->Core == eCoreSTM8)
  2051.     {
  2052.       PrefixCnt = 0;
  2053.       AddPrefix(0x72);
  2054.     }
  2055.     BAsmCode[PrefixCnt] = Code + (BitPos << 1);
  2056.     memcpy(BAsmCode + 1 + PrefixCnt, AdrVals.Vals, AdrVals.Cnt);
  2057.     AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[3], pCurrCPUProps->AddrIntType, &OK, &Flags) - (EProgCounter() + PrefixCnt + 1 + AdrVals.Cnt + 1);
  2058.     if (OK)
  2059.     {
  2060.       if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[3]);
  2061.       else
  2062.       {
  2063.         BAsmCode[PrefixCnt + 1 + AdrVals.Cnt] = AdrInt & 0xff;
  2064.         CodeLen = PrefixCnt + 1 + AdrVals.Cnt + 1;
  2065.       }
  2066.     }
  2067.   }
  2068. }
  2069.  
  2070. /*!------------------------------------------------------------------------
  2071.  * \fn     DecodeJP_CALL(Word Code)
  2072.  * \brief  decode JP/CALL instructions
  2073.  * \param  Code instruction code
  2074.  * ------------------------------------------------------------------------ */
  2075.  
  2076. static void DecodeJP_CALL(Word Code)
  2077. {
  2078.   if (!ChkArgCnt(1, 1));
  2079.   else if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  2080.   else
  2081.   {
  2082.     LongWord Mask;
  2083.     tAdrVals AdrVals;
  2084.  
  2085.     Mask = ConstructMask(MModAbs8 | MModAbs16 | MModIX | MModIX8 | MModIX16 | MModIY
  2086.                        | MModIY8 | MModIY16 | MModIAbs8 | MModIAbs16 | MModI16Abs16
  2087.                        | MModIXAbs8 | MModIXAbs16 | MModI16XAbs16 | MModIYAbs8 | MModIYAbs16,
  2088.                          eSymbolSizeUnknown);
  2089.     if (DecodeAdr(&ArgStr[1], Mask, True, &AdrVals))
  2090.     {
  2091.       BAsmCode[PrefixCnt] = Code + (AdrVals.Part << 4);
  2092.       CompleteCode(&AdrVals);
  2093.     }
  2094.   }
  2095. }
  2096.  
  2097. /*!------------------------------------------------------------------------
  2098.  * \fn     DecodeJPF_CALLF(Word Code)
  2099.  * \brief  decode JPF/CALLF instructions
  2100.  * \param  Code instruction code
  2101.  * ------------------------------------------------------------------------ */
  2102.  
  2103. static void DecodeJPF_CALLF(Word Code)
  2104. {
  2105.   tAdrVals AdrVals;
  2106.  
  2107.   if (!ChkArgCnt(1, 1));
  2108.   else if (pCurrCPUProps->Core != eCoreSTM8) WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  2109.   else if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  2110.   else if (DecodeAdr(&ArgStr[1], MModAbs24 | MModI16Abs24, True, &AdrVals))
  2111.   {
  2112.     BAsmCode[PrefixCnt] = Code;
  2113.     CompleteCode(&AdrVals);
  2114.   }
  2115. }
  2116.  
  2117. /*!------------------------------------------------------------------------
  2118.  * \fn     DecodeRel(Word Code)
  2119.  * \brief  decode relative branch instructions
  2120.  * \param  instruction code
  2121.  * ------------------------------------------------------------------------ */
  2122.  
  2123. static void DecodeRel(Word Code)
  2124. {
  2125.   if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  2126.   else if (!Code) WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  2127.   else if (!ChkArgCnt(1, 1));
  2128.   else if (*ArgStr[1].str.p_str == '[')
  2129.   {
  2130.     if (pCurrCPUProps->Core != eCoreST7) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  2131.     else
  2132.     {
  2133.       tAdrVals AdrVals;
  2134.  
  2135.       if (DecodeAdr(&ArgStr[1], MModIAbs8, False, &AdrVals))
  2136.       {
  2137.         BAsmCode[PrefixCnt] = Lo(Code);
  2138.         CompleteCode(&AdrVals);
  2139.       }
  2140.     }
  2141.   }
  2142.   else
  2143.   {
  2144.     Boolean OK;
  2145.     Integer AdrInt;
  2146.     tSymbolFlags Flags;
  2147.  
  2148.     if (Hi(Code))
  2149.       BAsmCode[PrefixCnt++] = Hi(Code);
  2150.     AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], pCurrCPUProps->AddrIntType, &OK, &Flags) - (EProgCounter() + 2 + PrefixCnt);
  2151.     if (OK)
  2152.     {
  2153.       if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
  2154.       else
  2155.       {
  2156.         BAsmCode[PrefixCnt] = Lo(Code);
  2157.         BAsmCode[PrefixCnt + 1] = AdrInt & 0xff;
  2158.         CodeLen = PrefixCnt + 2;
  2159.       }
  2160.     }
  2161.   }
  2162. }
  2163.  
  2164. /*!------------------------------------------------------------------------
  2165.  * \fn     DecodeRxWA(Word Code)
  2166.  * \brief  decode RLWA/RRWA instructions
  2167.  * \param  Code instruction code
  2168.  * ------------------------------------------------------------------------ */
  2169.  
  2170. static void DecodeRxWA(Word Code)
  2171. {
  2172.   tAdrMode SrcMode;
  2173.   tAdrVals DestAdrVals;
  2174.  
  2175.   if (*AttrPart.str.p_str) WrStrErrorPos(ErrNum_UseLessAttr, &AttrPart);
  2176.   else if (!ChkArgCnt(1, 2));
  2177.   else if (pCurrCPUProps->Core != eCoreSTM8) WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  2178.   else if (((ArgCnt == 1) || DecodeReg(&ArgStr[2], &SrcMode, MModA)) && DecodeAdr(&ArgStr[1], MModX | MModY, False, &DestAdrVals))
  2179.   {
  2180.     BAsmCode[PrefixCnt] = Code;
  2181.     CodeLen = PrefixCnt + 1;
  2182.   }
  2183. }
  2184.  
  2185. /*!------------------------------------------------------------------------
  2186.  * \fn     DecodeBIT(Word Code)
  2187.  * \brief  decode BIT instruction
  2188.  * ------------------------------------------------------------------------ */
  2189.  
  2190. static void DecodeBIT(Word Code)
  2191. {
  2192.   LongWord BitSpec;
  2193.  
  2194.   UNUSED(Code);
  2195.  
  2196.   /* if in structure definition, add special element to structure */
  2197.  
  2198.   if (ActPC == StructSeg)
  2199.   {
  2200.     Boolean OK;
  2201.     Byte BitPos;
  2202.     PStructElem pElement;
  2203.  
  2204.     if (!ChkArgCnt(2, 2))
  2205.       return;
  2206.     BitPos = EvalBitPosition(&ArgStr[2], &OK);
  2207.     if (!OK)
  2208.       return;
  2209.     pElement = CreateStructElem(&LabPart);
  2210.     if (!pElement)
  2211.       return;
  2212.     pElement->pRefElemName = as_strdup(ArgStr[1].str.p_str);
  2213.     pElement->OpSize = eSymbolSize8Bit;
  2214.     pElement->BitPos = BitPos;
  2215.     pElement->ExpandFnc = ExpandST7Bit;
  2216.     AddStructElem(pInnermostNamedStruct->StructRec, pElement);
  2217.   }
  2218.   else
  2219.   {
  2220.     if (DecodeBitArg(&BitSpec, 1, ArgCnt))
  2221.     {
  2222.       *ListLine = '=';
  2223.       DissectBit_ST7(ListLine + 1, STRINGSIZE - 3, BitSpec);
  2224.       PushLocHandle(-1);
  2225.       EnterIntSymbol(&LabPart, BitSpec, SegBData, False);
  2226.       PopLocHandle();
  2227.       /* TODO: MakeUseList? */
  2228.     }
  2229.   }
  2230. }
  2231.  
  2232. /*--------------------------------------------------------------------------*/
  2233.  
  2234. /*!------------------------------------------------------------------------
  2235.  * \fn     InitFields(void)
  2236.  * \brief  build up hash table of instructions
  2237.  * ------------------------------------------------------------------------ */
  2238.  
  2239. static void AddFixed(const char *NName, Word NCode)
  2240. {
  2241.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  2242. }
  2243.  
  2244. static void AddAri(const char *NName, Word NCode, Boolean NMay)
  2245. {
  2246.   AddInstTable(InstTable, NName, NCode | (NMay << 8), DecodeAri);
  2247. }
  2248.  
  2249. static void AddAri16(const char *NName, Word NCode)
  2250. {
  2251.   AddInstTable(InstTable, NName, NCode, DecodeAri16);
  2252. }
  2253.  
  2254. static void AddRMW(const char *NName, Byte NCode)
  2255. {
  2256.   char WName[10];
  2257.  
  2258.   AddInstTable(InstTable, NName, NCode, DecodeRMW);
  2259.   as_snprintf(WName, sizeof(WName), "%sW", NName);
  2260.   AddInstTable(InstTable, WName, NCode | 0x100, DecodeRMW);
  2261. }
  2262.  
  2263. static void AddRel(const char *NName, Word NCode)
  2264. {
  2265.   AddInstTable(InstTable, NName, NCode, DecodeRel);
  2266. }
  2267.  
  2268. static void InitFields(void)
  2269. {
  2270.   InstTable = CreateInstTable(201);
  2271.   SetDynamicInstTable(InstTable);
  2272.   add_null_pseudo(InstTable);
  2273.  
  2274.   AddInstTable(InstTable, "LD", 0, DecodeLD);
  2275.   AddInstTable(InstTable, "LDF", 0, DecodeLDF);
  2276.   AddInstTable(InstTable, "LDW", 0, DecodeLDW);
  2277.   AddInstTable(InstTable, "MOV", 0, DecodeMOV);
  2278.   AddInstTable(InstTable, "PUSH", 0x0004, DecodePUSH_POP);
  2279.   AddInstTable(InstTable, "POP", 0x0000, DecodePUSH_POP);
  2280.   AddInstTable(InstTable, "PUSHW", 0x0104, DecodePUSH_POP);
  2281.   AddInstTable(InstTable, "POPW", 0x0100, DecodePUSH_POP);
  2282.   AddInstTable(InstTable, "CP", 0, DecodeCP);
  2283.   AddInstTable(InstTable, "CPW", 1, DecodeCP);
  2284.   AddInstTable(InstTable, "MUL", 0, DecodeMUL);
  2285.   AddInstTable(InstTable, "DIV", 0, DecodeDIV);
  2286.   AddInstTable(InstTable, "DIVW", 1, DecodeDIV);
  2287.   AddInstTable(InstTable, "EXG", 0, DecodeEXG);
  2288.   AddInstTable(InstTable, "EXGW", 1, DecodeEXG);
  2289.   AddInstTable(InstTable, "RLWA", 0x02, DecodeRxWA);
  2290.   AddInstTable(InstTable, "RRWA", 0x01, DecodeRxWA);
  2291.   AddInstTable(InstTable, "BCCM", 0x9001, DecodeBitOp);
  2292.   AddInstTable(InstTable, "BCPL", 0x9000, DecodeBitOp);
  2293.   AddInstTable(InstTable, "BRES", 0x7211, DecodeBitOp);
  2294.   AddInstTable(InstTable, "BSET", 0x7210, DecodeBitOp);
  2295.   AddInstTable(InstTable, "BTJF", 0x01, DecodeBTJF_BTJT);
  2296.   AddInstTable(InstTable, "BTJT", 0x00, DecodeBTJF_BTJT);
  2297.   AddInstTable(InstTable, "JP", 0x0c, DecodeJP_CALL);
  2298.   AddInstTable(InstTable, "CALL", 0x0d, DecodeJP_CALL);
  2299.   AddInstTable(InstTable, "JPF", 0xac, DecodeJPF_CALLF);
  2300.   AddInstTable(InstTable, "CALLF", 0x8d, DecodeJPF_CALLF);
  2301.   AddInstTable(InstTable, "BIT", 0, DecodeBIT);
  2302.  
  2303.   AddFixed("HALT" , 0x8e); AddFixed("IRET" , 0x80); AddFixed("NOP"  , 0x9d);
  2304.   AddFixed("RCF"  , 0x98); AddFixed("RET"  , 0x81); AddFixed("RIM"  , 0x9a);
  2305.   AddFixed("RSP"  , 0x9c); AddFixed("SCF"  , 0x99); AddFixed("SIM"  , 0x9b);
  2306.   AddFixed("TRAP" , 0x83); AddFixed("WFI"  , 0x8f); AddFixed("BREAK", 0x018b);
  2307.   AddFixed("WFE"  , 0x728f); AddFixed("RVF"  , 0x019c); AddFixed("RETF", 0x0187);
  2308.   AddFixed("CCF"  , 0x018c);
  2309.  
  2310.   AddAri("ADC" , 0x09, True ); AddAri("ADD" , 0x0b, True ); AddAri("AND" , 0x04, True );
  2311.   AddAri("BCP" , 0x05, True ); AddAri("OR"  , 0x0a, True ); AddAri("SBC" , 0x02, True );
  2312.   AddAri("SUB" , 0x00, True ); AddAri("XOR" , 0x08, True );
  2313.  
  2314.   AddAri16("ADDW", 0x090b); AddAri16("SUBW", 0x0200);
  2315.  
  2316.   AddRMW("CLR" , 0x0f); AddRMW("CPL" , 0x03); AddRMW("DEC" , 0x0a);
  2317.   AddRMW("INC" , 0x0c); AddRMW("NEG" , 0x00); AddRMW("RLC" , 0x09);
  2318.   AddRMW("RRC" , 0x06); AddRMW("SLA" , 0x08); AddRMW("SLL" , 0x08);
  2319.   AddRMW("SRA" , 0x07); AddRMW("SRL" , 0x04); AddRMW("SWAP", 0x0e);
  2320.   AddRMW("TNZ" , 0x0d);
  2321.  
  2322.   AddRel("CALLR", 0xad);
  2323.   AddRel("JRA"  , 0x20);
  2324.   AddRel("JRC"  , 0x25);
  2325.   AddRel("JREQ" , 0x27);
  2326.   AddRel("JRF"  , 0x21);
  2327.   AddRel("JRH"  , (pCurrCPUProps->Core == eCoreSTM8) ? 0x9029 : 0x29);
  2328.   AddRel("JRIH" , (pCurrCPUProps->Core == eCoreSTM8) ? 0x902f : 0x2f);
  2329.   AddRel("JRIL" , (pCurrCPUProps->Core == eCoreSTM8) ? 0x902e : 0x2e);
  2330.   AddRel("JRM"  , (pCurrCPUProps->Core == eCoreSTM8) ? 0x902d : 0x2d);
  2331.   AddRel("JRMI" , 0x2b);
  2332.   AddRel("JRNC" , 0x24);
  2333.   AddRel("JRNE" , 0x26);
  2334.   AddRel("JRNH" , (pCurrCPUProps->Core == eCoreSTM8) ? 0x9028 : 0x28);
  2335.   AddRel("JRNM" , (pCurrCPUProps->Core == eCoreSTM8) ? 0x902c : 0x2c);
  2336.   AddRel("JRNV" , (pCurrCPUProps->Core == eCoreSTM8) ? 0x28 : 0x00);
  2337.   AddRel("JRPL" , 0x2a);
  2338.   AddRel("JRSGE", (pCurrCPUProps->Core == eCoreSTM8) ? 0x2e : 0x00);
  2339.   AddRel("JRSGT", (pCurrCPUProps->Core == eCoreSTM8) ? 0x2c : 0x00);
  2340.   AddRel("JRSLE", (pCurrCPUProps->Core == eCoreSTM8) ? 0x2d : 0x00);
  2341.   AddRel("JRSLT", (pCurrCPUProps->Core == eCoreSTM8) ? 0x2f : 0x00);
  2342.   AddRel("JRT"  , 0x20);
  2343.   AddRel("JRUGE", 0x24);
  2344.   AddRel("JRUGT", 0x22);
  2345.   AddRel("JRULE", 0x23);
  2346.   AddRel("JRULT", 0x25);
  2347.   AddRel("JRV"  , (pCurrCPUProps->Core == eCoreSTM8) ? 0x29 : 0x00);
  2348.  
  2349.   add_moto8_pseudo(InstTable, e_moto_pseudo_flags_be);
  2350.   AddMoto16Pseudo(InstTable, e_moto_pseudo_flags_be);
  2351. }
  2352.  
  2353. /*!------------------------------------------------------------------------
  2354.  * \fn     DeinitFields(void)
  2355.  * \brief  tear down instruction hash table
  2356.  * ------------------------------------------------------------------------ */
  2357.  
  2358. static void DeinitFields(void)
  2359. {
  2360.   DestroyInstTable(InstTable);
  2361. }
  2362.  
  2363. /*!------------------------------------------------------------------------
  2364.  * \fn     MakeCode_ST7(void)
  2365.  * \brief  entry point to decode machine instructions
  2366.  * ------------------------------------------------------------------------ */
  2367.  
  2368. static Boolean DecodeAttrPart_ST7(void)
  2369. {
  2370.   if (strlen(AttrPart.str.p_str) > 1)
  2371.   {
  2372.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  2373.     return False;
  2374.   }
  2375.   return DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False);
  2376. }
  2377.  
  2378. static void MakeCode_ST7(void)
  2379. {
  2380.   if (AttrPartOpSize[0] == eSymbolSizeUnknown)
  2381.     AttrPartOpSize[0] = eSymbolSize8Bit;
  2382.   OpSize = AttrPartOpSize[0];
  2383.   PrefixCnt = 0;
  2384.  
  2385.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  2386.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  2387. }
  2388.  
  2389. /*!------------------------------------------------------------------------
  2390.  * \fn     IsDef_ST7(void)
  2391.  * \brief  does instruction consume label field?
  2392.  * \return true if to be consumed
  2393.  * ------------------------------------------------------------------------ */
  2394.  
  2395. static Boolean IsDef_ST7(void)
  2396. {
  2397.   return Memo("BIT");
  2398. }
  2399.  
  2400. /*!------------------------------------------------------------------------
  2401.  * \fn     SwitchTo_ST7(void)
  2402.  * \brief  switch to target
  2403.  * ------------------------------------------------------------------------ */
  2404.  
  2405. static void SwitchTo_ST7(void *pUser)
  2406. {
  2407.   pCurrCPUProps = (const tCPUProps*)pUser;
  2408.   TurnWords = False;
  2409.   SetIntConstMode(eIntConstModeMoto);
  2410.  
  2411.   PCSymbol = "PC"; HeaderID = 0x33; NOPCode = 0x9d;
  2412.   DivideChars = ","; HasAttrs = True; AttrChars = ".";
  2413.  
  2414.   ValidSegs = 1 << SegCode;
  2415.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  2416.   SegLimits[SegCode] = IntTypeDefs[pCurrCPUProps->AddrIntType].Max;
  2417.  
  2418.   DecodeAttrPart = DecodeAttrPart_ST7;
  2419.   MakeCode = MakeCode_ST7;
  2420.   IsDef = IsDef_ST7;
  2421.   SwitchFrom = DeinitFields;
  2422.   DissectBit = DissectBit_ST7;
  2423.   InitFields();
  2424.   AddMoto16PseudoONOFF(False);
  2425. }
  2426.  
  2427. /*!------------------------------------------------------------------------
  2428.  * \fn     codest7_init(void)
  2429.  * \brief  register ST7/STM8 target
  2430.  * ------------------------------------------------------------------------ */
  2431.  
  2432. static const tCPUProps CPUProps[] =
  2433. {
  2434.   { "ST7"         ,  Int16, eCoreST7  },
  2435.   { "ST7232AK1"   ,  Int16, eCoreST7  },
  2436.   { "ST7232AK2"   ,  Int16, eCoreST7  },
  2437.   { "ST7232AJ1"   ,  Int16, eCoreST7  },
  2438.   { "ST7232AJ2"   ,  Int16, eCoreST7  },
  2439.   { "ST72251G1"   ,  Int16, eCoreST7  },
  2440.   { "ST72251G2"   ,  Int16, eCoreST7  },
  2441.   { "ST72311J2"   ,  Int16, eCoreST7  },
  2442.   { "ST72311J4"   ,  Int16, eCoreST7  },
  2443.   { "ST72321BR6"  ,  Int16, eCoreST7  },
  2444.   { "ST72321BR7"  ,  Int16, eCoreST7  },
  2445.   { "ST72321BR9"  ,  Int16, eCoreST7  },
  2446.   { "ST72324J6"   ,  Int16, eCoreST7  },
  2447.   { "ST72324K6"   ,  Int16, eCoreST7  },
  2448.   { "ST72324J4"   ,  Int16, eCoreST7  },
  2449.   { "ST72324K4"   ,  Int16, eCoreST7  },
  2450.   { "ST72324J2"   ,  Int16, eCoreST7  },
  2451.   { "ST72324K2"   ,  Int16, eCoreST7  },
  2452.   { "ST72325S4"   ,  Int16, eCoreST7  },
  2453.   { "ST72325S6"   ,  Int16, eCoreST7  },
  2454.   { "ST72325J7"   ,  Int16, eCoreST7  },
  2455.   { "ST72325R9"   ,  Int16, eCoreST7  },
  2456.   { "ST72344K2"   ,  Int16, eCoreST7  },
  2457.   { "ST72344K4"   ,  Int16, eCoreST7  },
  2458.   { "ST72345C4"   ,  Int16, eCoreST7  },
  2459.   { "ST72521BR6"  ,  Int16, eCoreST7  },
  2460.   { "ST72521BM9"  ,  Int16, eCoreST7  },
  2461.   { "ST72361AR4"  ,  Int16, eCoreST7  },
  2462.   { "ST72361AR6"  ,  Int16, eCoreST7  },
  2463.   { "ST72361AR7"  ,  Int16, eCoreST7  },
  2464.   { "ST72361AR9"  ,  Int16, eCoreST7  },
  2465.   { "ST7FOXK1"    ,  Int16, eCoreST7  },
  2466.   { "ST7FOXK2"    ,  Int16, eCoreST7  },
  2467.   { "ST7LITES2Y0" ,  Int16, eCoreST7  },
  2468.   { "ST7LITES5Y0" ,  Int16, eCoreST7  },
  2469.   { "ST7LITE02Y0" ,  Int16, eCoreST7  },
  2470.   { "ST7LITE05Y0" ,  Int16, eCoreST7  },
  2471.   { "ST7LITE09Y0" ,  Int16, eCoreST7  },
  2472.   { "ST7LITE10F1" ,  Int16, eCoreST7  },
  2473.   { "ST7LITE15F1" ,  Int16, eCoreST7  },
  2474.   { "ST7LITE19F1" ,  Int16, eCoreST7  },
  2475.   { "ST7LITE10BF0",  Int16, eCoreST7  },
  2476.   { "ST7LITE15BF0",  Int16, eCoreST7  },
  2477.   { "ST7LITE15BF1",  Int16, eCoreST7  },
  2478.   { "ST7LITE19BF0",  Int16, eCoreST7  },
  2479.   { "ST7LITE19BF1",  Int16, eCoreST7  },
  2480.   { "ST7LITE20F2" ,  Int16, eCoreST7  },
  2481.   { "ST7LITE25F2" ,  Int16, eCoreST7  },
  2482.   { "ST7LITE29F2" ,  Int16, eCoreST7  },
  2483.   { "ST7LITE30F2" ,  Int16, eCoreST7  },
  2484.   { "ST7LITE35F2" ,  Int16, eCoreST7  },
  2485.   { "ST7LITE39F2" ,  Int16, eCoreST7  },
  2486.   { "ST7LITE49K2" ,  Int16, eCoreST7  },
  2487.   { "ST7MC1K2"    ,  Int16, eCoreST7  },
  2488.   { "ST7MC1K4"    ,  Int16, eCoreST7  },
  2489.   { "ST7MC2N6"    ,  Int16, eCoreST7  },
  2490.   { "ST7MC2S4"    ,  Int16, eCoreST7  },
  2491.   { "ST7MC2S6"    ,  Int16, eCoreST7  },
  2492.   { "ST7MC2S7"    ,  Int16, eCoreST7  },
  2493.   { "ST7MC2S9"    ,  Int16, eCoreST7  },
  2494.   { "ST7MC2R6"    ,  Int16, eCoreST7  },
  2495.   { "ST7MC2R7"    ,  Int16, eCoreST7  },
  2496.   { "ST7MC2R9"    ,  Int16, eCoreST7  },
  2497.   { "ST7MC2M9"    ,  Int16, eCoreST7  },
  2498.  
  2499.   { "STM8"        ,  Int24, eCoreSTM8 },
  2500.   { "STM8S001J3"  ,  Int16, eCoreSTM8 },
  2501.   { "STM8S003F3"  ,  Int16, eCoreSTM8 },
  2502.   { "STM8S003K3"  ,  Int16, eCoreSTM8 },
  2503.   { "STM8S005C6"  ,  Int16, eCoreSTM8 },
  2504.   { "STM8S005K6"  ,  Int16, eCoreSTM8 },
  2505.   { "STM8S007C8"  ,  Int24, eCoreSTM8 },
  2506.   { "STM8S103F2"  ,  Int16, eCoreSTM8 },
  2507.   { "STM8S103F3"  ,  Int16, eCoreSTM8 },
  2508.   { "STM8S103K3"  ,  Int16, eCoreSTM8 },
  2509.   { "STM8S105C4"  ,  Int16, eCoreSTM8 },
  2510.   { "STM8S105C6"  ,  Int16, eCoreSTM8 },
  2511.   { "STM8S105K4"  ,  Int16, eCoreSTM8 },
  2512.   { "STM8S105K6"  ,  Int16, eCoreSTM8 },
  2513.   { "STM8S105S4"  ,  Int16, eCoreSTM8 },
  2514.   { "STM8S105S6"  ,  Int16, eCoreSTM8 },
  2515.   { "STM8S207MB"  ,  Int24, eCoreSTM8 },
  2516.   { "STM8S207M8"  ,  Int24, eCoreSTM8 },
  2517.   { "STM8S207RB"  ,  Int24, eCoreSTM8 },
  2518.   { "STM8S207R8"  ,  Int24, eCoreSTM8 },
  2519.   { "STM8S207R6"  ,  Int16, eCoreSTM8 },
  2520.   { "STM8S207CB"  ,  Int24, eCoreSTM8 },
  2521.   { "STM8S207C8"  ,  Int24, eCoreSTM8 },
  2522.   { "STM8S207C6"  ,  Int16, eCoreSTM8 },
  2523.   { "STM8S207SB"  ,  Int24, eCoreSTM8 },
  2524.   { "STM8S207S8"  ,  Int24, eCoreSTM8 },
  2525.   { "STM8S207S6"  ,  Int16, eCoreSTM8 },
  2526.   { "STM8S207K8"  ,  Int24, eCoreSTM8 },
  2527.   { "STM8S207K6"  ,  Int16, eCoreSTM8 },
  2528.   { "STM8S208MB"  ,  Int24, eCoreSTM8 },
  2529.   { "STM8S208RB"  ,  Int24, eCoreSTM8 },
  2530.   { "STM8S208R8"  ,  Int24, eCoreSTM8 },
  2531.   { "STM8S208R6"  ,  Int24, eCoreSTM8 },
  2532.   { "STM8S208CB"  ,  Int24, eCoreSTM8 },
  2533.   { "STM8S208C8"  ,  Int24, eCoreSTM8 },
  2534.   { "STM8S208C6"  ,  Int16, eCoreSTM8 },
  2535.   { "STM8S208SB"  ,  Int24, eCoreSTM8 },
  2536.   { "STM8S208S8"  ,  Int24, eCoreSTM8 },
  2537.   { "STM8S208S6"  ,  Int16, eCoreSTM8 },
  2538.   { "STM8S903K3"  ,  Int16, eCoreSTM8 },
  2539.   { "STM8S903F3"  ,  Int16, eCoreSTM8 },
  2540.   { "STM8L050J3"  ,  Int16, eCoreSTM8 },
  2541.   { "STM8L051F3"  ,  Int16, eCoreSTM8 },
  2542.   { "STM8L052C6"  ,  Int16, eCoreSTM8 },
  2543.   { "STM8L052R8"  ,  Int24, eCoreSTM8 },
  2544.   { "STM8L001J3"  ,  Int16, eCoreSTM8 },
  2545.   { "STM8L101F1"  ,  Int16, eCoreSTM8 },
  2546.   { "STM8L101F2"  ,  Int16, eCoreSTM8 },
  2547.   { "STM8L101G2"  ,  Int16, eCoreSTM8 },
  2548.   { "STM8L101F3"  ,  Int16, eCoreSTM8 },
  2549.   { "STM8L101G3"  ,  Int16, eCoreSTM8 },
  2550.   { "STM8L101K3"  ,  Int16, eCoreSTM8 },
  2551.   { "STM8L151C2"  ,  Int16, eCoreSTM8 },
  2552.   { "STM8L151K2"  ,  Int16, eCoreSTM8 },
  2553.   { "STM8L151G2"  ,  Int16, eCoreSTM8 },
  2554.   { "STM8L151F2"  ,  Int16, eCoreSTM8 },
  2555.   { "STM8L151C3"  ,  Int16, eCoreSTM8 },
  2556.   { "STM8L151K3"  ,  Int16, eCoreSTM8 },
  2557.   { "STM8L151G3"  ,  Int16, eCoreSTM8 },
  2558.   { "STM8L151F3"  ,  Int16, eCoreSTM8 },
  2559.   { "STM8L151C4"  ,  Int16, eCoreSTM8 },
  2560.   { "STM8L151C6"  ,  Int16, eCoreSTM8 },
  2561.   { "STM8L151K4"  ,  Int16, eCoreSTM8 },
  2562.   { "STM8L151K6"  ,  Int16, eCoreSTM8 },
  2563.   { "STM8L151G4"  ,  Int16, eCoreSTM8 },
  2564.   { "STM8L151G6"  ,  Int16, eCoreSTM8 },
  2565.   { "STM8L152C4"  ,  Int16, eCoreSTM8 },
  2566.   { "STM8L152C6"  ,  Int16, eCoreSTM8 },
  2567.   { "STM8L152K4"  ,  Int16, eCoreSTM8 },
  2568.   { "STM8L152K6"  ,  Int16, eCoreSTM8 },
  2569.   { "STM8L151R6"  ,  Int16, eCoreSTM8 },
  2570.   { "STM8L151C8"  ,  Int24, eCoreSTM8 },
  2571.   { "STM8L151M8"  ,  Int16, eCoreSTM8 },
  2572.   { "STM8L151R8"  ,  Int24, eCoreSTM8 },
  2573.   { "STM8L152R6"  ,  Int16, eCoreSTM8 },
  2574.   { "STM8L152C8"  ,  Int24, eCoreSTM8 },
  2575.   { "STM8L152K8"  ,  Int24, eCoreSTM8 },
  2576.   { "STM8L152M8"  ,  Int24, eCoreSTM8 },
  2577.   { "STM8L152R8"  ,  Int24, eCoreSTM8 },
  2578.   { "STM8L162M8"  ,  Int24, eCoreSTM8 },
  2579.   { "STM8L162R8"  ,  Int24, eCoreSTM8 },
  2580.   { "STM8AF6366"  ,  Int16, eCoreSTM8 },
  2581.   { "STM8AF6388"  ,  Int24, eCoreSTM8 },
  2582.   { "STM8AF6213"  ,  Int16, eCoreSTM8 },
  2583.   { "STM8AF6223"  ,  Int16, eCoreSTM8 },
  2584.   { "STM8AF6226"  ,  Int16, eCoreSTM8 },
  2585.   { "STM8AF6246"  ,  Int16, eCoreSTM8 },
  2586.   { "STM8AF6248"  ,  Int16, eCoreSTM8 },
  2587.   { "STM8AF6266"  ,  Int16, eCoreSTM8 },
  2588.   { "STM8AF6268"  ,  Int16, eCoreSTM8 },
  2589.   { "STM8AF6269"  ,  Int16, eCoreSTM8 },
  2590.   { "STM8AF6286"  ,  Int24, eCoreSTM8 },
  2591.   { "STM8AF6288"  ,  Int24, eCoreSTM8 },
  2592.   { "STM8AF6289"  ,  Int24, eCoreSTM8 },
  2593.   { "STM8AF628A"  ,  Int24, eCoreSTM8 },
  2594.   { "STM8AF62A6"  ,  Int24, eCoreSTM8 },
  2595.   { "STM8AF62A8"  ,  Int24, eCoreSTM8 },
  2596.   { "STM8AF62A9"  ,  Int24, eCoreSTM8 },
  2597.   { "STM8AF62AA"  ,  Int24, eCoreSTM8 },
  2598.   { "STM8AF5268"  ,  Int16, eCoreSTM8 },
  2599.   { "STM8AF5269"  ,  Int16, eCoreSTM8 },
  2600.   { "STM8AF5286"  ,  Int24, eCoreSTM8 },
  2601.   { "STM8AF5288"  ,  Int24, eCoreSTM8 },
  2602.   { "STM8AF5289"  ,  Int24, eCoreSTM8 },
  2603.   { "STM8AF528A"  ,  Int24, eCoreSTM8 },
  2604.   { "STM8AF52A6"  ,  Int24, eCoreSTM8 },
  2605.   { "STM8AF52A8"  ,  Int24, eCoreSTM8 },
  2606.   { "STM8AF52A9"  ,  Int24, eCoreSTM8 },
  2607.   { "STM8AF52AA"  ,  Int24, eCoreSTM8 },
  2608.   { "STM8AL3136"  ,  Int16, eCoreSTM8 },
  2609.   { "STM8AL3138"  ,  Int16, eCoreSTM8 },
  2610.   { "STM8AL3146"  ,  Int16, eCoreSTM8 },
  2611.   { "STM8AL3148"  ,  Int16, eCoreSTM8 },
  2612.   { "STM8AL3166"  ,  Int16, eCoreSTM8 },
  2613.   { "STM8AL3168"  ,  Int16, eCoreSTM8 },
  2614.   { "STM8AL3L46"  ,  Int16, eCoreSTM8 },
  2615.   { "STM8AL3L48"  ,  Int16, eCoreSTM8 },
  2616.   { "STM8AL3L66"  ,  Int16, eCoreSTM8 },
  2617.   { "STM8AL3L68"  ,  Int16, eCoreSTM8 },
  2618.   { "STM8AL3188"  ,  Int24, eCoreSTM8 },
  2619.   { "STM8AL3189"  ,  Int24, eCoreSTM8 },
  2620.   { "STM8AL318A"  ,  Int24, eCoreSTM8 },
  2621.   { "STM8AL3L88"  ,  Int24, eCoreSTM8 },
  2622.   { "STM8AL3L89"  ,  Int24, eCoreSTM8 },
  2623.   { "STM8AL3L8A"  ,  Int24, eCoreSTM8 },
  2624.   { "STM8TL52F4"  ,  Int16, eCoreSTM8 },
  2625.   { "STM8TL52G4"  ,  Int16, eCoreSTM8 },
  2626.   { "STM8TL53C4"  ,  Int16, eCoreSTM8 },
  2627.   { "STM8TL53F4"  ,  Int16, eCoreSTM8 },
  2628.   { "STM8TL53G4"  ,  Int16, eCoreSTM8 },
  2629.   { NULL          ,  UInt1, eCoreST7  },
  2630. };
  2631.  
  2632. void codest7_init(void)
  2633. {
  2634.   const tCPUProps *pProp;
  2635.  
  2636.   for (pProp = CPUProps; pProp->pName; pProp++)
  2637.     (void)AddCPUUser(pProp->pName, SwitchTo_ST7, (void*)pProp, NULL);
  2638. }
  2639.