Subversion Repositories pentevo

Rev

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

  1. /* codez8.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator Zilog Z8                                                    */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "nls.h"
  16. #include "strutil.h"
  17. #include "bpemu.h"
  18. #include "asmdef.h"
  19. #include "asmsub.h"
  20. #include "asmpars.h"
  21. #include "asmstructs.h"
  22. #include "asmitree.h"
  23. #include "asmallg.h"
  24. #include "codepseudo.h"
  25. #include "intpseudo.h"
  26. #include "codevars.h"
  27. #include "headids.h"
  28. #include "errmsg.h"
  29.  
  30. #include "codez8.h"
  31.  
  32. typedef enum
  33. {
  34.   eCoreNone = 0,
  35.   eCoreZ8NMOS = 1 << 0,
  36.   eCoreZ8CMOS = 1 << 1,
  37.   eCoreSuper8 = 1 << 2,
  38.   eCoreZ8Encore = 1 << 3,
  39.   eCoreAll = eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore
  40. } tCoreFlags;
  41.  
  42. typedef struct
  43. {
  44.   const char *pName;
  45.   Word Code;
  46.   tCoreFlags CoreFlags;
  47. } BaseOrder;
  48.  
  49. typedef struct
  50. {
  51.   Word Code;
  52.   tCoreFlags CoreFlags;
  53.   Boolean Is16;
  54. } ALU1Order;
  55.  
  56. typedef struct
  57. {
  58.   const char *Name;
  59.   Byte Code;
  60. } Condition;
  61.  
  62. #ifdef __cplusplus
  63. # include "codez8.hpp"
  64. #endif
  65.  
  66. typedef struct
  67. {
  68.   const char *pName;
  69.   tCoreFlags CoreFlags;
  70.   Word WorkOfs;
  71.   Word RAMEnd, SFRStart;
  72. } tCPUProps;
  73.  
  74. #define LongWorkOfs 0xee0   /* ditto with 12-bit-addresses */
  75.  
  76. #define EXTPREFIX 0x1f
  77.  
  78. #define mIsSuper8() (pCurrCPUProps->CoreFlags & eCoreSuper8)
  79. #define mIsZ8Encore() (pCurrCPUProps->CoreFlags & eCoreZ8Encore)
  80.  
  81. /* CAUTION: ModIReg and ModIRReg are mutually exclusive
  82.             ModReg  and ModRReg  are mutually exclusive */
  83.  
  84. enum
  85. {
  86.   ModNone = -1,
  87.   ModWReg = 0,      /* working register R0..R15, 'r' */
  88.   ModReg = 1,       /* general register 'R' */
  89.   ModRReg = 2,      /* general register pair 'RR' (must be even) */
  90.   ModIWReg = 3,     /* indirect working register @R0...@R15 'Ir' */
  91.   ModIReg = 4,      /* indirect general register 'IR' */
  92.   ModImm = 5,       /* immediate value 'IM' */
  93.   ModWRReg = 6,     /* working register pair 'rr' (must be even) */
  94.   ModIWRReg = 7,    /* indirect working register pair 'Irr' (must be even) */
  95.   ModIRReg = 8,     /* indirect general register pair 'IRR' (must be even) */
  96.   ModInd = 9,
  97.   ModXReg = 10,
  98.   ModIndRR = 11,
  99.   ModIndRR16 = 12,
  100.   ModWeird = 13,
  101.   ModDA = 14
  102. };
  103.  
  104. #define MModWReg   (1 << ModWReg)
  105. #define MModReg    (1 << ModReg)
  106. #define MModRReg   (1 << ModRReg)
  107. #define MModIWReg  (1 << ModIWReg)
  108. #define MModIReg   (1 << ModIReg)
  109. #define MModImm    (1 << ModImm)
  110. #define MModWRReg  (1 << ModWRReg)
  111. #define MModIWRReg (1 << ModIWRReg)
  112. #define MModIRReg  (1 << ModIRReg)
  113. #define MModInd    (1 << ModInd)
  114. #define MModXReg   (1 << ModXReg)
  115. #define MModIndRR  (1 << ModIndRR)
  116. #define MModIndRR16  (1 << ModIndRR16)
  117. #define MModWeird  (1 << ModWeird)
  118. #define MModDA     (1 << ModDA)
  119.  
  120. static ShortInt AdrType, OpSize;
  121. static Byte AdrVal;
  122. static Word AdrWVal;
  123. static LongInt AdrIndex;
  124.  
  125. static BaseOrder *FixedOrders;
  126. static BaseOrder *ALU2Orders;
  127. static BaseOrder *ALUXOrders;
  128. static ALU1Order *ALU1Orders;
  129. static Condition *Conditions;
  130.  
  131. static int CondCnt, TrueCond;
  132.  
  133. static const tCPUProps *pCurrCPUProps;
  134.  
  135. static LongInt RPVal, RP0Val, RP1Val;
  136. static IntType RegSpaceType;
  137.  
  138. /*--------------------------------------------------------------------------*/
  139. /* address expression decoding routines */
  140.  
  141. /*!------------------------------------------------------------------------
  142.  * \fn     IsWRegCore(const char *pArg, Byte *pResult)
  143.  * \brief  Is argument a working register? (Rn, n=0..15)
  144.  * \param  pArg argument
  145.  * \param  pResult resulting register number if it is
  146.  * \return True if it is
  147.  * ------------------------------------------------------------------------ */
  148.  
  149. static Boolean IsWRegCore(const char *pArg, Byte *pResult)
  150. {
  151.   if ((strlen(pArg) < 2) || (as_toupper(*pArg) != 'R')) return False;
  152.   else
  153.   {
  154.     Boolean OK;
  155.  
  156.     *pResult = ConstLongInt(pArg + 1, &OK, 10);
  157.     return OK && (*pResult <= 15);
  158.   }
  159. }
  160.  
  161. /*!------------------------------------------------------------------------
  162.  * \fn     IsWReg(const tStrComp *pArg, Byte *pResult, Boolean MustBeReg)
  163.  * \brief  Is argument a working register (Rn, n=0..15) or register alias?
  164.  * \param  pArg argument
  165.  * \param  pResult resulting register number if it is
  166.  * \param  MustBeReg expecting register?
  167.  * \return reg eval result
  168.  * ------------------------------------------------------------------------ */
  169.  
  170. static Boolean IsWReg(const tStrComp *pArg, Byte *pResult, Boolean MustBeReg)
  171. {
  172.   tRegDescr RegDescr;
  173.   tEvalResult EvalResult;
  174.   tRegEvalResult RegEvalResult;
  175.  
  176.   if (IsWRegCore(pArg->str.p_str, pResult))
  177.     return True;
  178.  
  179.   RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSize8Bit, MustBeReg);
  180.   *pResult = RegDescr.Reg;
  181.   return RegEvalResult;
  182. }
  183.  
  184. /*!------------------------------------------------------------------------
  185.  * \fn     IsWRRegCore(const char *pArg, Byte *pResult)
  186.  * \brief  Is argument a working register pair? (RRn, n=0..15)
  187.  * \param  pArg argument
  188.  * \param  pResult resulting value if it is
  189.  * \return True if it is
  190.  * ------------------------------------------------------------------------ */
  191.  
  192. static Boolean IsWRRegCore(const char *pArg, Byte *pResult)
  193. {
  194.   if ((strlen(pArg) < 3) || as_strncasecmp(pArg, "RR", 2)) return False;
  195.   else
  196.   {
  197.     Boolean OK;
  198.  
  199.     *pResult = ConstLongInt(pArg + 2, &OK, 10);
  200.     return OK && (*pResult <= 15);
  201.   }
  202. }
  203.  
  204. #if 0
  205. /*!------------------------------------------------------------------------
  206.  * \fn     IsWRReg(const tStrComp *pArg, Byte *pResult, Boolean MustBeReg)
  207.  * \brief  Is argument a working register pair (RRn, n=0..15) or register pair alias?
  208.  * \param  pArg argument
  209.  * \param  pResult resulting value if it is
  210.  * \param  MustBeReg expecting register?
  211.  * \return reg eval result
  212.  * ------------------------------------------------------------------------ */
  213.  
  214. static Boolean IsWRReg(const tStrComp *pArg, Byte *pResult, Boolean MustBeReg)
  215. {
  216.   tRegDescr RegDescr;
  217.   tEvalResult EvalResult;
  218.   tRegEvalResult RegEvalResult;
  219.  
  220.   if (IsWRRegCore(pArg->str.p_str, pResult))
  221.     return True;
  222.  
  223.   RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSize16Bit, MustBeReg);
  224.   *pResult = RegDescr.Reg;
  225.   return RegEvalResult;
  226. }
  227. #endif
  228.  
  229. /*!------------------------------------------------------------------------
  230.  * \fn     IsWRegOrWRReg(const tStrComp *pArg, Byte *pResult, tSymbolSize *pSize, Boolean MustBeReg)
  231.  * \brief  Is argument a working register (pair) ((R)Rn, n=0..15) or register (pair) alias?
  232.  * \param  pArg argument
  233.  * \param  pResult resulting value if it is
  234.  * \param  pSize register size if it is
  235.  * \param  MustBeReg expecting register?
  236.  * \return reg eval result
  237.  * ------------------------------------------------------------------------ */
  238.  
  239. static tRegEvalResult IsWRegOrWRReg(const tStrComp *pArg, Byte *pResult, tSymbolSize *pSize, Boolean MustBeReg)
  240. {
  241.   tEvalResult EvalResult;
  242.   tRegEvalResult RegEvalResult;
  243.  
  244.   if (IsWRegCore(pArg->str.p_str, pResult))
  245.   {
  246.     EvalResult.DataSize = eSymbolSize8Bit;
  247.     RegEvalResult = eIsReg;
  248.   }
  249.   else if (IsWRRegCore(pArg->str.p_str, pResult))
  250.   {
  251.     EvalResult.DataSize = eSymbolSize16Bit;
  252.     RegEvalResult = eIsReg;
  253.   }
  254.   else
  255.   {
  256.     tRegDescr RegDescr;
  257.  
  258.     RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
  259.     *pResult = RegDescr.Reg;
  260.   }
  261.  
  262.   if ((eIsReg == RegEvalResult) && (EvalResult.DataSize == eSymbolSize16Bit) && (*pResult & 1))
  263.   {
  264.     WrStrErrorPos(ErrNum_AddrMustBeEven, pArg);
  265.     RegEvalResult = MustBeReg ? eIsNoReg : eRegAbort;
  266.   }
  267.  
  268.   *pSize = EvalResult.DataSize;
  269.   return RegEvalResult;
  270. }
  271.  
  272. /*!------------------------------------------------------------------------
  273.  * \fn     DissectReg_Z8(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  274.  * \brief  dissect register symbols - Z8 variant
  275.  * \param  pDest destination buffer
  276.  * \param  DestSize destination buffer size
  277.  * \param  Value numeric register value
  278.  * \param  InpSize register size
  279.  * ------------------------------------------------------------------------ */
  280.  
  281. static void DissectReg_Z8(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  282. {
  283.   switch (InpSize)
  284.   {
  285.     case eSymbolSize8Bit:
  286.       as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
  287.       break;
  288.     case eSymbolSize16Bit:
  289.       as_snprintf(pDest, DestSize, "RR%u", (unsigned)Value);
  290.       break;
  291.     default:
  292.       as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
  293.   }
  294. }
  295.  
  296. /*!------------------------------------------------------------------------
  297.  * \fn     CorrMode8(Word Mask, ShortInt Old, ShortInt New)
  298.  * \brief  upgrade from working reg mode to gen. reg mode if necessary & possible?
  299.  * \param  Mask bit mask of allowed addressing modes
  300.  * \param  Old currently selected (working reg) mode
  301.  * \param  New possible new mode
  302.  * \return True if converted
  303.  * ------------------------------------------------------------------------ */
  304.  
  305. static Boolean CorrMode8(Word Mask, ShortInt Old, ShortInt New)
  306. {
  307.    if ((AdrType == Old) && ((Mask & (1 << Old)) == 0) && ((Mask & (1 << New)) != 0))
  308.    {
  309.      AdrType = New;
  310.      AdrVal += pCurrCPUProps->WorkOfs;
  311.      return True;
  312.    }
  313.    else
  314.      return False;
  315. }
  316.  
  317. /*!------------------------------------------------------------------------
  318.  * \fn     Boolean CorrMode12(Word Mask, ShortInt Old, ShortInt New)
  319.  * \brief  upgrade from working reg mode to ext. reg (12 bit) mode if necessary & possible?
  320.  * \param  Mask bit mask of allowed addressing modes
  321.  * \param  Old currently selected (working reg) mode
  322.  * \param  New possible new mode
  323.  * \return True if converted
  324.  * ------------------------------------------------------------------------ */
  325.  
  326. static Boolean CorrMode12(Word Mask, ShortInt Old, ShortInt New)
  327. {
  328.    if ((AdrType == Old) && ((Mask & (1 << Old)) == 0) && ((Mask & (1 << New)) != 0))
  329.    {
  330.      AdrType = New;
  331.      AdrWVal = AdrVal + LongWorkOfs;
  332.      return True;
  333.    }
  334.    else
  335.      return False;
  336. }
  337.  
  338. /*!------------------------------------------------------------------------
  339.  * \fn     ChkAdr(Word Mask, const tStrComp *pArg)
  340.  * \brief  check for validity of decoded addressing mode
  341.  * \param  Mask bit mask of allowed addressing modes
  342.  * \param  pArg original expression
  343.  * \return true if OK
  344.  * ------------------------------------------------------------------------ */
  345.  
  346. static Boolean ChkAdr(Word Mask, const tStrComp *pArg)
  347. {
  348.    CorrMode8(Mask, ModWReg, ModReg);
  349.    CorrMode12(Mask, ModWReg, ModXReg);
  350.    CorrMode8(Mask, ModIWReg, ModIReg);
  351.  
  352.    if ((AdrType != ModNone) && !(Mask & (1 << AdrType)))
  353.    {
  354.      WrStrErrorPos(ErrNum_InvAddrMode, pArg); AdrType = ModNone;
  355.      return False;
  356.    }
  357.    return True;
  358. }
  359.  
  360. /*!------------------------------------------------------------------------
  361.  * \fn     IsWRegAddress(Word Address, Byte *pWorkReg)
  362.  * \brief  check whether data address is accessible as work register
  363.  * \param  Address data address in 8/12 bit data space
  364.  * \param  pWorkReg resulting work register # if yes
  365.  * \param  FirstPassUnknown flag about questionable value
  366.  * \return true if accessible as work register
  367.  * ------------------------------------------------------------------------ */
  368.  
  369. static Boolean ChkInRange(Word Address, Word Base, Word Length, Byte *pOffset)
  370. {
  371.   if ((Address >= Base) && (Address < Base + Length))
  372.   {
  373.     *pOffset = Address - Base;
  374.     return True;
  375.   }
  376.   return False;
  377. }
  378.  
  379. static Boolean IsWRegAddress(Word Address, Byte *pWorkReg)
  380. {
  381.   if (mIsSuper8())
  382.   {
  383.     if ((RP0Val <= 0xff) && ChkInRange(Address, RP0Val & 0xf8, 8, pWorkReg))
  384.       return True;
  385.     if ((RP1Val <= 0xff) && ChkInRange(Address, RP1Val & 0xf8, 8, pWorkReg))
  386.     {
  387.       *pWorkReg += 8;
  388.       return True;
  389.     }
  390.   }
  391.   else if (mIsZ8Encore())
  392.   {
  393.     if ((RPVal <= 0xff) && ChkInRange(Address, (RPVal & 0xf0) | ((RPVal & 0x0f) << 8), 16, pWorkReg))
  394.       return True;
  395.   }
  396.   else
  397.   {
  398.     if ((RPVal <= 0xff) && ChkInRange(Address, RPVal & 0xf0, 16, pWorkReg))
  399.       return True;
  400.   }
  401.   return False;
  402. }
  403.  
  404. /*!------------------------------------------------------------------------
  405.  * \fn     IsRegAddress(Word Address)
  406.  * \brief  check whether data address is accessible via 8-bit address
  407.  * \param  Address data address in 8/12 bit data space
  408.  * \return true if accessible via 8-bit address
  409.  * ------------------------------------------------------------------------ */
  410.  
  411. static Boolean IsRegAddress(Word Address)
  412. {
  413.   /* simple Z8 does not support 12 bit register addresses, so
  414.      always force this to TRUE for it */
  415.  
  416.   if (!(pCurrCPUProps->CoreFlags & eCoreZ8Encore))
  417.     return TRUE;
  418.   return ((RPVal <= 0xff)
  419.        && (Hi(Address) == (RPVal & 15)));
  420. }
  421.  
  422. /*!------------------------------------------------------------------------
  423.  * \fn     DecodeAdr(const tStrComp *pArg, Word Mask)
  424.  * \brief  decode address expression
  425.  * \param  pArg expression in source code
  426.  * \param  Mask bit mask of allowed modes
  427.  * \return True if successfully decoded to an allowed mode
  428.  * ------------------------------------------------------------------------ */
  429.  
  430. int GetForceLen(const char *pArg)
  431. {
  432.   int Result = 0;
  433.  
  434.   while ((Result < 2) && (pArg[Result] == '>'))
  435.     Result++;
  436.   return Result;
  437. }
  438.  
  439. static ShortInt IsWRegWithRP(const tStrComp *pComp, Byte *pResult, Word Mask16Modes, Word Mask8Modes)
  440. {
  441.   tEvalResult EvalResult;
  442.   Word Address;
  443.   tSymbolSize Size;
  444.  
  445.   switch (IsWRegOrWRReg(pComp, pResult, &Size, False))
  446.   {
  447.     case eIsReg:
  448.       return Size;
  449.     case eIsNoReg:
  450.       break;
  451.     case eRegAbort:
  452.       return eSymbolSizeUnknown;
  453.   }
  454.  
  455.   /* It's neither Rn nor RRn.  Since an address by itself has no
  456.      operand size, only one mode may be allowed to keep things
  457.      unambiguous: */
  458.  
  459.   if (Mask16Modes && Mask8Modes)
  460.   {
  461.     WrStrErrorPos(ErrNum_InvReg, pComp);
  462.     return eSymbolSizeUnknown;
  463.   }
  464.  
  465.   Address = EvalStrIntExpressionWithResult(pComp, UInt8, &EvalResult);
  466.   if (!EvalResult.OK)
  467.     return eSymbolSizeUnknown;
  468.   /* if (mFirstPassUnknown(EvalResult.Flags)) ... */
  469.  
  470.   if (Mask16Modes && IsWRegAddress(Address, pResult))
  471.   {
  472.     if (mFirstPassUnknown(EvalResult.Flags)) *pResult &= ~1;
  473.     if (*pResult & 1)
  474.     {
  475.       WrStrErrorPos(ErrNum_AddrMustBeEven, pComp);
  476.       return eSymbolSizeUnknown;
  477.     }
  478.     return eSymbolSize16Bit;
  479.   }
  480.  
  481.   if (Mask8Modes && IsWRegAddress(Address, pResult))
  482.     return eSymbolSize8Bit;
  483.  
  484.   WrStrErrorPos(ErrNum_InvReg, pComp);
  485.   return eSymbolSizeUnknown;
  486. }
  487.  
  488. static Boolean DecodeAdr(const tStrComp *pArg, Word Mask)
  489. {
  490.   Boolean OK;
  491.   tEvalResult EvalResult;
  492.   char  *p;
  493.   int ForceLen, l;
  494.   tSymbolSize Size;
  495.  
  496.   if (!mIsSuper8() && !mIsZ8Encore())
  497.     Mask &= ~MModIndRR;
  498.   if (!mIsSuper8())
  499.     Mask &= ~MModIndRR16;
  500.   if (!mIsZ8Encore())
  501.     Mask &= ~(MModXReg | MModWeird);
  502.  
  503.   AdrType = ModNone;
  504.  
  505.   /* immediate ? */
  506.  
  507.   if (*pArg->str.p_str == '#')
  508.   {
  509.     switch (OpSize)
  510.     {
  511.       case eSymbolSize8Bit:
  512.         AdrVal = EvalStrIntExpressionOffs(pArg, 1, Int8, &OK);
  513.         break;
  514.       case eSymbolSize16Bit:
  515.         AdrWVal = EvalStrIntExpressionOffs(pArg, 1, Int16, &OK);
  516.         break;
  517.       default:
  518.         OK = False;
  519.     }
  520.     if (OK) AdrType = ModImm;
  521.     return ChkAdr(Mask, pArg);
  522.   }
  523.  
  524.   /* Register ? */
  525.  
  526.   switch (IsWRegOrWRReg(pArg, &AdrVal, &Size, False))
  527.   {
  528.     case eIsReg:
  529.       AdrType = (Size == eSymbolSize16Bit) ? ModWRReg : ModWReg;
  530.       return ChkAdr(Mask, pArg);
  531.     case eIsNoReg:
  532.       break;
  533.     case eRegAbort:
  534.       return False;
  535.   }
  536.  
  537.   /* treat absolute address as register? */
  538.  
  539.   if (*pArg->str.p_str == '!')
  540.   {
  541.     AdrWVal = EvalStrIntExpressionOffsWithResult(pArg, 1, UInt16, &EvalResult);
  542.     if (EvalResult.OK)
  543.     {
  544.       if (!mFirstPassUnknown(EvalResult.Flags) && !IsWRegAddress(AdrWVal, &AdrVal))
  545.         WrError(ErrNum_InAccPage);
  546.       AdrType = ModWReg;
  547.       return ChkAdr(Mask, pArg);
  548.     }
  549.     return False;
  550.   }
  551.  
  552.   /* indirekte Konstrukte ? */
  553.  
  554.   if (*pArg->str.p_str == '@')
  555.   {
  556.     tStrComp Comp;
  557.     tRegEvalResult RegEvalResult;
  558.  
  559.     StrCompRefRight(&Comp, pArg, 1);
  560.     if ((strlen(Comp.str.p_str) >= 6) && (!as_strncasecmp(Comp.str.p_str, ".RR", 3)) && (IsIndirect(Comp.str.p_str + 3)))
  561.     {
  562.       AdrVal = EvalStrIntExpressionOffsWithResult(&Comp, 3, Int8, &EvalResult);
  563.       if (EvalResult.OK)
  564.       {
  565.         AdrType = ModWeird;
  566.         ChkSpace(SegData, EvalResult.AddrSpaceMask);
  567.       }
  568.     }
  569.     else if ((RegEvalResult = IsWRegOrWRReg(&Comp, &AdrVal, &Size, False)) != eIsNoReg)
  570.     {
  571.       if (RegEvalResult == eRegAbort)
  572.         return False;
  573.       AdrType = (Size == eSymbolSize16Bit) ? ModIWRReg : ModIWReg;
  574.     }
  575.     else
  576.     {
  577.       /* Trying to do a working register optimization at this place is
  578.          extremely tricky since an expression like @<address> has no
  579.          inherent operand size (8/16 bit).  So the optimization IRR->Irr
  580.          will only be allowed if IR is not allowed, or Irr is the only
  581.          mode allowed: */
  582.  
  583.       Word ModeMask = Mask & (MModIRReg | MModIWRReg | MModIReg | MModIWReg);
  584.  
  585.       if (ModeMask == (MModIWReg | MModIWRReg))
  586.       {
  587.         WrStrErrorPos(ErrNum_UndefRegSize, &Comp);
  588.         return False;
  589.       }
  590.  
  591.       AdrWVal = EvalStrIntExpressionOffsWithResult(&Comp, ForceLen = GetForceLen(pArg->str.p_str), Int8, &EvalResult);
  592.       if (EvalResult.OK)
  593.       {
  594.         ChkSpace(SegData, EvalResult.AddrSpaceMask);
  595.         if (!(ModeMask & MModIReg) || (ModeMask == MModIWRReg))
  596.         {
  597.           if (mFirstPassUnknown(EvalResult.Flags)) AdrWVal &= ~1;
  598.           if (AdrWVal & 1) WrStrErrorPos(ErrNum_AddrMustBeEven, &Comp);
  599.           else if ((Mask & MModIWRReg) && (ForceLen <= 0) && IsWRegAddress(AdrWVal, &AdrVal))
  600.             AdrType = ModIWRReg;
  601.           else
  602.           {
  603.             AdrVal = AdrWVal;
  604.             AdrType = ModIRReg;
  605.           }
  606.         }
  607.         else
  608.         {
  609.           if ((Mask & MModIWReg) && (ForceLen <= 0) && IsWRegAddress(AdrWVal, &AdrVal))
  610.             AdrType = ModIWReg;
  611.           else
  612.           {
  613.             AdrVal = AdrWVal;
  614.             AdrType = ModIReg;
  615.           }
  616.         }
  617.       }
  618.     }
  619.     return ChkAdr(Mask, pArg);
  620.   }
  621.  
  622.   /* indiziert ? */
  623.  
  624.   l = strlen(pArg->str.p_str);
  625.   if ((l > 4) && (pArg->str.p_str[l - 1] == ')'))
  626.   {
  627.     tStrComp Left, Right;
  628.  
  629.     StrCompRefRight(&Right, pArg, 0);
  630.     StrCompShorten(&Right, 1);
  631.     p = RQuotPos(pArg->str.p_str, '(');
  632.     if (!p)
  633.     {
  634.       WrStrErrorPos(ErrNum_BrackErr, pArg);
  635.       return False;
  636.     }
  637.     StrCompSplitRef(&Left, &Right, &Right, p);
  638.  
  639.     switch (IsWRegWithRP(&Right, &AdrVal, Mask & (MModIndRR | MModIndRR16), Mask & MModInd))
  640.     {
  641.       case eSymbolSize8Bit:
  642.         /* We are operating on a single base register and therefore in a 8-bit address space.
  643.            So we may allow both a signed or unsigned displacements since addresses will wrap
  644.            around anyway: */
  645.  
  646.         AdrIndex = EvalStrIntExpressionWithResult(&Left, Int8, &EvalResult);
  647.         if (EvalResult.OK)
  648.         {
  649.           AdrType = ModInd; ChkSpace(SegData, EvalResult.AddrSpaceMask);
  650.         }
  651.         return ChkAdr(Mask, pArg);
  652.  
  653.       case eSymbolSize16Bit:
  654.         /* 16 bit index only allowed if index register is not zero */
  655.         AdrIndex = EvalStrIntExpressionWithResult(&Left, ((Mask & MModIndRR16) && (AdrVal != 0)) ? Int16 : SInt8, &EvalResult);
  656.         if (EvalResult.OK)
  657.         {
  658.           if ((Mask & MModIndRR) && RangeCheck(AdrIndex, SInt8))
  659.             AdrType = ModIndRR;
  660.           else
  661.             AdrType = ModIndRR16;
  662.           /* TODO: differentiate LDC/LDE */
  663.           ChkSpace(SegData, EvalResult.AddrSpaceMask);
  664.         }
  665.         return ChkAdr(Mask, pArg);
  666.  
  667.       default:
  668.         return False;
  669.     }
  670.   }
  671.  
  672.   /* simple direct address ? */
  673.  
  674.   AdrWVal = EvalStrIntExpressionOffsWithResult(pArg, ForceLen = GetForceLen(pArg->str.p_str),
  675.                                       (Mask & MModDA) ? UInt16 : RegSpaceType, &EvalResult);
  676.   if (EvalResult.OK)
  677.   {
  678.     if (Mask & MModDA)
  679.     {
  680.       AdrType = ModDA;
  681.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  682.     }
  683.     else
  684.     {
  685.       if (mFirstPassUnknown(EvalResult.Flags) && !(Mask & ModXReg))
  686.         AdrWVal = Lo(AdrWVal) | ((RPVal & 15) << 8);
  687.       if (IsWRegAddress(AdrWVal, &AdrVal) && (Mask & MModWReg) && (ForceLen <= 0))
  688.       {
  689.         AdrType = ModWReg;
  690.       }
  691.       else if (IsRegAddress(AdrWVal) && (Mask & (MModReg | MModRReg)) && (ForceLen <= 1))
  692.       {
  693.         if (Mask & MModRReg)
  694.         {
  695.           if (mFirstPassUnknown(EvalResult.Flags))
  696.             AdrWVal &= ~1;
  697.           if (AdrWVal & 1)
  698.           {
  699.             WrStrErrorPos(ErrNum_AddrMustBeEven, pArg);
  700.             return False;
  701.           }
  702.           AdrType = ModRReg;
  703.         }
  704.         else
  705.           AdrType = ModReg;
  706.         AdrVal = Lo(AdrWVal);
  707.       }
  708.       else
  709.         AdrType = ModXReg;
  710.       ChkSpace(SegData, EvalResult.AddrSpaceMask);
  711.     }
  712.     return ChkAdr(Mask, pArg);
  713.   }
  714.   else
  715.     return False;
  716. }
  717.  
  718. static int DecodeCond(const tStrComp *pArg)
  719. {
  720.   int z;
  721.  
  722.   NLS_UpString(pArg->str.p_str);
  723.   for (z = 0; z < CondCnt; z++)
  724.     if (strcmp(Conditions[z].Name, pArg->str.p_str) == 0)
  725.       break;
  726.  
  727.   if (z >= CondCnt)
  728.     WrStrErrorPos(ErrNum_UndefCond, pArg);
  729.  
  730.   return z;
  731. }
  732.  
  733. static Boolean ChkCoreFlags(tCoreFlags CoreFlags)
  734. {
  735.   if (pCurrCPUProps->CoreFlags & CoreFlags)
  736.     return True;
  737.   WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  738.   return False;
  739. }
  740.  
  741. /*--------------------------------------------------------------------------*/
  742. /* Bit Symbol Handling */
  743.  
  744. /*
  745.  * Compact representation of bits and bit fields in symbol table:
  746.  * bits 0..2: (start) bit position
  747.  * bits 3...10/14: register address in SFR space (256B/4KB)
  748.  */
  749.  
  750. /*!------------------------------------------------------------------------
  751.  * \fn     EvalBitPosition(const char *pBitArg, Boolean *pOK, ShortInt OpSize)
  752.  * \brief  evaluate constant bit position, with bit range depending on operand size
  753.  * \param  pBitArg bit position argument
  754.  * \param  pOK returns True if OK
  755.  * \param  OpSize operand size (0 -> 8 bits)
  756.  * \return bit position as number
  757.  * ------------------------------------------------------------------------ */
  758.  
  759. static Byte EvalBitPosition(const tStrComp *pBitArg, Boolean *pOK, ShortInt OpSize)
  760. {
  761.   switch (OpSize)
  762.   {
  763.     case eSymbolSize8Bit:
  764.       return EvalStrIntExpressionOffs(pBitArg, !!(*pBitArg->str.p_str == '#'), UInt3, pOK);
  765.     default:
  766.       WrStrErrorPos(ErrNum_InvOpSize, pBitArg);
  767.       *pOK = False;
  768.       return 0;
  769.   }
  770. }
  771.  
  772. /*!------------------------------------------------------------------------
  773.  * \fn     AssembleBitSymbol(Byte BitPos, ShortInt OpSize, Word Address)
  774.  * \brief  build the compact internal representation of a bit field symbol
  775.  * \param  BitPos bit position in word
  776.  * \param  Width width of bit field
  777.  * \param  OpSize operand size (0..2)
  778.  * \param  Address register address
  779.  * \return compact representation
  780.  * ------------------------------------------------------------------------ */
  781.  
  782. static LongWord AssembleBitSymbol(Byte BitPos, ShortInt OpSize, Word Address)
  783. {
  784.   UNUSED(OpSize);
  785.   return BitPos
  786.        | (((LongWord)Address & 0xfff) << 3);
  787. }
  788.  
  789. /*!------------------------------------------------------------------------
  790.  * \fn     DecodeBitArg2(LongWord *pResult, const tStrComp *pRegArg, const tStrComp *pBitArg, ShortInt OpSize)
  791.  * \brief  encode a bit symbol, address & bit position separated
  792.  * \param  pResult resulting encoded bit
  793.  * \param  pRegArg register argument
  794.  * \param  pBitArg bit argument
  795.  * \param  OpSize register size (0 = 8 bit)
  796.  * \return True if success
  797.  * ------------------------------------------------------------------------ */
  798.  
  799. static Boolean DecodeBitArg2(LongWord *pResult, const tStrComp *pRegArg, const tStrComp *pBitArg, ShortInt OpSize)
  800. {
  801.   Boolean OK;
  802.   LongWord Addr;
  803.   Byte BitPos;
  804.  
  805.   BitPos = EvalBitPosition(pBitArg, &OK, OpSize);
  806.   if (!OK)
  807.     return False;
  808.  
  809.   /* all I/O registers reside in the first 256/4K byte of the address space */
  810.  
  811.   DecodeAdr(pRegArg, MModWReg | (mIsZ8Encore() ? MModXReg : MModReg));
  812.   switch (AdrType)
  813.   {
  814.     case ModXReg:
  815.       Addr = AdrWVal;
  816.       break;
  817.     case ModWReg:
  818.       Addr = AdrVal + pCurrCPUProps->WorkOfs;
  819.       break;
  820.     case ModReg:
  821.       Addr = AdrVal;
  822.       break;
  823.     default:
  824.       return False;
  825.   }
  826.  
  827.   *pResult = AssembleBitSymbol(BitPos, OpSize, Addr);
  828.  
  829.   return True;
  830. }
  831.  
  832. /*!------------------------------------------------------------------------
  833.  * \fn     DecodeBitArg(LongWord *pResult, int Start, int Stop, ShortInt OpSize)
  834.  * \brief  encode a bit symbol from instruction argument(s)
  835.  * \param  pResult resulting encoded bit
  836.  * \param  Start first argument
  837.  * \param  Stop last argument
  838.  * \param  OpSize register size (0 = 8 bit)
  839.  * \return True if success
  840.  * ------------------------------------------------------------------------ */
  841.  
  842. static Boolean DecodeBitArg(LongWord *pResult, int Start, int Stop, ShortInt OpSize)
  843. {
  844.   *pResult = 0;
  845.  
  846.   /* Just one argument -> parse as bit argument */
  847.  
  848.   if (Start == Stop)
  849.   {
  850.     tEvalResult EvalResult;
  851.  
  852.     *pResult = EvalStrIntExpressionWithResult(&ArgStr[Start],
  853.                                     mIsZ8Encore() ? UInt15 : UInt11,
  854.                                     &EvalResult);
  855.     if (EvalResult.OK)
  856.       ChkSpace(SegBData, EvalResult.AddrSpaceMask);
  857.     return EvalResult.OK;
  858.   }
  859.  
  860.   /* register & bit position are given as separate arguments */
  861.  
  862.   else if (Stop == Start + 1)
  863.     return DecodeBitArg2(pResult, &ArgStr[Start], &ArgStr[Stop], OpSize);
  864.  
  865.   /* other # of arguments not allowed */
  866.  
  867.   else
  868.   {
  869.     WrError(ErrNum_WrongArgCnt);
  870.     return False;
  871.   }
  872. }
  873.  
  874. /*!------------------------------------------------------------------------
  875.  * \fn     ExpandZ8Bit(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
  876.  * \brief  expands bit definition when a structure is instantiated
  877.  * \param  pVarName desired symbol name
  878.  * \param  pStructElem element definition
  879.  * \param  Base base address of instantiated structure
  880.  * ------------------------------------------------------------------------ */
  881.  
  882. static void ExpandZ8Bit(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
  883. {
  884.   LongWord Address = Base + pStructElem->Offset;
  885.  
  886.   if (pInnermostNamedStruct)
  887.   {
  888.     PStructElem pElem = CloneStructElem(pVarName, pStructElem);
  889.  
  890.     if (!pElem)
  891.       return;
  892.     pElem->Offset = Address;
  893.     AddStructElem(pInnermostNamedStruct->StructRec, pElem);
  894.   }
  895.   else
  896.   {
  897.     if (!ChkRange(Address, 0, 0x7ff)
  898.      || !ChkRange(pStructElem->BitPos, 0, 7))
  899.       return;
  900.  
  901.     PushLocHandle(-1);
  902.     EnterIntSymbol(pVarName, AssembleBitSymbol(pStructElem->BitPos, eSymbolSize8Bit, Address), SegBData, False);
  903.     PopLocHandle();
  904.     /* TODO: MakeUseList? */
  905.   }
  906. }
  907.  
  908. /*!------------------------------------------------------------------------
  909.  * \fn     DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos, ShortInt *pOpSize)
  910.  * \brief  transform compact represenation of bit (field) symbol into components
  911.  * \param  BitSymbol compact storage
  912.  * \param  pAddress (I/O) register address
  913.  * \param  pBitPos (start) bit position
  914.  * \param  pWidth pWidth width of bit field, always one for individual bit
  915.  * \param  pOpSize returns register size (0 for 8 bits)
  916.  * \return constant True
  917.  * ------------------------------------------------------------------------ */
  918.  
  919. static Boolean DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos, ShortInt *pOpSize)
  920. {
  921.   *pAddress = (BitSymbol >> 3) & 0xfff;
  922.   *pBitPos = BitSymbol & 7;
  923.   *pOpSize = eSymbolSize8Bit;
  924.   return True;
  925. }
  926.  
  927. /*!------------------------------------------------------------------------
  928.  * \fn     DecodeWRBitArg(int StartArg, int EndArg, Byte *pResult)
  929.  * \brief  decode bit argument in working register
  930.  * \param  StartArg 1st argument
  931.  * \param  EndArg last argument
  932.  * \param  pResult resulting encoded bit
  933.  * \return TRUE if successfully decoded
  934.  * ------------------------------------------------------------------------ */
  935.  
  936. static Boolean DecodeWRBitArg(int StartArg, int EndArg, Byte *pResult)
  937. {
  938.   LongWord Result;
  939.   Word Address;
  940.   Byte BitPos;
  941.   ShortInt OpSize;
  942.  
  943.   if (!DecodeBitArg(&Result, StartArg, EndArg, eSymbolSize8Bit))
  944.     return False;
  945.   (void)DissectBitSymbol(Result, &Address, &BitPos, &OpSize);
  946.   if ((Address < pCurrCPUProps->WorkOfs) || (Address >= pCurrCPUProps->WorkOfs + 16))
  947.   {
  948.     WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[StartArg]);
  949.     return False;
  950.   }
  951.   *pResult = ((Address & 15) << 3) | BitPos;
  952.   return True;
  953. }
  954.  
  955. /*!------------------------------------------------------------------------
  956.  * \fn     DissectBit_Z8(char *pDest, size_t DestSize, LargeWord Inp)
  957.  * \brief  dissect compact storage of bit (field) into readable form for listing
  958.  * \param  pDest destination for ASCII representation
  959.  * \param  DestSize destination buffer size
  960.  * \param  Inp compact storage
  961.  * ------------------------------------------------------------------------ */
  962.  
  963. static void DissectBit_Z8(char *pDest, size_t DestSize, LargeWord Inp)
  964. {
  965.   Byte BitPos;
  966.   Word Address;
  967.   ShortInt OpSize;
  968.  
  969.   DissectBitSymbol(Inp, &Address, &BitPos, &OpSize);
  970.   UNUSED(OpSize);
  971.  
  972.   UNUSED(DestSize);
  973.   if ((Address >= pCurrCPUProps->WorkOfs) && (Address <= pCurrCPUProps->WorkOfs + 15))
  974.     as_snprintf(pDest, DestSize, "%c%u", HexStartCharacter + ('r' - 'a'), (unsigned)(Address & 15));
  975.   else
  976.     SysString(pDest, DestSize, Address, ListRadixBase,
  977.               mIsZ8Encore() ? 3 : 2, (16 == ListRadixBase) && (IntConstMode == eIntConstModeIntel),
  978.               HexStartCharacter, SplitByteCharacter);
  979.   as_snprcatf(pDest, DestSize, ".%u", (unsigned)BitPos);
  980. }
  981.  
  982. /*--------------------------------------------------------------------------*/
  983. /* Instruction Decoders */
  984.  
  985. static void DecodeFixed(Word Index)
  986. {
  987.   BaseOrder *pOrder = FixedOrders + Index;
  988.  
  989.   if (ChkArgCnt(0, 0)
  990.    && ChkCoreFlags(pOrder->CoreFlags))
  991.   {
  992.     CodeLen = 1;
  993.     BAsmCode[0] = pOrder->Code;
  994.   }
  995. }
  996.  
  997. static void DecodeALU2(Word Index)
  998. {
  999.   BaseOrder *pOrder = ALU2Orders + Index;
  1000.   Byte Save;
  1001.   int l = 0;
  1002.  
  1003.   if (ChkArgCnt(2, 2)
  1004.    && ChkCoreFlags(pOrder->CoreFlags))
  1005.   {
  1006.     if (Hi(pOrder->Code))
  1007.       BAsmCode[l++] = Hi(pOrder->Code);
  1008.     DecodeAdr(&ArgStr[1], MModReg | MModWReg | ((pCurrCPUProps->CoreFlags & eCoreSuper8) ? 0 : MModIReg));
  1009.     switch (AdrType)
  1010.     {
  1011.       case ModReg:
  1012.        Save = AdrVal;
  1013.        DecodeAdr(&ArgStr[2], MModReg | MModIReg | MModImm);
  1014.        switch (AdrType)
  1015.        {
  1016.          case ModReg:
  1017.           BAsmCode[l++] = pOrder->Code + 4;
  1018.           BAsmCode[l++] = AdrVal;
  1019.           BAsmCode[l++] = Save;
  1020.           CodeLen = l;
  1021.           break;
  1022.          case ModIReg:
  1023.           BAsmCode[l++] = pOrder->Code + 5;
  1024.           BAsmCode[l++] = AdrVal;
  1025.           BAsmCode[l++] = Save;
  1026.           CodeLen = l;
  1027.           break;
  1028.          case ModImm:
  1029.           BAsmCode[l++] = pOrder->Code + 6;
  1030.           BAsmCode[l++] = Save;
  1031.           BAsmCode[l++] = AdrVal;
  1032.           CodeLen = l;
  1033.           break;
  1034.        }
  1035.        break;
  1036.       case ModWReg:
  1037.        Save = AdrVal;
  1038.        DecodeAdr(&ArgStr[2], MModWReg| MModReg | MModIWReg | MModIReg | MModImm);
  1039.        switch (AdrType)
  1040.        {
  1041.          case ModWReg:
  1042.           BAsmCode[l++] = pOrder->Code + 2;
  1043.           BAsmCode[l++] = (Save << 4) + AdrVal;
  1044.           CodeLen = l;
  1045.           break;
  1046.          case ModReg:
  1047.           BAsmCode[l++] = pOrder->Code + 4;
  1048.           BAsmCode[l++] = AdrVal;
  1049.           BAsmCode[l++] = pCurrCPUProps->WorkOfs + Save;
  1050.           CodeLen = l;
  1051.           break;
  1052.          case ModIWReg:
  1053.           BAsmCode[l++] = pOrder->Code + 3;
  1054.           BAsmCode[l++] = (Save << 4) + AdrVal;
  1055.           CodeLen = l;
  1056.           break;
  1057.          case ModIReg:
  1058.           BAsmCode[l++] = pOrder->Code + 5;
  1059.           BAsmCode[l++] = AdrVal;
  1060.           BAsmCode[l++] = pCurrCPUProps->WorkOfs + Save;
  1061.           CodeLen = l;
  1062.           break;
  1063.          case ModImm:
  1064.           BAsmCode[l++] = pOrder->Code + 6;
  1065.           BAsmCode[l++] = Save + pCurrCPUProps->WorkOfs;
  1066.           BAsmCode[l++] = AdrVal;
  1067.           CodeLen = l;
  1068.           break;
  1069.        }
  1070.        break;
  1071.       case ModIReg:
  1072.        Save = AdrVal;
  1073.        if (DecodeAdr(&ArgStr[2], MModImm))
  1074.        {
  1075.          BAsmCode[l++] = pOrder->Code + 7;
  1076.          BAsmCode[l++] = Save;
  1077.          BAsmCode[l++] = AdrVal;
  1078.          CodeLen = l;
  1079.        }
  1080.        break;
  1081.     }
  1082.   }
  1083. }
  1084.  
  1085. static void DecodeALUX(Word Index)
  1086. {
  1087.   BaseOrder *pOrder = ALUXOrders + Index;
  1088.   int l = 0;
  1089.  
  1090.   if (ChkArgCnt(2, 2)
  1091.    && ChkCoreFlags(pOrder->CoreFlags))
  1092.   {
  1093.     if (Hi(pOrder->Code))
  1094.       BAsmCode[l++] = Hi(pOrder->Code);
  1095.     if (DecodeAdr(&ArgStr[1], MModXReg))
  1096.     {
  1097.       BAsmCode[l + 3] = Lo(AdrWVal);
  1098.       BAsmCode[l + 2] = Hi(AdrWVal) & 15;
  1099.       DecodeAdr(&ArgStr[2], MModXReg | MModImm);
  1100.       switch (AdrType)
  1101.       {
  1102.         case ModXReg:
  1103.           BAsmCode[l + 0] = pOrder->Code;
  1104.           BAsmCode[l + 1] = AdrWVal >> 4;
  1105.           BAsmCode[l + 2] |= (AdrWVal & 15) << 4;
  1106.           CodeLen = l + 4;
  1107.           break;
  1108.         case ModImm:
  1109.           BAsmCode[l + 0] = pOrder->Code + 1;
  1110.           BAsmCode[l + 1] = AdrVal;
  1111.           CodeLen = l + 4;
  1112.           break;
  1113.       }
  1114.     }
  1115.   }
  1116. }
  1117.  
  1118. static void DecodeALU1(Word Index)
  1119. {
  1120.   ALU1Order *pOrder = ALU1Orders + Index;
  1121.   int l = 0;
  1122.  
  1123.   if (ChkArgCnt(1, 1)
  1124.    && ChkCoreFlags(pOrder->CoreFlags))
  1125.   {
  1126.     if (Hi(pOrder->Code))
  1127.       BAsmCode[l++] = Hi(pOrder->Code);
  1128.     DecodeAdr(&ArgStr[1], (pOrder->Is16 ? (MModWRReg | MModRReg) : MModReg) | MModIReg);
  1129.     switch (AdrType)
  1130.     {
  1131.       case ModReg:
  1132.       case ModRReg:
  1133.        BAsmCode[l++] = pOrder->Code;
  1134.        BAsmCode[l++] = AdrVal;
  1135.        CodeLen = l;
  1136.        break;
  1137.       case ModWRReg:
  1138.        BAsmCode[l++] = pOrder->Code;
  1139.        BAsmCode[l++] = pCurrCPUProps->WorkOfs + AdrVal;
  1140.        CodeLen = l;
  1141.        break;
  1142.       case ModIReg:
  1143.        BAsmCode[l++] = pOrder->Code + 1;
  1144.        BAsmCode[l++] = AdrVal;
  1145.        CodeLen = l;
  1146.        break;
  1147.     }
  1148.   }
  1149. }
  1150.  
  1151. static void DecodeLD(Word Index)
  1152. {
  1153.   Word Save;
  1154.  
  1155.   UNUSED(Index);
  1156.  
  1157.   if (ChkArgCnt(2, 2)
  1158.    && ChkCoreFlags(eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore))
  1159.   {
  1160.     DecodeAdr(&ArgStr[1], MModReg | MModWReg | MModIReg | MModIWReg | MModInd);
  1161.     switch (AdrType)
  1162.     {
  1163.       case ModReg:
  1164.         Save = AdrVal;
  1165.         DecodeAdr(&ArgStr[2], MModReg | MModWReg | MModIReg | MModImm);
  1166.         switch (AdrType)
  1167.         {
  1168.          case ModReg: /* Super8 OK */
  1169.            BAsmCode[0] = 0xe4;
  1170.            BAsmCode[1] = AdrVal;
  1171.            BAsmCode[2] = Save;
  1172.            CodeLen = 3;
  1173.            break;
  1174.          case ModWReg:
  1175.            if (pCurrCPUProps->CoreFlags & eCoreZ8Encore)
  1176.            {
  1177.              BAsmCode[0] = 0xe4;
  1178.              BAsmCode[1] = AdrVal + pCurrCPUProps->WorkOfs;
  1179.              BAsmCode[2] = Save;
  1180.              CodeLen = 3;
  1181.            }
  1182.            else /** non-eZ8 **/ /* Super8 OK */
  1183.            {
  1184.              BAsmCode[0] = (AdrVal << 4) + 9;
  1185.              BAsmCode[1] = Save;
  1186.              CodeLen = 2;
  1187.            }
  1188.            break;
  1189.          case ModIReg: /* Super8 OK */
  1190.            BAsmCode[0] = 0xe5;
  1191.            BAsmCode[1] = AdrVal;
  1192.            BAsmCode[2] = Save;
  1193.            CodeLen = 3;
  1194.            break;
  1195.          case ModImm: /* Super8 OK */
  1196.            BAsmCode[0] = 0xe6;
  1197.            BAsmCode[1] = Save;
  1198.            BAsmCode[2] = AdrVal;
  1199.            CodeLen = 3;
  1200.            break;
  1201.         }
  1202.         break;
  1203.       case ModWReg:
  1204.         Save = AdrVal;
  1205.         DecodeAdr(&ArgStr[2], MModWReg | MModReg | MModIWReg | MModIReg | MModImm | MModInd);
  1206.         switch (AdrType)
  1207.         {
  1208.           case ModWReg:
  1209.             if (pCurrCPUProps->CoreFlags & eCoreZ8Encore)
  1210.             {
  1211.               BAsmCode[0] = 0xe4;
  1212.               BAsmCode[1] = AdrVal + pCurrCPUProps->WorkOfs;
  1213.               BAsmCode[2] = Save + pCurrCPUProps->WorkOfs;
  1214.               CodeLen = 3;
  1215.             }
  1216.             else /** non-eZ8 */ /* Super8 OK */
  1217.             {
  1218.               BAsmCode[0] = (Save << 4) + 8;
  1219.               BAsmCode[1] = AdrVal + pCurrCPUProps->WorkOfs;
  1220.               CodeLen = 2;
  1221.             }
  1222.             break;
  1223.           case ModReg:
  1224.             if (pCurrCPUProps->CoreFlags & eCoreZ8Encore)
  1225.             {
  1226.               BAsmCode[0] = 0xe4;
  1227.               BAsmCode[1] = AdrVal;
  1228.               BAsmCode[2] = Save + pCurrCPUProps->WorkOfs;
  1229.               CodeLen = 3;
  1230.             }
  1231.             else /** non-eZ8 **/ /* Super8 OK */
  1232.             {
  1233.               BAsmCode[0] = (Save << 4) + 8;
  1234.               BAsmCode[1] = AdrVal;
  1235.               CodeLen = 2;
  1236.             }
  1237.             break;
  1238.           case ModIWReg:
  1239.             /* is C7 r,IR or r,ir? */
  1240.             BAsmCode[0] = (pCurrCPUProps->CoreFlags & eCoreSuper8) ? 0xc7 : 0xe3;
  1241.             BAsmCode[1] = (Save << 4) + AdrVal;
  1242.             CodeLen = 2;
  1243.             break;
  1244.           case ModIReg: /* Super8 OK */
  1245.             BAsmCode[0] = 0xe5;
  1246.             BAsmCode[1] = AdrVal;
  1247.             BAsmCode[2] = pCurrCPUProps->WorkOfs + Save;
  1248.             CodeLen = 3;
  1249.             break;
  1250.           case ModImm: /* Super8 OK */
  1251.             BAsmCode[0] = (Save << 4) + 12;
  1252.             BAsmCode[1] = AdrVal;
  1253.             CodeLen = 2;
  1254.             break;
  1255.           case ModInd:
  1256.             BAsmCode[0] = (pCurrCPUProps->CoreFlags & eCoreSuper8) ? 0x87 : 0xc7;
  1257.             BAsmCode[1] = (Save << 4) + AdrVal;
  1258.             BAsmCode[2] = AdrIndex;
  1259.             CodeLen = 3;
  1260.             break;
  1261.         }
  1262.         break;
  1263.       case ModIReg:
  1264.         Save = AdrVal;
  1265.         DecodeAdr(&ArgStr[2], MModReg | MModImm);
  1266.         switch (AdrType)
  1267.         {
  1268.           case ModReg: /* Super8 OK */
  1269.             BAsmCode[0] = 0xf5;
  1270.             BAsmCode[1] = AdrVal;
  1271.             BAsmCode[2] = Save;
  1272.             CodeLen = 3;
  1273.             break;
  1274.           case ModImm:
  1275.             BAsmCode[0] = (pCurrCPUProps->CoreFlags & eCoreSuper8) ? 0xd6 : 0xe7;
  1276.             BAsmCode[1] = Save;
  1277.             BAsmCode[2] = AdrVal;
  1278.             CodeLen = 3;
  1279.             break;
  1280.         }
  1281.         break;
  1282.       case ModIWReg:
  1283.         Save = AdrVal;
  1284.         DecodeAdr(&ArgStr[2], MModWReg | MModReg | MModImm);
  1285.         switch (AdrType)
  1286.         {
  1287.           case ModWReg:
  1288.             BAsmCode[0] = (pCurrCPUProps->CoreFlags & eCoreSuper8) ? 0xd7 : 0xf3;
  1289.             BAsmCode[1] = (Save << 4) + AdrVal;
  1290.             CodeLen = 2;
  1291.             break;
  1292.           case ModReg: /* Super8 OK */
  1293.             BAsmCode[0] = 0xf5;
  1294.             BAsmCode[1] = AdrVal;
  1295.             BAsmCode[2] = pCurrCPUProps->WorkOfs + Save;
  1296.             CodeLen = 3;
  1297.             break;
  1298.           case ModImm:
  1299.             BAsmCode[0] = (pCurrCPUProps->CoreFlags & eCoreSuper8) ? 0xd6 : 0xe7;
  1300.             BAsmCode[1] = pCurrCPUProps->WorkOfs + Save;
  1301.             BAsmCode[2] = AdrVal;
  1302.             CodeLen = 3;
  1303.             break;
  1304.         }
  1305.         break;
  1306.       case ModInd:
  1307.         Save = AdrVal;
  1308.         if (DecodeAdr(&ArgStr[2], MModWReg))
  1309.         {
  1310.           BAsmCode[0] = (pCurrCPUProps->CoreFlags & eCoreSuper8) ? 0x97 : 0xd7;
  1311.           BAsmCode[1] = (AdrVal << 4) + Save;
  1312.           BAsmCode[2] = AdrIndex;
  1313.           CodeLen = 3;
  1314.         }
  1315.         break;
  1316.     }
  1317.   }
  1318. }
  1319.  
  1320. static void DecodeLDCE(Word Code)
  1321. {
  1322.   Byte Save, Super8Add = mIsSuper8() && !!(Code == 0x82);
  1323.  
  1324.   if (ChkArgCnt(2, 2)
  1325.    && ChkCoreFlags(eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore))
  1326.   {
  1327.     LongWord DestMask = MModWReg | MModIWRReg, SrcMask;
  1328.  
  1329.     if ((pCurrCPUProps->CoreFlags & eCoreZ8Encore) && (Code == 0xc2))
  1330.       DestMask |= MModIWReg;
  1331.     if (mIsSuper8())
  1332.       DestMask |= MModIndRR | MModIndRR16 | MModDA;
  1333.     DecodeAdr(&ArgStr[1], DestMask);
  1334.     switch (AdrType)
  1335.     {
  1336.       case ModWReg:
  1337.         SrcMask = MModIWRReg;
  1338.         if (pCurrCPUProps->CoreFlags & eCoreSuper8)
  1339.           SrcMask |= MModIndRR | MModIndRR16 | MModDA;
  1340.         Save = AdrVal; DecodeAdr(&ArgStr[2], SrcMask);
  1341.         switch (AdrType)
  1342.         {
  1343.           case ModIWRReg:
  1344.             BAsmCode[0] = mIsSuper8() ? 0xc3 : Code;
  1345.             BAsmCode[1] = (Save << 4) | AdrVal | Super8Add;
  1346.             CodeLen = 2;
  1347.             break;
  1348.           case ModDA:
  1349.             BAsmCode[0] = 0xa7;
  1350.             BAsmCode[1] = (Save << 4) | Super8Add;
  1351.             BAsmCode[2] = Lo(AdrWVal);
  1352.             BAsmCode[3] = Hi(AdrWVal);
  1353.             CodeLen = 4;
  1354.             break;
  1355.           case ModIndRR:
  1356.             BAsmCode[0] = 0xe7;
  1357.             BAsmCode[1] = (Save << 4) | AdrVal | Super8Add;
  1358.             BAsmCode[2] = Lo(AdrIndex);
  1359.             CodeLen = 3;
  1360.             break;
  1361.           case ModIndRR16:
  1362.             BAsmCode[0] = 0xa7;
  1363.             BAsmCode[1] = (Save << 4) | AdrVal | Super8Add;
  1364.             BAsmCode[2] = Lo(AdrIndex);
  1365.             BAsmCode[3] = Hi(AdrIndex);
  1366.             CodeLen = 4;
  1367.             break;
  1368.         }
  1369.         break;
  1370.       case ModIWReg:
  1371.         Save = AdrVal; DecodeAdr(&ArgStr[2], MModIWRReg);
  1372.         if (AdrType != ModNone)
  1373.         {
  1374.           BAsmCode[0] = 0xc5;
  1375.           BAsmCode[1] = (Save << 4) | AdrVal;
  1376.           CodeLen = 2;
  1377.         }
  1378.         break;
  1379.       case ModIWRReg:
  1380.         Save = AdrVal; DecodeAdr(&ArgStr[2], MModWReg);
  1381.         if (AdrType != ModNone)
  1382.         {
  1383.           BAsmCode[0] = mIsSuper8() ? 0xd3 : Code + 0x10;
  1384.           BAsmCode[1] = (AdrVal << 4) | Save | Super8Add;
  1385.           CodeLen = 2;
  1386.         }
  1387.         break;
  1388.       case ModDA: /* Super8 only */
  1389.         BAsmCode[2] = Lo(AdrWVal);
  1390.         BAsmCode[3] = Hi(AdrWVal);
  1391.         DecodeAdr(&ArgStr[2], MModWReg);
  1392.         if (AdrType != ModNone)
  1393.         {
  1394.           BAsmCode[0] = 0xb7;
  1395.           BAsmCode[1] = (AdrVal << 4) | Super8Add;
  1396.           CodeLen = 4;
  1397.         }
  1398.         break;
  1399.       case ModIndRR: /* Super8 only */
  1400.         BAsmCode[2] = Lo(AdrIndex);
  1401.         Save = AdrVal;
  1402.         DecodeAdr(&ArgStr[2], MModWReg);
  1403.         if (AdrType != ModNone)
  1404.         {
  1405.           BAsmCode[0] = 0xf7;
  1406.           BAsmCode[1] = (AdrVal << 4) | Save | Super8Add;
  1407.           CodeLen = 3;
  1408.         }
  1409.         break;
  1410.       case ModIndRR16: /* Super8 only */
  1411.         BAsmCode[2] = Lo(AdrIndex);
  1412.         BAsmCode[3] = Hi(AdrIndex);
  1413.         Save = AdrVal;
  1414.         DecodeAdr(&ArgStr[2], MModWReg);
  1415.         if (AdrType != ModNone)
  1416.         {
  1417.           BAsmCode[0] = 0xb7;
  1418.           BAsmCode[1] = (AdrVal << 4) | Save | Super8Add;
  1419.           CodeLen = 4;
  1420.         }
  1421.         break;
  1422.     }
  1423.   }
  1424. }
  1425.  
  1426. static void DecodeLDCEI(Word Index)
  1427. {
  1428.   Byte Save;
  1429.  
  1430.   if (ChkArgCnt(2, 2)
  1431.    && ChkCoreFlags(eCoreZ8NMOS | eCoreZ8CMOS | eCoreZ8Encore))
  1432.   {
  1433.     DecodeAdr(&ArgStr[1], MModIWReg | MModIWRReg);
  1434.     switch (AdrType)
  1435.     {
  1436.       case ModIWReg:
  1437.         Save = AdrVal; DecodeAdr(&ArgStr[2], MModIWRReg);
  1438.         if (AdrType != ModNone)
  1439.         {
  1440.           BAsmCode[0] = Index;
  1441.           BAsmCode[1] = (Save << 4) + AdrVal;
  1442.           CodeLen = 2;
  1443.         }
  1444.         break;
  1445.       case ModIWRReg:
  1446.         Save = AdrVal; DecodeAdr(&ArgStr[2], MModIWReg);
  1447.         if (AdrType != ModNone)
  1448.         {
  1449.           BAsmCode[0] = Index + 0x10;
  1450.           BAsmCode[1] = (AdrVal << 4) + Save;
  1451.           CodeLen = 2;
  1452.         }
  1453.         break;
  1454.     }
  1455.   }
  1456. }
  1457.  
  1458. static void DecodeLDCEDI(Word Code)
  1459. {
  1460.   if (ChkArgCnt(2, 2)
  1461.    && ChkCoreFlags(eCoreSuper8)
  1462.    && DecodeAdr(&ArgStr[1], MModWReg))
  1463.   {
  1464.     BAsmCode[0] = Lo(Code);
  1465.     BAsmCode[1] = AdrVal << 4;
  1466.     DecodeAdr(&ArgStr[2], MModIWRReg);
  1467.     if (AdrType == ModIWRReg)
  1468.     {
  1469.       BAsmCode[1] |= AdrVal | Hi(Code);
  1470.       CodeLen = 2;
  1471.     }
  1472.   }
  1473. }
  1474.  
  1475. static void DecodeLDCEPDI(Word Code)
  1476. {
  1477.   if (ChkArgCnt(2, 2)
  1478.    && ChkCoreFlags(eCoreSuper8)
  1479.    && DecodeAdr(&ArgStr[1], MModIWRReg))
  1480.   {
  1481.     BAsmCode[0] = Lo(Code);
  1482.     BAsmCode[1] = AdrVal | Hi(Code);
  1483.     DecodeAdr(&ArgStr[2], MModWReg);
  1484.     if (AdrType == ModWReg)
  1485.     {
  1486.       BAsmCode[1] |= AdrVal << 4;
  1487.       CodeLen = 2;
  1488.     }
  1489.   }
  1490. }
  1491.  
  1492. static void DecodeINC(Word Index)
  1493. {
  1494.   UNUSED(Index);
  1495.  
  1496.   if (ChkArgCnt(1, 1)
  1497.    && ChkCoreFlags(eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore))
  1498.   {
  1499.     DecodeAdr(&ArgStr[1], MModWReg | MModReg | MModIReg);
  1500.     switch (AdrType)
  1501.     {
  1502.       case ModWReg:
  1503.         BAsmCode[0] = (AdrVal << 4) + 0x0e;
  1504.         CodeLen = 1;
  1505.         break;
  1506.       case ModReg:
  1507.         BAsmCode[0] = 0x20;
  1508.         BAsmCode[1] = AdrVal;
  1509.         CodeLen = 2;
  1510.         break;
  1511.       case ModIReg:
  1512.         BAsmCode[0] = 0x21;
  1513.         BAsmCode[1] = AdrVal;
  1514.         CodeLen = 2;
  1515.         break;
  1516.     }
  1517.   }
  1518. }
  1519.  
  1520. static void DecodeJR(Word Index)
  1521. {
  1522.   Integer AdrInt;
  1523.   int z;
  1524.   tEvalResult EvalResult;
  1525.  
  1526.   UNUSED(Index);
  1527.  
  1528.   if (ChkArgCnt(1, 2)
  1529.    && ChkCoreFlags(eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore))
  1530.   {
  1531.     z = (ArgCnt == 1) ? TrueCond : DecodeCond(&ArgStr[1]);
  1532.     if (z < CondCnt)
  1533.     {
  1534.       AdrInt = EvalStrIntExpressionWithResult(&ArgStr[ArgCnt], Int16, &EvalResult) - (EProgCounter() + 2);
  1535.       if (EvalResult.OK)
  1536.       {
  1537.         if (!mSymbolQuestionable(EvalResult.Flags)
  1538.          && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig);
  1539.         else
  1540.         {
  1541.           ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1542.           BAsmCode[0] = (Conditions[z].Code << 4) + 0x0b;
  1543.           BAsmCode[1] = Lo(AdrInt);
  1544.           CodeLen = 2;
  1545.         }
  1546.       }
  1547.     }
  1548.   }
  1549. }
  1550.  
  1551. static void DecodeDJNZ(Word Index)
  1552. {
  1553.   Integer AdrInt;
  1554.   Boolean OK;
  1555.   tSymbolFlags Flags;
  1556.  
  1557.   UNUSED(Index);
  1558.  
  1559.   if (ChkArgCnt(2, 2)
  1560.    && ChkCoreFlags(eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore)
  1561.    && DecodeAdr(&ArgStr[1], MModWReg))
  1562.   {
  1563.     AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[2], Int16, &OK, &Flags) - (EProgCounter() + 2);
  1564.     if (OK)
  1565.     {
  1566.       if (!mSymbolQuestionable(Flags)
  1567.        && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig);
  1568.       else
  1569.       {
  1570.         BAsmCode[0] = (AdrVal << 4) + 0x0a;
  1571.         BAsmCode[1] = Lo(AdrInt);
  1572.         CodeLen = 2;
  1573.       }
  1574.     }
  1575.   }
  1576. }
  1577.  
  1578. static void DecodeCPIJNE(Word Code)
  1579. {
  1580.   if (ChkArgCnt(3, 3)
  1581.    && ChkCoreFlags(eCoreSuper8)
  1582.    && DecodeAdr(&ArgStr[1], MModWReg))
  1583.   {
  1584.     BAsmCode[1] = AdrVal & 0x0f;
  1585.  
  1586.     DecodeAdr(&ArgStr[2], MModIWReg);
  1587.     if (AdrType != ModNone)
  1588.     {
  1589.       Boolean OK;
  1590.       tSymbolFlags Flags;
  1591.       Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[3], Int16, &OK, &Flags) - (EProgCounter() + 3);
  1592.  
  1593.       BAsmCode[1] |= AdrVal << 4;
  1594.  
  1595.       if (OK)
  1596.       {
  1597.         if (!mSymbolQuestionable(Flags)
  1598.          && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig);
  1599.         else
  1600.         {
  1601.           BAsmCode[0] = Code;
  1602.           BAsmCode[2] = Lo(AdrInt);
  1603.           CodeLen = 3;
  1604.         }
  1605.       }
  1606.     }
  1607.   }
  1608. }
  1609.  
  1610. static void DecodeCALL(Word Index)
  1611. {
  1612.   Boolean IsSuper8 = !!(pCurrCPUProps->CoreFlags & eCoreSuper8);
  1613.   UNUSED(Index);
  1614.  
  1615.   if (ChkArgCnt(1, 1)
  1616.    && ChkCoreFlags(eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore))
  1617.   {
  1618.     DecodeAdr(&ArgStr[1], MModIWRReg | MModIRReg | MModDA | (IsSuper8 ? MModImm : 0));
  1619.     switch (AdrType)
  1620.     {
  1621.       case ModIWRReg:
  1622.         BAsmCode[0] = IsSuper8 ? 0xf4 : 0xd4;
  1623.         BAsmCode[1] = pCurrCPUProps->WorkOfs + AdrVal;
  1624.         CodeLen = 2;
  1625.         break;
  1626.       case ModIRReg:
  1627.         BAsmCode[0] = IsSuper8 ? 0xf4 : 0xd4;
  1628.         BAsmCode[1] = AdrVal;
  1629.         CodeLen = 2;
  1630.         break;
  1631.       case ModDA:
  1632.         BAsmCode[0] = IsSuper8 ? 0xf6 : 0xd6;
  1633.         BAsmCode[1] = Hi(AdrWVal);
  1634.         BAsmCode[2] = Lo(AdrWVal);
  1635.         CodeLen = 3;
  1636.         break;
  1637.       case ModImm:
  1638.         BAsmCode[0] = 0xd4;
  1639.         BAsmCode[1] = AdrVal;
  1640.         CodeLen = 2;
  1641.         break;
  1642.     }
  1643.   }
  1644. }
  1645.  
  1646. static void DecodeJP(Word Index)
  1647. {
  1648.   int z;
  1649.  
  1650.   UNUSED(Index);
  1651.  
  1652.   if (ChkArgCnt(1, 2)
  1653.    && ChkCoreFlags(eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore))
  1654.   {
  1655.     z = (ArgCnt == 1) ? TrueCond : DecodeCond(&ArgStr[1]);
  1656.     if (z < CondCnt)
  1657.     {
  1658.       DecodeAdr(&ArgStr[ArgCnt], MModIWRReg | MModIRReg | MModDA);
  1659.       switch (AdrType)
  1660.       {
  1661.         case ModIWRReg:
  1662.           if (z != TrueCond) WrError(ErrNum_InvAddrMode);
  1663.           else
  1664.           {
  1665.             BAsmCode[0] = (pCurrCPUProps->CoreFlags & eCoreZ8Encore) ? 0xc4 : 0x30;
  1666.             BAsmCode[1] = pCurrCPUProps->WorkOfs + AdrVal;
  1667.             CodeLen = 2;
  1668.           }
  1669.           break;
  1670.         case ModIRReg:
  1671.           if (z != TrueCond) WrError(ErrNum_InvAddrMode);
  1672.           else
  1673.           {
  1674.             BAsmCode[0] = (pCurrCPUProps->CoreFlags & eCoreZ8Encore) ? 0xc4 : 0x30;
  1675.             BAsmCode[1] = AdrVal;
  1676.             CodeLen = 2;
  1677.           }
  1678.           break;
  1679.         case ModDA:
  1680.           BAsmCode[0] = (Conditions[z].Code << 4) + 0x0d;
  1681.           BAsmCode[1] = Hi(AdrWVal);
  1682.           BAsmCode[2] = Lo(AdrWVal);
  1683.           CodeLen = 3;
  1684.           break;
  1685.       }
  1686.     }
  1687.   }
  1688. }
  1689.  
  1690. static void DecodeSRP(Word Code)
  1691. {
  1692.   Boolean Valid;
  1693.  
  1694.   if (ChkArgCnt(1, 1)
  1695.    && ChkCoreFlags((Hi(Code) ? eCoreNone : (eCoreZ8NMOS | eCoreZ8CMOS | eCoreZ8Encore)) | eCoreSuper8)
  1696.    && DecodeAdr(&ArgStr[1], MModImm))
  1697.   {
  1698.     if (pCurrCPUProps->CoreFlags & eCoreZ8Encore || Memo("RDR"))
  1699.       Valid = True;
  1700.     else
  1701.     {
  1702.       Byte MuteMask = Hi(Code) ? 7 : 15;
  1703.  
  1704.       Valid = (((AdrVal & MuteMask) == 0) && ((AdrVal <= pCurrCPUProps->RAMEnd) || (AdrVal >= pCurrCPUProps->SFRStart)));
  1705.     }
  1706.     if (!Valid) WrError(ErrNum_InvRegisterPointer);
  1707.     BAsmCode[0] = (pCurrCPUProps->CoreFlags & eCoreZ8Encore) ? 0x01 : Lo(Code);
  1708.     BAsmCode[1] = AdrVal | Hi(Code);
  1709.     CodeLen = 2;
  1710.   }
  1711. }
  1712.  
  1713. static void DecodeStackExt(Word Index)
  1714. {
  1715.   if (ChkArgCnt(1, 1)
  1716.    && ChkCoreFlags(eCoreZ8Encore)
  1717.    && DecodeAdr(&ArgStr[1], MModXReg))
  1718.   {
  1719.     BAsmCode[0] = Index;
  1720.     BAsmCode[1] = AdrWVal >> 4;
  1721.     BAsmCode[2] = (AdrWVal & 15) << 4;
  1722.     CodeLen = 3;
  1723.   }
  1724. }
  1725.  
  1726. static void DecodeStackDI(Word Code)
  1727. {
  1728.   int MemIdx = ((Code >> 4) & 15) - 7;
  1729.  
  1730.   if (ChkArgCnt(2, 2)
  1731.      && ChkCoreFlags(eCoreSuper8))
  1732.   {
  1733.     Byte Reg;
  1734.  
  1735.     DecodeAdr(&ArgStr[3 - MemIdx], MModReg | MModWReg);
  1736.     Reg = (AdrType == ModWReg) ? AdrVal + pCurrCPUProps->WorkOfs : AdrVal;
  1737.     if (AdrType != ModNone)
  1738.     {
  1739.       DecodeAdr(&ArgStr[MemIdx], MModIReg | MModIWReg);
  1740.       if (AdrType == ModIWReg)
  1741.         AdrVal += pCurrCPUProps->WorkOfs;
  1742.       if (AdrType != ModNone)
  1743.       {
  1744.         BAsmCode[0] = Code;
  1745.         BAsmCode[1] = AdrVal;
  1746.         BAsmCode[2] = Reg;
  1747.         CodeLen = 3;
  1748.       }
  1749.     }
  1750.   }
  1751. }
  1752.  
  1753. static void DecodeTRAP(Word Index)
  1754. {
  1755.   UNUSED(Index);
  1756.  
  1757.   if (ChkArgCnt(1, 1)
  1758.    && ChkCoreFlags(eCoreZ8Encore)
  1759.    && DecodeAdr(&ArgStr[1], MModImm))
  1760.   {
  1761.     BAsmCode[0] = 0xf2;
  1762.     BAsmCode[1] = AdrVal;
  1763.     CodeLen = 2;
  1764.   }
  1765. }
  1766.  
  1767. static void DecodeBSWAP(Word Index)
  1768. {
  1769.   UNUSED(Index);
  1770.  
  1771.   if (ChkArgCnt(1, 1)
  1772.    && ChkCoreFlags(eCoreZ8Encore)
  1773.    && DecodeAdr(&ArgStr[1], MModReg))
  1774.   {
  1775.     BAsmCode[0] = 0xd5;
  1776.     BAsmCode[1] = AdrVal;
  1777.     CodeLen = 2;
  1778.   }
  1779. }
  1780.  
  1781. static void DecodeMULT(Word Index)
  1782. {
  1783.   UNUSED(Index);
  1784.  
  1785.   if (ChkArgCnt(1, 1)
  1786.    && ChkCoreFlags(eCoreZ8Encore))
  1787.   {
  1788.     DecodeAdr(&ArgStr[1], MModWRReg | MModReg);
  1789.     switch (AdrType)
  1790.     {
  1791.       case ModWRReg:
  1792.         BAsmCode[0] = 0xf4;
  1793.         BAsmCode[1] = AdrVal + pCurrCPUProps->WorkOfs;
  1794.         CodeLen = 2;
  1795.         break;
  1796.       case ModReg:
  1797.         BAsmCode[0] = 0xf4;
  1798.         BAsmCode[1] = AdrVal;
  1799.         CodeLen = 2;
  1800.         break;
  1801.     }
  1802.   }
  1803. }
  1804.  
  1805. static void DecodeMULT_DIV(Word Code)
  1806. {
  1807.   if (ChkArgCnt(2, 2)
  1808.    && ChkCoreFlags(eCoreSuper8)
  1809.    && DecodeAdr(&ArgStr[1], MModWRReg | MModRReg))
  1810.   {
  1811.     BAsmCode[2] = (AdrType == ModWRReg) ? AdrVal + pCurrCPUProps->WorkOfs : AdrVal;
  1812.     DecodeAdr(&ArgStr[2], MModWReg | MModReg | MModIReg | MModImm);
  1813.     switch (AdrType)
  1814.     {
  1815.       case ModWReg:
  1816.         BAsmCode[0] = Code;
  1817.         BAsmCode[1] = AdrVal + pCurrCPUProps->WorkOfs;
  1818.         CodeLen = 3;
  1819.         break;
  1820.       case ModReg:
  1821.         BAsmCode[0] = Code;
  1822.         BAsmCode[1] = AdrVal;
  1823.         CodeLen = 3;
  1824.         break;
  1825.       case ModIReg:
  1826.         BAsmCode[0] = Code  + 1;
  1827.         BAsmCode[1] = AdrVal;
  1828.         CodeLen = 3;
  1829.         break;
  1830.       case ModImm:
  1831.         BAsmCode[0] = Code  + 2;
  1832.         BAsmCode[1] = AdrVal;
  1833.         CodeLen = 3;
  1834.         break;
  1835.     }
  1836.   }
  1837. }
  1838.  
  1839. static void DecodeLDX(Word Index)
  1840. {
  1841.   Word Save;
  1842.  
  1843.   UNUSED(Index);
  1844.  
  1845.   if (ChkArgCnt(2, 2)
  1846.    && ChkCoreFlags(eCoreZ8Encore))
  1847.   {
  1848.     DecodeAdr(&ArgStr[1], MModWReg | MModIWReg | MModReg | MModIReg | MModIWRReg | MModIndRR | MModXReg | MModWeird);
  1849.     switch (AdrType)
  1850.     {
  1851.       case ModWReg:
  1852.         Save = AdrVal;
  1853.         DecodeAdr(&ArgStr[2], MModXReg | MModIndRR | MModImm);
  1854.         switch (AdrType)
  1855.         {
  1856.           case ModXReg:
  1857.             Save += LongWorkOfs;
  1858.             BAsmCode[0] = 0xe8;
  1859.             BAsmCode[1] = AdrWVal >> 4;
  1860.             BAsmCode[2] = ((AdrWVal & 15) << 4) | (Hi(Save) & 15);
  1861.             BAsmCode[3] = Lo(Save);
  1862.             CodeLen = 4;
  1863.             break;
  1864.           case ModIndRR:
  1865.             BAsmCode[0] = 0x88;
  1866.             BAsmCode[1] = (Save << 4) | AdrVal;
  1867.             BAsmCode[2] = AdrIndex;
  1868.             CodeLen = 3;
  1869.             break;
  1870.           case ModImm:
  1871.             BAsmCode[0] = 0xe9;
  1872.             BAsmCode[1] = AdrVal;
  1873.             BAsmCode[2] = Hi(LongWorkOfs | Save);
  1874.             BAsmCode[3] = Lo(LongWorkOfs | Save);
  1875.             CodeLen = 4;
  1876.             break;
  1877.         }
  1878.         break;
  1879.       case ModIWReg:
  1880.         Save = AdrVal;
  1881.         DecodeAdr(&ArgStr[2], MModXReg);
  1882.         switch (AdrType)
  1883.         {
  1884.           case ModXReg:
  1885.             BAsmCode[0] = 0x85;
  1886.             BAsmCode[1] = (Save << 4) | (Hi(AdrWVal) & 15);
  1887.             BAsmCode[2] = Lo(AdrWVal);
  1888.             CodeLen = 3;
  1889.             break;
  1890.         }
  1891.         break;
  1892.       case ModReg:
  1893.         Save = AdrVal;
  1894.         DecodeAdr(&ArgStr[2], MModIReg);
  1895.         switch (AdrType)
  1896.         {
  1897.           case ModIReg:
  1898.             BAsmCode[0] = 0x86;
  1899.             BAsmCode[1] = AdrVal;
  1900.             BAsmCode[2] = Save;
  1901.             CodeLen = 3;
  1902.             break;
  1903.         }
  1904.         break;
  1905.       case ModIReg:
  1906.         Save = AdrVal;
  1907.         DecodeAdr(&ArgStr[2], MModReg | MModWeird);
  1908.         switch (AdrType)
  1909.         {
  1910.           case ModReg:
  1911.             BAsmCode[0] = 0x96;
  1912.             BAsmCode[1] = AdrVal;
  1913.             BAsmCode[2] = Save;
  1914.             CodeLen = 3;
  1915.             break;
  1916.           case ModWeird:
  1917.             BAsmCode[0] = 0x87;
  1918.             BAsmCode[1] = AdrVal;
  1919.             BAsmCode[2] = Save;
  1920.             CodeLen = 3;
  1921.             break;
  1922.         }
  1923.         break;
  1924.       case ModIWRReg:
  1925.         Save = pCurrCPUProps->WorkOfs + AdrVal;
  1926.         DecodeAdr(&ArgStr[2], MModReg);
  1927.         switch (AdrType)
  1928.         {
  1929.           case ModReg:
  1930.             BAsmCode[0] = 0x96;
  1931.             BAsmCode[1] = AdrVal;
  1932.             BAsmCode[2] = Save;
  1933.             CodeLen = 3;
  1934.             break;
  1935.         }
  1936.         break;
  1937.       case ModIndRR:
  1938.         BAsmCode[2] = AdrIndex;
  1939.         Save = AdrVal;
  1940.         DecodeAdr(&ArgStr[2], MModWReg);
  1941.         switch (AdrType)
  1942.         {
  1943.           case ModWReg:
  1944.             BAsmCode[0] = 0x89;
  1945.             BAsmCode[1] = (Save << 4) | AdrVal;
  1946.             CodeLen = 3;
  1947.             break;
  1948.         }
  1949.         break;
  1950.       case ModXReg:
  1951.         Save = AdrWVal;
  1952.         DecodeAdr(&ArgStr[2], MModWReg | MModIWReg | MModXReg | MModImm);
  1953.         switch (AdrType)
  1954.         {
  1955.           case ModWReg:
  1956.             BAsmCode[0] = 0x94;
  1957.             BAsmCode[1] = (AdrVal << 4) | (Hi(Save) & 15);
  1958.             BAsmCode[2] = Lo(Save);
  1959.             CodeLen = 3;
  1960.             break;
  1961.           case ModIWReg:
  1962.             BAsmCode[0] = 0x95;
  1963.             BAsmCode[1] = (AdrVal << 4) | (Hi(Save) & 15);
  1964.             BAsmCode[2] = Lo(Save);
  1965.             CodeLen = 3;
  1966.             break;
  1967.           case ModXReg:
  1968.             BAsmCode[0] = 0xe8;
  1969.             BAsmCode[1] = AdrWVal >> 4;
  1970.             BAsmCode[2] = ((AdrWVal & 15) << 4) | (Hi(Save) & 15);
  1971.             BAsmCode[3] = Lo(Save);
  1972.             CodeLen = 4;
  1973.             break;
  1974.           case ModImm:
  1975.             BAsmCode[0] = 0xe9;
  1976.             BAsmCode[1] = AdrVal;
  1977.             BAsmCode[2] = (Hi(Save) & 15);
  1978.             BAsmCode[3] = Lo(Save);
  1979.             CodeLen = 4;
  1980.             break;
  1981.         }
  1982.         break;
  1983.       case ModWeird:
  1984.         Save = AdrVal;
  1985.         DecodeAdr(&ArgStr[2], MModIReg);
  1986.         switch (AdrType)
  1987.         {
  1988.           case ModIReg:
  1989.             BAsmCode[0] = 0x97;
  1990.             BAsmCode[1] = AdrVal;
  1991.             BAsmCode[2] = Save;
  1992.             CodeLen = 3;
  1993.             break;
  1994.         }
  1995.         break;
  1996.     }
  1997.   }
  1998. }
  1999.  
  2000. static void DecodeLDW(Word Code)
  2001. {
  2002.   if (ChkArgCnt(2, 2)
  2003.    && ChkCoreFlags(eCoreSuper8))
  2004.   {
  2005.     DecodeAdr(&ArgStr[1], MModRReg | MModWRReg);
  2006.     if (AdrType != ModNone)
  2007.     {
  2008.       Byte Dest = (AdrType == ModRReg) ? AdrVal : AdrVal + pCurrCPUProps->WorkOfs;
  2009.  
  2010.       OpSize = eSymbolSize16Bit;
  2011.       DecodeAdr(&ArgStr[2], MModRReg | MModWRReg | MModIReg | MModImm);
  2012.       switch (AdrType)
  2013.       {
  2014.         case ModWRReg:
  2015.         case ModRReg:
  2016.           BAsmCode[0] = Code;
  2017.           BAsmCode[1] = (AdrType == ModRReg) ? AdrVal : AdrVal + pCurrCPUProps->WorkOfs;
  2018.           BAsmCode[2] = Dest;
  2019.           CodeLen = 3;
  2020.           break;
  2021.         case ModIReg:
  2022.           BAsmCode[0] = Code + 1;
  2023.           BAsmCode[1] = AdrVal;
  2024.           BAsmCode[2] = Dest;
  2025.           CodeLen = 3;
  2026.           break;
  2027.         case ModImm:
  2028.           BAsmCode[0] = Code + 2;
  2029.           BAsmCode[1] = Dest;
  2030.           BAsmCode[2] = Hi(AdrWVal);
  2031.           BAsmCode[3] = Lo(AdrWVal);
  2032.           CodeLen = 4;
  2033.           break;
  2034.       }
  2035.     }
  2036.   }
  2037. }
  2038.  
  2039. static void DecodeLDWX(Word Index)
  2040. {
  2041.   UNUSED(Index);
  2042.  
  2043.   if (ChkArgCnt(2, 2)
  2044.    && ChkCoreFlags(eCoreZ8Encore)
  2045.    && DecodeAdr(&ArgStr[1], MModXReg))
  2046.   {
  2047.     BAsmCode[0] = 0x1f;
  2048.     BAsmCode[1] = 0xe8;
  2049.     BAsmCode[3] = Hi(AdrWVal);
  2050.     BAsmCode[4] = Lo(AdrWVal);
  2051.     if (DecodeAdr(&ArgStr[2], MModXReg))
  2052.     {
  2053.       BAsmCode[2] = AdrWVal >> 4;
  2054.       BAsmCode[3] |= (AdrWVal & 0x0f) << 4;
  2055.       CodeLen = 5;
  2056.     }
  2057.   }
  2058. }
  2059.  
  2060. static void DecodeLEA(Word Index)
  2061. {
  2062.   Byte Save;
  2063.  
  2064.   UNUSED(Index);
  2065.  
  2066.   if (ChkArgCnt(2, 2)
  2067.    && ChkCoreFlags(eCoreZ8Encore))
  2068.   {
  2069.     DecodeAdr(&ArgStr[1], MModWReg | MModWRReg);
  2070.     switch (AdrType)
  2071.     {
  2072.       case ModWReg:
  2073.         Save = AdrVal;
  2074.         if (DecodeAdr(&ArgStr[2], MModInd))
  2075.         {
  2076.           BAsmCode[0] = 0x98;
  2077.           BAsmCode[1] = (Save << 4) | AdrVal;
  2078.           BAsmCode[2] = AdrIndex;
  2079.           CodeLen = 3;
  2080.         }
  2081.         break;
  2082.       case ModWRReg:
  2083.         Save = AdrVal;
  2084.         if (DecodeAdr(&ArgStr[2], MModIndRR))
  2085.         {
  2086.           BAsmCode[0] = 0x99;
  2087.           BAsmCode[1] = (Save << 4) | AdrVal;
  2088.           BAsmCode[2] = AdrIndex;
  2089.           CodeLen = 3;
  2090.         }
  2091.         break;
  2092.     }
  2093.   }
  2094. }
  2095.  
  2096. static void DecodeBIT(Word Index)
  2097. {
  2098.   Boolean OK;
  2099.  
  2100.   UNUSED(Index);
  2101.  
  2102.   if (ChkArgCnt(3, 3)
  2103.    && ChkCoreFlags(eCoreZ8Encore))
  2104.   {
  2105.     BAsmCode[1] = EvalStrIntExpression(&ArgStr[1], UInt1, &OK) << 7;
  2106.     if (OK)
  2107.     {
  2108.       BAsmCode[1] |= EvalStrIntExpression(&ArgStr[2], UInt3, &OK) << 4;
  2109.       if (OK)
  2110.       {
  2111.         DecodeAdr(&ArgStr[3], MModWReg);
  2112.         switch (AdrType)
  2113.         {
  2114.           case ModWReg:
  2115.             BAsmCode[0] = 0xe2;
  2116.             BAsmCode[1] |= AdrVal;
  2117.             CodeLen = 2;
  2118.             break;
  2119.         }
  2120.       }
  2121.     }
  2122.   }
  2123. }
  2124.  
  2125. static void DecodeBit(Word Index)
  2126. {
  2127.   Boolean OK;
  2128.  
  2129.   if (ChkCoreFlags(eCoreZ8Encore))
  2130.     switch (ArgCnt)
  2131.     {
  2132.       case 1:
  2133.       {
  2134.         LongWord BitArg;
  2135.         ShortInt OpSize = eSymbolSize8Bit;
  2136.  
  2137.         if (DecodeBitArg(&BitArg, 1, 1, OpSize))
  2138.         {
  2139.           Word Address;
  2140.           Byte BitPos;
  2141.  
  2142.           (void)DissectBitSymbol(BitArg, &Address, &BitPos, &OpSize);
  2143.           if ((Address & 0xff0) == pCurrCPUProps->WorkOfs)
  2144.           {
  2145.             BAsmCode[0] = 0xe2;
  2146.             BAsmCode[1] = Index | (BitPos << 4) | (Address & 15);
  2147.             CodeLen = 2;
  2148.           }
  2149.           else /* -> ANDX,ORX ER,IM */
  2150.           {
  2151.             BAsmCode[0] = Index ? 0x49 : 0x59;
  2152.             BAsmCode[1] = Index ? (1 << BitPos) : ~(1 << BitPos);
  2153.             BAsmCode[2] = Hi(Address);
  2154.             BAsmCode[3] = Lo(Address);
  2155.             CodeLen = 4;
  2156.           }
  2157.         }
  2158.         break;
  2159.       }
  2160.       case 2:
  2161.         BAsmCode[1] = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
  2162.         if (OK)
  2163.         {
  2164.           DecodeAdr(&ArgStr[2], MModWReg | MModXReg);
  2165.           switch (AdrType)
  2166.           {
  2167.             case ModWReg:
  2168.               BAsmCode[0] = 0xe2;
  2169.               BAsmCode[1] = (BAsmCode[1] << 4) | Index | AdrVal;
  2170.               CodeLen = 2;
  2171.               break;
  2172.             case ModXReg: /* -> ANDX,ORX ER,IM */
  2173.               BAsmCode[0] = Index ? 0x49 : 0x59;
  2174.               BAsmCode[1] = Index ? (1 << BAsmCode[1]) : ~(1 << BAsmCode[1]);
  2175.               BAsmCode[2] = Hi(AdrWVal);
  2176.               BAsmCode[3] = Lo(AdrWVal);
  2177.               CodeLen = 4;
  2178.               break;
  2179.           }
  2180.         }
  2181.         break;
  2182.       default:
  2183.         (void)ChkArgCnt(1, 2);
  2184.     }
  2185. }
  2186.  
  2187. static void DecodeBTJCore(Word Index, int ArgOffset)
  2188. {
  2189.   int TmpCodeLen = 0;
  2190.  
  2191.   switch (ArgCnt - ArgOffset)
  2192.   {
  2193.     case 2:
  2194.     {
  2195.       LongWord BitArg;
  2196.       ShortInt OpSize = eSymbolSize8Bit;
  2197.  
  2198.       if (DecodeBitArg(&BitArg, 1 + ArgOffset, 1 + ArgOffset, OpSize))
  2199.       {
  2200.         Word Address;
  2201.         Byte BitPos;
  2202.  
  2203.         (void)DissectBitSymbol(BitArg, &Address, &BitPos, &OpSize);
  2204.         if ((Address & 0xff0) == pCurrCPUProps->WorkOfs)
  2205.         {
  2206.           BAsmCode[0] = 0xf6;
  2207.           BAsmCode[1] = (Address & 15) | (BitPos << 4);
  2208.           TmpCodeLen = 2;
  2209.         }
  2210.         else
  2211.           WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2212.       }
  2213.       break;
  2214.     }
  2215.     case 3:
  2216.     {
  2217.       Boolean OK;
  2218.  
  2219.       BAsmCode[1] = EvalStrIntExpression(&ArgStr[1 + ArgOffset], UInt3, &OK) << 4;
  2220.       if (OK)
  2221.       {
  2222.         DecodeAdr(&ArgStr[2 + ArgOffset], MModWReg | MModIWReg);
  2223.         switch (AdrType)
  2224.         {
  2225.           case ModWReg:
  2226.             BAsmCode[0] = 0xf6;
  2227.             BAsmCode[1] |= AdrVal;
  2228.             TmpCodeLen = 2;
  2229.             break;
  2230.           case ModIWReg:
  2231.             BAsmCode[0] = 0xf7;
  2232.             BAsmCode[1] |= AdrVal;
  2233.             TmpCodeLen = 2;
  2234.             break;
  2235.         }
  2236.       }
  2237.       break;
  2238.     }
  2239.     default:
  2240.       (void)ChkArgCnt(3, 4);
  2241.   }
  2242.   if (TmpCodeLen > 0)
  2243.   {
  2244.     tEvalResult EvalResult;
  2245.     Integer AdrInt = EvalStrIntExpressionWithResult(&ArgStr[ArgCnt], Int16, &EvalResult) - (EProgCounter() + TmpCodeLen + 1);
  2246.  
  2247.     BAsmCode[1] |= Index;
  2248.     if (EvalResult.OK)
  2249.     {
  2250.       if (!mSymbolQuestionable(EvalResult.Flags)
  2251.        && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig);
  2252.       else
  2253.       {
  2254.         ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  2255.         BAsmCode[TmpCodeLen] = Lo(AdrInt);
  2256.         CodeLen = TmpCodeLen + 1;
  2257.       }
  2258.     }
  2259.   }
  2260. }
  2261.  
  2262. static void DecodeBTJ(Word Index)
  2263. {
  2264.   if (ChkCoreFlags(eCoreZ8Encore)
  2265.    && ChkArgCnt(3, 4))
  2266.   {
  2267.     Boolean OK;
  2268.  
  2269.     Index = EvalStrIntExpression(&ArgStr[1], UInt1, &OK) << 7;
  2270.     if (OK)
  2271.       DecodeBTJCore(Index, 1);
  2272.   }
  2273. }
  2274.  
  2275. static void DecodeBtj(Word Index)
  2276. {
  2277.   UNUSED(Index);
  2278.  
  2279.   if (ChkArgCnt(2, 3)
  2280.    && ChkCoreFlags(eCoreZ8Encore))
  2281.     DecodeBTJCore(Index, 0);
  2282. }
  2283.  
  2284. static void DecodeBit1(Word Code)
  2285. {
  2286.   if (ChkArgCnt(1, 2)
  2287.    && ChkCoreFlags(eCoreSuper8)
  2288.    && DecodeWRBitArg(1, ArgCnt, &BAsmCode[1]))
  2289.   {
  2290.     BAsmCode[1] = (BAsmCode[1] << 1) | Hi(Code);
  2291.     BAsmCode[0] = Lo(Code);
  2292.     CodeLen = 2;
  2293.   }
  2294. }
  2295.  
  2296. static void DecodeBit2(Word Code)
  2297. {
  2298.   if (ChkCoreFlags(eCoreSuper8))
  2299.   {
  2300.     LongWord BitValue;
  2301.     Byte Reg;
  2302.  
  2303.     switch (ArgCnt)
  2304.     {
  2305.       case 3:
  2306.       {
  2307.         int BitStart, BitEnd, RegIdx;
  2308.  
  2309.         if ((*ArgStr[2].str.p_str == '#') && Hi(Code))
  2310.         {
  2311.           BitStart = 1;
  2312.           BitEnd = 2;
  2313.           RegIdx = 3;
  2314.           BAsmCode[1] = 0x01;
  2315.         }
  2316.         else
  2317.         {
  2318.           BitStart = 2;
  2319.           BitEnd = 3;
  2320.           RegIdx = 1;
  2321.           BAsmCode[1] = 0x00;
  2322.         }
  2323.         DecodeAdr(&ArgStr[RegIdx], MModWReg); Reg = AdrVal;
  2324.         if ((AdrType == ModWReg) && DecodeBitArg2(&BitValue, &ArgStr[BitStart], &ArgStr[BitEnd], eSymbolSize8Bit));
  2325.         else
  2326.           return;
  2327.         break;
  2328.       }
  2329.       case 2:
  2330.       {
  2331.         if ((IsWReg(&ArgStr[1], &Reg, False) == eIsReg)
  2332.          && DecodeBitArg(&BitValue, 2, 2, eSymbolSize8Bit))
  2333.         {
  2334.           BAsmCode[1] = 0x00;
  2335.         }
  2336.         else if ((IsWReg(&ArgStr[2], &Reg, False) == eIsReg)
  2337.               && DecodeBitArg(&BitValue, 1, 1, eSymbolSize8Bit)
  2338.               && Hi(Code))
  2339.         {
  2340.           BAsmCode[1] = 0x01;
  2341.         }
  2342.         else
  2343.         {
  2344.           WrError(ErrNum_InvAddrMode);
  2345.           return;
  2346.         }
  2347.         break;
  2348.       }
  2349.       default:
  2350.         (void)ChkArgCnt(2, 3);
  2351.         return;
  2352.     }
  2353.     CodeLen = 3;
  2354.     BAsmCode[0] = Lo(Code);
  2355.     BAsmCode[1] |= (Reg << 4) | ((BitValue & 7) << 1);
  2356.     BAsmCode[2] = BitValue >> 3;
  2357.     CodeLen = 3;
  2358.   }
  2359. }
  2360.  
  2361. static void DecodeBitRel(Word Code)
  2362. {
  2363.   if (ChkArgCnt(2, 3)
  2364.    && ChkCoreFlags(eCoreSuper8)
  2365.    && DecodeWRBitArg(2, ArgCnt, &BAsmCode[1]))
  2366.   {
  2367.     tEvalResult EvalResult;
  2368.     Integer AdrInt = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult) - (EProgCounter() + 3);
  2369.     if (EvalResult.OK)
  2370.     {
  2371.       if (!mSymbolQuestionable(EvalResult.Flags)
  2372.        && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig);
  2373.       else
  2374.       {
  2375.         ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  2376.         BAsmCode[0] = Lo(Code);
  2377.         BAsmCode[1] = (BAsmCode[1] << 1) | Hi(Code);
  2378.         BAsmCode[2] = Lo(AdrInt);
  2379.         CodeLen = 3;
  2380.       }
  2381.     }
  2382.   }
  2383. }
  2384.  
  2385. static void DecodeSFR(Word Code)
  2386. {
  2387.   UNUSED(Code);
  2388.  
  2389.   CodeEquate(SegData, 0, mIsZ8Encore() ? 0xfff : 0xff);
  2390. }
  2391.  
  2392. static void DecodeDEFBIT(Word Code)
  2393. {
  2394.   LongWord BitSpec;
  2395.  
  2396.   UNUSED(Code);
  2397.  
  2398.   /* if in structure definition, add special element to structure */
  2399.  
  2400.   if (ActPC == StructSeg)
  2401.   {
  2402.     Boolean OK;
  2403.     Byte BitPos;
  2404.     PStructElem pElement;
  2405.  
  2406.     if (!ChkArgCnt(2, 2))
  2407.       return;
  2408.     BitPos = EvalBitPosition(&ArgStr[2], &OK, eSymbolSize8Bit);
  2409.     if (!OK)
  2410.       return;
  2411.     pElement = CreateStructElem(&LabPart);
  2412.     if (!pElement)
  2413.       return;
  2414.     pElement->pRefElemName = as_strdup(ArgStr[1].str.p_str);
  2415.     pElement->OpSize = eSymbolSize8Bit;
  2416.     pElement->BitPos = BitPos;
  2417.     pElement->ExpandFnc = ExpandZ8Bit;
  2418.     AddStructElem(pInnermostNamedStruct->StructRec, pElement);
  2419.   }
  2420.   else
  2421.   {
  2422.     if (DecodeBitArg(&BitSpec, 1, ArgCnt, eSymbolSize8Bit))
  2423.     {
  2424.       *ListLine = '=';
  2425.       DissectBit_Z8(ListLine + 1, STRINGSIZE - 3, BitSpec);
  2426.       PushLocHandle(-1);
  2427.       EnterIntSymbol(&LabPart, BitSpec, SegBData, False);
  2428.       PopLocHandle();
  2429.       /* TODO: MakeUseList? */
  2430.     }
  2431.   }
  2432. }
  2433.  
  2434. /*--------------------------------------------------------------------------*/
  2435. /* Instruction Table Buildup/Teardown */
  2436.  
  2437. static void AddFixed(const char *NName, Word Code, tCoreFlags CoreFlags)
  2438. {
  2439.   order_array_rsv_end(FixedOrders, BaseOrder);
  2440.   FixedOrders[InstrZ].Code = Code;
  2441.   FixedOrders[InstrZ].CoreFlags = CoreFlags;
  2442.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
  2443. }
  2444.  
  2445. static void AddALU2(const char *NName, Word Code, tCoreFlags CoreFlags)
  2446. {
  2447.   order_array_rsv_end(ALU2Orders, BaseOrder);
  2448.   ALU2Orders[InstrZ].Code = Code;
  2449.   ALU2Orders[InstrZ].CoreFlags = CoreFlags;
  2450.   AddInstTable(InstTable, NName, InstrZ++, DecodeALU2);
  2451. }
  2452.  
  2453. static void AddALUX(const char *NName, Word Code, tCoreFlags CoreFlags)
  2454. {
  2455.   order_array_rsv_end(ALUXOrders, BaseOrder);
  2456.   ALUXOrders[InstrZ].Code = Code;
  2457.   ALUXOrders[InstrZ].CoreFlags = CoreFlags;
  2458.   AddInstTable(InstTable, NName, InstrZ++, DecodeALUX);
  2459. }
  2460.  
  2461. static void AddALU1(const char *NName, Word Code, tCoreFlags CoreFlags, Boolean Is16)
  2462. {
  2463.   order_array_rsv_end(ALU1Orders, ALU1Order);
  2464.   ALU1Orders[InstrZ].Code = Code;
  2465.   ALU1Orders[InstrZ].CoreFlags = CoreFlags;
  2466.   ALU1Orders[InstrZ].Is16 = Is16;
  2467.   AddInstTable(InstTable, NName, InstrZ++, DecodeALU1);
  2468. }
  2469.  
  2470. static void AddCondition(const char *NName, Byte NCode)
  2471. {
  2472.   order_array_rsv_end(Conditions, Condition);
  2473.   Conditions[InstrZ].Name = NName;
  2474.   Conditions[InstrZ++].Code = NCode;
  2475. }
  2476.  
  2477. static void InitFields(void)
  2478. {
  2479.   InstTable = CreateInstTable(201);
  2480.  
  2481.   InstrZ = 0;
  2482.   AddFixed("CCF"  , 0xef   , eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
  2483.   AddFixed("DI"   , 0x8f   , eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
  2484.   AddFixed("EI"   , 0x9f   , eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
  2485.   AddFixed("HALT" , 0x7f   ,               eCoreZ8CMOS               | eCoreZ8Encore);
  2486.   AddFixed("IRET" , 0xbf   , eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
  2487.   AddFixed("NOP"  , NOPCode, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
  2488.   AddFixed("RCF"  , 0xcf   , eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
  2489.   AddFixed("RET"  , 0xaf   , eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
  2490.   AddFixed("SCF"  , 0xdf   , eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
  2491.   AddFixed("STOP" , 0x6f   ,               eCoreZ8CMOS               | eCoreZ8Encore);
  2492.   AddFixed("ATM"  , 0x2f   , eCoreZ8NMOS | eCoreZ8CMOS               | eCoreZ8Encore);
  2493.   AddFixed("BRK"  , 0x00   ,                                           eCoreZ8Encore);
  2494.   AddFixed("WDH"  , 0x4f   , eCoreZ8NMOS | eCoreZ8CMOS                              );
  2495.   AddFixed("WDT"  , 0x5f   , eCoreZ8NMOS | eCoreZ8CMOS               | eCoreZ8Encore);
  2496.   AddFixed("ENTER", 0x1f   ,                             eCoreSuper8                );
  2497.   AddFixed("EXIT" , 0x2f   ,                             eCoreSuper8                );
  2498.   AddFixed("NEXT" , 0x0f   ,                             eCoreSuper8                );
  2499.   AddFixed("SB0"  , 0x4f   ,                             eCoreSuper8                );
  2500.   AddFixed("SB1"  , 0x5f   ,                             eCoreSuper8                );
  2501.   AddFixed("WFI"  , 0x3f   ,                             eCoreSuper8                );
  2502.  
  2503.   InstrZ = 0;
  2504.   AddALU2("ADD" , 0x0000, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
  2505.   AddALU2("ADC" , 0x0010, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
  2506.   AddALU2("SUB" , 0x0020, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
  2507.   AddALU2("SBC" , 0x0030, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
  2508.   AddALU2("OR"  , 0x0040, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
  2509.   AddALU2("AND" , 0x0050, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
  2510.   AddALU2("TCM" , 0x0060, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
  2511.   AddALU2("TM"  , 0x0070, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
  2512.   AddALU2("CP"  , 0x00a0, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
  2513.   AddALU2("XOR" , 0x00b0, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
  2514.   AddALU2("CPC" , (EXTPREFIX << 8) | 0xa0, eCoreZ8Encore);
  2515.  
  2516.   InstrZ = 0;
  2517.   AddALUX("ADDX", 0x0008, eCoreZ8Encore);
  2518.   AddALUX("ADCX", 0x0018, eCoreZ8Encore);
  2519.   AddALUX("SUBX", 0x0028, eCoreZ8Encore);
  2520.   AddALUX("SBCX", 0x0038, eCoreZ8Encore);
  2521.   AddALUX("ORX" , 0x0048, eCoreZ8Encore);
  2522.   AddALUX("ANDX", 0x0058, eCoreZ8Encore);
  2523.   AddALUX("TCMX", 0x0068, eCoreZ8Encore);
  2524.   AddALUX("TMX" , 0x0078, eCoreZ8Encore);
  2525.   AddALUX("CPX" , 0x00a8, eCoreZ8Encore);
  2526.   AddALUX("XORX", 0x00b8, eCoreZ8Encore);
  2527.   AddALUX("CPCX", (EXTPREFIX << 8) | 0xa8, eCoreZ8Encore);
  2528.  
  2529.   InstrZ = 0;
  2530.   AddALU1("DEC" , (pCurrCPUProps->CoreFlags & eCoreZ8Encore) ? 0x0030 : 0x0000, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
  2531.   AddALU1("RLC" , 0x0010, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
  2532.   AddALU1("DA"  , 0x0040, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
  2533.   AddALU1("POP" , 0x0050, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
  2534.   AddALU1("COM" , 0x0060, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
  2535.   AddALU1("PUSH", 0x0070, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
  2536.   AddALU1("DECW", 0x0080, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, True );
  2537.   AddALU1("RL"  , 0x0090, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
  2538.   AddALU1("INCW", 0x00a0, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, True );
  2539.   AddALU1("CLR" , 0x00b0, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
  2540.   AddALU1("RRC" , 0x00c0, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
  2541.   AddALU1("SRA" , 0x00d0, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
  2542.   AddALU1("RR"  , 0x00e0, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
  2543.   AddALU1("SWAP", 0x00f0, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
  2544.   AddALU1("SRL" , (EXTPREFIX << 8) | 0xc0, eCoreZ8NMOS | eCoreZ8CMOS | eCoreZ8Encore, False);
  2545.  
  2546.   InstrZ = 0;
  2547.   AddCondition("F"  , 0); TrueCond = InstrZ; AddCondition("T"  , 8);
  2548.   AddCondition("C"  , 7); AddCondition("NC" ,15);
  2549.   AddCondition("Z"  , 6); AddCondition("NZ" ,14);
  2550.   AddCondition("MI" , 5); AddCondition("PL" ,13);
  2551.   AddCondition("OV" , 4); AddCondition("NOV",12);
  2552.   AddCondition("EQ" , 6); AddCondition("NE" ,14);
  2553.   AddCondition("LT" , 1); AddCondition("GE" , 9);
  2554.   AddCondition("LE" , 2); AddCondition("GT" ,10);
  2555.   AddCondition("ULT", 7); AddCondition("UGE",15);
  2556.   AddCondition("ULE", 3); AddCondition("UGT",11);
  2557.   CondCnt = InstrZ;
  2558.  
  2559.   AddInstTable(InstTable, "LD", 0, DecodeLD);
  2560.   AddInstTable(InstTable, "LDX", 0, DecodeLDX);
  2561.   AddInstTable(InstTable, "LDW", 0xc4, DecodeLDW);
  2562.   AddInstTable(InstTable, "LDWX", 0, DecodeLDWX);
  2563.   AddInstTable(InstTable, "LDC", 0xc2, DecodeLDCE);
  2564.   AddInstTable(InstTable, "LDE", 0x82, DecodeLDCE);
  2565.   if (mIsSuper8())
  2566.   {
  2567.     AddInstTable(InstTable, "LDCI", 0x00e3, DecodeLDCEDI);
  2568.     AddInstTable(InstTable, "LDEI", 0x01e3, DecodeLDCEDI);
  2569.   }
  2570.   else
  2571.   {
  2572.     AddInstTable(InstTable, "LDCI", 0xc3, DecodeLDCEI);
  2573.     AddInstTable(InstTable, "LDEI", 0x83, DecodeLDCEI);
  2574.   }
  2575.   AddInstTable(InstTable, "LDCD", 0x00e2, DecodeLDCEDI);
  2576.   AddInstTable(InstTable, "LDED", 0x01e2, DecodeLDCEDI);
  2577.   AddInstTable(InstTable, "LDCPD", 0x00f2, DecodeLDCEPDI);
  2578.   AddInstTable(InstTable, "LDEPD", 0x01f2, DecodeLDCEPDI);
  2579.   AddInstTable(InstTable, "LDCPI", 0x00f3, DecodeLDCEPDI);
  2580.   AddInstTable(InstTable, "LDEPI", 0x01f3, DecodeLDCEPDI);
  2581.   AddInstTable(InstTable, "INC", 0, DecodeINC);
  2582.   AddInstTable(InstTable, "JR", 0, DecodeJR);
  2583.   AddInstTable(InstTable, "JP", 0, DecodeJP);
  2584.   AddInstTable(InstTable, "CALL", 0, DecodeCALL);
  2585.   AddInstTable(InstTable, "SRP", 0x0031, DecodeSRP);
  2586.   AddInstTable(InstTable, "SRP0", 0x0231, DecodeSRP);
  2587.   AddInstTable(InstTable, "SRP1", 0x0131, DecodeSRP);
  2588.   AddInstTable(InstTable, "RDR", 0x01d5, DecodeSRP);
  2589.   AddInstTable(InstTable, "DJNZ", 0, DecodeDJNZ);
  2590.   AddInstTable(InstTable, "LEA", 0, DecodeLEA);
  2591.  
  2592.   AddInstTable(InstTable, "POPX" , 0xd8, DecodeStackExt);
  2593.   AddInstTable(InstTable, "PUSHX", 0xc8, DecodeStackExt);
  2594.   AddInstTable(InstTable, "POPUD", 0x92, DecodeStackDI);
  2595.   AddInstTable(InstTable, "POPUI", 0x93, DecodeStackDI);
  2596.   AddInstTable(InstTable, "PUSHUD", 0x82, DecodeStackDI);
  2597.   AddInstTable(InstTable, "PUSHUI", 0x83, DecodeStackDI);
  2598.   AddInstTable(InstTable, "TRAP" , 0, DecodeTRAP);
  2599.   AddInstTable(InstTable, "BSWAP", 0, DecodeBSWAP);
  2600.   if (mIsSuper8())
  2601.     AddInstTable(InstTable, "MULT" , 0x84, DecodeMULT_DIV);
  2602.   else
  2603.     AddInstTable(InstTable, "MULT" , 0, DecodeMULT);
  2604.   AddInstTable(InstTable, "DIV" , 0x94, DecodeMULT_DIV);
  2605.   AddInstTable(InstTable, "BIT", 0, DecodeBIT);
  2606.   AddInstTable(InstTable, "BCLR", 0x00, DecodeBit);
  2607.   AddInstTable(InstTable, "BSET", 0x80, DecodeBit);
  2608.   AddInstTable(InstTable, "BTJ", 0, DecodeBTJ);
  2609.   AddInstTable(InstTable, "BTJZ", 0x00, DecodeBtj);
  2610.   AddInstTable(InstTable, "BTJNZ", 0x80, DecodeBtj);
  2611.   AddInstTable(InstTable, "CPIJNE", 0xd2, DecodeCPIJNE);
  2612.   AddInstTable(InstTable, "CPIJE", 0xc2, DecodeCPIJNE);
  2613.   AddInstTable(InstTable, "BITC", 0x0057, DecodeBit1);
  2614.   AddInstTable(InstTable, "BITR", 0x0077, DecodeBit1);
  2615.   AddInstTable(InstTable, "BITS", 0x0177, DecodeBit1);
  2616.   AddInstTable(InstTable, "BAND", 0x0167, DecodeBit2);
  2617.   AddInstTable(InstTable, "BOR",  0x0107, DecodeBit2);
  2618.   AddInstTable(InstTable, "BXOR", 0x0127, DecodeBit2);
  2619.   AddInstTable(InstTable, "LDB",  0x0147, DecodeBit2);
  2620.   AddInstTable(InstTable, "BCP",  0x0017, DecodeBit2);
  2621.   AddInstTable(InstTable, "BTJRF",0x0037, DecodeBitRel);
  2622.   AddInstTable(InstTable, "BTJRT",0x0137, DecodeBitRel);
  2623.  
  2624.   AddInstTable(InstTable, "SFR", 0, DecodeSFR);
  2625.   AddInstTable(InstTable, "REG", 0, CodeREG);
  2626.   AddInstTable(InstTable, "DEFBIT", 0, DecodeDEFBIT);
  2627. }
  2628.  
  2629. static void DeinitFields(void)
  2630. {
  2631.   order_array_free(FixedOrders);
  2632.   order_array_free(ALU2Orders);
  2633.   order_array_free(ALU1Orders);
  2634.   order_array_free(ALUXOrders);
  2635.   order_array_free(Conditions);
  2636.  
  2637.   DestroyInstTable(InstTable);
  2638. }
  2639.  
  2640. /*---------------------------------------------------------------------*/
  2641.  
  2642. /*!------------------------------------------------------------------------
  2643.  * \fn     InternSymbol_Z8(char *pArg, TempResult *pResult)
  2644.  * \brief  handle built-in symbols on Z8
  2645.  * \param  pArg source code argument
  2646.  * \param  pResult result buffer
  2647.  * ------------------------------------------------------------------------ */
  2648.  
  2649. static void InternSymbol_Z8(char *pArg, TempResult *pResult)
  2650. {
  2651.   Byte RegNum;
  2652.  
  2653.   if (IsWRegCore(pArg, &RegNum))
  2654.   {
  2655.     pResult->Typ = TempReg;
  2656.     pResult->DataSize = eSymbolSize8Bit;
  2657.     pResult->Contents.RegDescr.Reg = RegNum;
  2658.     pResult->Contents.RegDescr.Dissect = DissectReg_Z8;
  2659.     pResult->Contents.RegDescr.compare = NULL;
  2660.   }
  2661.   else if (IsWRRegCore(pArg, &RegNum))
  2662.   {
  2663.     pResult->Typ = TempReg;
  2664.     pResult->DataSize = eSymbolSize16Bit;
  2665.     pResult->Contents.RegDescr.Reg = RegNum;
  2666.     pResult->Contents.RegDescr.Dissect = DissectReg_Z8;
  2667.     pResult->Contents.RegDescr.compare = NULL;
  2668.   }
  2669. }
  2670.  
  2671. static void MakeCode_Z8(void)
  2672. {
  2673.   CodeLen = 0; DontPrint = False; OpSize = eSymbolSize8Bit;
  2674.  
  2675.   /* zu ignorierendes */
  2676.  
  2677.   if (Memo("")) return;
  2678.  
  2679.   /* Pseudo Instructions */
  2680.  
  2681.   if (DecodeIntelPseudo(True))
  2682.     return;
  2683.  
  2684.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  2685.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  2686. }
  2687.  
  2688. static void InitCode_Z8(void)
  2689. {
  2690.   RPVal = 0;
  2691. }
  2692.  
  2693. static Boolean IsDef_Z8(void)
  2694. {
  2695.   return (Memo("SFR") || Memo("REG") || Memo("DEFBIT"));
  2696. }
  2697.  
  2698. static void SwitchFrom_Z8(void)
  2699. {
  2700.   DeinitFields();
  2701. }
  2702.  
  2703. static void AdaptRP01(void)
  2704. {
  2705.   /* SRP on Super8 sets RP0 & RP1.  Act similar for ASSUME on Super8: */
  2706.  
  2707.   if (RPVal >= 0x100)
  2708.     RP0Val = RP1Val = RPVal;
  2709.   else
  2710.   {
  2711.     RP0Val = RPVal;
  2712.     RP1Val = RPVal + 8;
  2713.   }
  2714. }
  2715.  
  2716. #define ASSUMEeZ8Count 1
  2717. #define ASSUMESuper8Count 3
  2718. static ASSUMERec ASSUMEeZ8s[] =
  2719. {
  2720.   {"RP"  , &RPVal  , 0, 0xff, 0x100, AdaptRP01},
  2721.   {"RP0" , &RP0Val , 0, 0xff, 0x100, NULL},
  2722.   {"RP1" , &RP1Val , 0, 0xff, 0x100, NULL}
  2723. };
  2724.  
  2725. /*!------------------------------------------------------------------------
  2726.  * \fn     SwitchTo_Z8(void *pUser)
  2727.  * \brief  prepare to assemble code for this target
  2728.  * \param  pUser CPU properties
  2729.  * ------------------------------------------------------------------------ */
  2730.  
  2731. static void SwitchTo_Z8(void *pUser)
  2732. {
  2733.   const TFamilyDescr *pDescr;
  2734.  
  2735.   TurnWords = False;
  2736.   SetIntConstMode(eIntConstModeIntel);
  2737.  
  2738.   pCurrCPUProps = (const tCPUProps*)pUser;
  2739.  
  2740.   if (mIsSuper8())
  2741.     pDescr = FindFamilyByName("Super8");
  2742.   else if (mIsZ8Encore())
  2743.     pDescr = FindFamilyByName("eZ8");
  2744.   else
  2745.     pDescr = FindFamilyByName("Z8");
  2746.  
  2747.   PCSymbol = "$"; HeaderID = pDescr->Id;
  2748.   NOPCode = mIsZ8Encore() ? 0x0f : 0xff;
  2749.   DivideChars = ","; HasAttrs = False;
  2750.  
  2751.   ValidSegs = (1 << SegCode) | (1 << SegData);
  2752.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  2753.   SegLimits[SegCode] = 0xffff;
  2754.   Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegData] = 0;
  2755.   if (pCurrCPUProps->CoreFlags & eCoreZ8Encore)
  2756.   {
  2757.     RegSpaceType = UInt12;
  2758.     SegLimits[SegData] = 0xfff;
  2759.     ValidSegs |= 1 << SegXData;
  2760.     Grans[SegXData] = 1; ListGrans[SegXData] = 1; SegInits[SegXData] = 0;
  2761.     SegLimits[SegXData] = 0xffff;
  2762.   }
  2763.   else
  2764.   {
  2765.     RegSpaceType = UInt8;
  2766.     SegLimits[SegData] = 0xff;
  2767.   }
  2768.  
  2769.   pASSUMERecs = ASSUMEeZ8s;
  2770.   ASSUMERecCnt = mIsSuper8() ? ASSUMESuper8Count : ASSUMEeZ8Count;
  2771.  
  2772.   MakeCode = MakeCode_Z8;
  2773.   IsDef = IsDef_Z8;
  2774.   InternSymbol = InternSymbol_Z8;
  2775.   DissectReg = DissectReg_Z8;
  2776.   DissectBit = DissectBit_Z8;
  2777.   SwitchFrom = SwitchFrom_Z8;
  2778.   InitFields();
  2779. }
  2780.  
  2781. /*!------------------------------------------------------------------------
  2782.  * \fn     codez8_init(void)
  2783.  * \brief  register target to AS
  2784.  * ------------------------------------------------------------------------ */
  2785.  
  2786. static const tCPUProps CPUProps[] =
  2787. {
  2788.   { "Z8601"    , eCoreZ8NMOS   , 0xe0,  0x7f,  0xf0 },
  2789.   { "Z8603"    , eCoreZ8NMOS   , 0xe0,  0x7f,  0xf0 },
  2790.   { "Z86C03"   , eCoreZ8CMOS   , 0xe0,  0x3f,  0xf0 },
  2791.   { "Z86E03"   , eCoreZ8CMOS   , 0xe0,  0x3f,  0xf0 },
  2792. /*{ "Z8604"    , eCoreZ8       , 0xe0,  0x7f,  0xf0 },*/
  2793.   { "Z86C06"   , eCoreZ8CMOS   , 0xe0,  0x7f,  0xf0 },
  2794.   { "Z86E06"   , eCoreZ8CMOS   , 0xe0,  0x7f,  0xf0 },
  2795.   { "Z86C08"   , eCoreZ8CMOS   , 0xe0,  0x7f,  0xf0 },
  2796.   { "Z86C30"   , eCoreZ8CMOS   , 0xe0,  0xef,  0xf0 },
  2797.   { "Z86C21"   , eCoreZ8CMOS   , 0xe0,  0xef,  0xf0 },
  2798.   { "Z86E21"   , eCoreZ8CMOS   , 0xe0,  0xef,  0xf0 },
  2799.   { "Z86C31"   , eCoreZ8CMOS   , 0xe0,  0x7f,  0xf0 },
  2800.   { "Z86C32"   , eCoreZ8CMOS   , 0xe0,  0xef,  0xf0 },
  2801.   { "Z86C40"   , eCoreZ8CMOS   , 0xe0,  0xef,  0xf0 },
  2802.   { "Z88C00"   , eCoreSuper8   , 0xc0,  0xbf,  0xe0 },
  2803.   { "Z88C01"   , eCoreSuper8   , 0xc0,  0xbf,  0xe0 },
  2804.   { "eZ8"      , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
  2805.   { "Z8F0113"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
  2806.   { "Z8F011A"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
  2807.   { "Z8F0123"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
  2808.   { "Z8F012A"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
  2809.   { "Z8F0130"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
  2810.   { "Z8F0131"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
  2811.   { "Z8F0213"  , eCoreZ8Encore , 0xee0, 0x1ff, 0xf00 },
  2812.   { "Z8F021A"  , eCoreZ8Encore , 0xee0, 0x1ff, 0xf00 },
  2813.   { "Z8F0223"  , eCoreZ8Encore , 0xee0, 0x1ff, 0xf00 },
  2814.   { "Z8F022A"  , eCoreZ8Encore , 0xee0, 0x1ff, 0xf00 },
  2815.   { "Z8F0230"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
  2816.   { "Z8F0231"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
  2817.   { "Z8F0411"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
  2818.   { "Z8F0412"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
  2819.   { "Z8F0413"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
  2820.   { "Z8F041A"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
  2821.   { "Z8F0421"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
  2822.   { "Z8F0422"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
  2823.   { "Z8F0423"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
  2824.   { "Z8F042A"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
  2825.   { "Z8F0430"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
  2826.   { "Z8F0431"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
  2827.   { "Z8F0811"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
  2828.   { "Z8F0812"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
  2829.   { "Z8F0813"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
  2830.   { "Z8F081A"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
  2831.   { "Z8F0821"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
  2832.   { "Z8F0822"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
  2833.   { "Z8F0823"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
  2834.   { "Z8F082A"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
  2835.   { "Z8F0830"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
  2836.   { "Z8F0831"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
  2837.   { "Z8F0880"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
  2838.   { "Z8F1232"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
  2839.   { "Z8F1233"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
  2840.   { "Z8F1621"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
  2841.   { "Z8F1622"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
  2842.   { "Z8F1680"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
  2843.   { "Z8F1681"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
  2844.   { "Z8F1682"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
  2845.   { "Z8F2421"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
  2846.   { "Z8F2422"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
  2847.   { "Z8F2480"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
  2848.   { "Z8F3221"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
  2849.   { "Z8F3222"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
  2850.   { "Z8F3281"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
  2851.   { "Z8F3282"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
  2852.   { "Z8F4821"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
  2853.   { "Z8F4822"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
  2854.   { "Z8F4823"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
  2855.   { "Z8F6081"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
  2856.   { "Z8F6082"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
  2857.   { "Z8F6421"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
  2858.   { "Z8F6422"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
  2859.   { "Z8F6423"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
  2860.   { "Z8F6481"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
  2861.   { "Z8F6482"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
  2862.   { NULL       , eCoreNone     , 0x00,  0x00, 0x000 }
  2863. };
  2864.  
  2865. void codez8_init(void)
  2866. {
  2867.   const tCPUProps *pRun;
  2868.  
  2869.   for (pRun = CPUProps; pRun->pName; pRun++)
  2870.     (void)AddCPUUser(pRun->pName, SwitchTo_Z8, (void*)pRun, NULL);
  2871.  
  2872.   AddInitPassProc(InitCode_Z8);
  2873. }
  2874.