Subversion Repositories pentevo

Rev

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

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