Subversion Repositories pentevo

Rev

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

  1. /* code78c10.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator NEC uPD78(C)(0|1)x                                          */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <ctype.h>
  13. #include <string.h>
  14.  
  15. #include "bpemu.h"
  16. #include "strutil.h"
  17. #include "asmdef.h"
  18. #include "asmsub.h"
  19. #include "asmpars.h"
  20. #include "asmstructs.h"
  21. #include "asmitree.h"
  22. #include "asmcode.h"
  23. #include "codepseudo.h"
  24. #include "intpseudo.h"
  25. #include "codevars.h"
  26. #include "errmsg.h"
  27. #include "headids.h"
  28.  
  29. #include "code78c10.h"
  30.  
  31. /*---------------------------------------------------------------------------*/
  32.  
  33. typedef struct
  34. {
  35.   const char *p_name;
  36.   Byte code;
  37. } intflag_t;
  38.  
  39. typedef struct
  40. {
  41.   const char name[5];
  42.   Byte code, flags;
  43. } reg_t;
  44.  
  45. typedef struct
  46. {
  47.   const char *p_name;
  48.   Byte code, flags, core_mask;
  49. } sreg_t;
  50.  
  51. typedef struct
  52. {
  53.   const char *pName;
  54.   Byte Code;
  55.   Byte MayIndirect;
  56. } tAdrMode;
  57.  
  58. typedef enum
  59. {
  60.   eCoreNone,
  61.   eCore7800Low,
  62.   eCore7800High,
  63.   eCore7807,
  64.   eCore7810
  65. } tCore;
  66.  
  67. #define core_mask_no_low ((1 << eCore7800High) | (1 << eCore7807) | (1 << eCore7810))
  68. #define core_mask_7800 ((1 << eCore7800Low) | (1 << eCore7800High))
  69. #define core_mask_7800_low (1 << eCore7800Low)
  70. #define core_mask_7800_high (1 << eCore7800High)
  71. #define core_mask_7807 (1 << eCore7807)
  72. #define core_mask_7810 (1 << eCore7810)
  73. #define core_mask_7807_7810 ((1 << eCore7807) | (1 << eCore7810))
  74. #define core_mask_all ((1 << eCore7800Low) | (1 << eCore7800High) | (1 << eCore7807) | (1 << eCore7810))
  75. #define core_mask_cmos 0x80
  76.  
  77. enum
  78. {
  79.   eFlagHasV = 1 << 0,
  80.   eFlagCMOS = 1 << 1,
  81.   eFlagSR   = 1 << 2, /* sr  -> may be written from A */
  82.   eFlagSR1  = 1 << 3, /* sr1 -> may be read to A */
  83.   eFlagSR2  = 1 << 4, /* sr2 -> load or read/modify/write with immediate */
  84.   eFlagSR3  = 1 << 5, /* sr3 -> may be written from EA */
  85.   eFlagSR4  = 1 << 6  /* sr4 -> may be read to EA */
  86. };
  87.  
  88. /* Flags in high byte of ALU operations: */
  89.  
  90. #define ALUImm_SR (1 << 0)
  91. #define ALUReg_Src (1 << 1)
  92. #define ALUReg_Dest (1 << 2)
  93. #define ALUReg_MayZ80 (1 << 3)
  94.  
  95. typedef struct
  96. {
  97.   char Name[6];
  98.   Byte Core;
  99.   Byte Flags;
  100. } tCPUProps;
  101.  
  102. typedef enum { e_decode_reg_unknown, e_decode_reg_ok, e_decode_reg_error } decode_reg_res_t;
  103.  
  104. typedef struct
  105. {
  106.   Word code;
  107.   unsigned core_mask;
  108. } order_t;
  109.  
  110. typedef enum
  111. {
  112.   e_mod_none = -1,
  113.   e_mod_reg8 = 0,
  114.   e_mod_reg16 = 1,
  115.   e_mod_imm = 2,
  116.   e_mod_indir = 3,
  117.   e_mod_wa = 4,
  118.   e_mod_abs = 5,
  119.   e_mod_sreg8 = 6,
  120.   e_mod_sreg16 = 7
  121. } z80_adr_mode_t;
  122.  
  123. #define MModReg8 (1 << e_mod_reg8)
  124. #define MModReg16 (1 << e_mod_reg16)
  125. #define MModImm (1 << e_mod_imm)
  126. #define MModIndir (1 << e_mod_indir)
  127. #define MModWA (1 << e_mod_wa)
  128. #define MModAbs (1 << e_mod_abs)
  129. #define MModSReg8 (1 << e_mod_sreg8)
  130. #define MModSReg16 (1 << e_mod_sreg16)
  131.  
  132. #define REG_V 0
  133. #define REG_A 1
  134. #define REG_B 2
  135. #define REG_C 3
  136. #define REG_D 4
  137. #define REG_H 6
  138. #define REG_EAH 8
  139. #define REG_BC 1
  140. #define REG_DE 2
  141. #define REG_HL 3
  142. #define REG_EA 4
  143.  
  144. typedef struct
  145. {
  146.   z80_adr_mode_t mode;
  147.   unsigned count;
  148.   Boolean force_long;
  149.   Byte val, vals[2];
  150. } z80_adr_vals_t;
  151.  
  152. static Boolean is_7807_781x;
  153.  
  154. static LongInt WorkArea;
  155.  
  156. static const tCPUProps *pCurrCPUProps;
  157.  
  158. static order_t *fixed_orders, *reg2_orders;
  159. static sreg_t *s_regs8, *s_regs16;
  160. static intflag_t *int_flags;
  161. static tSymbolSize z80_op_size, z80_def_op_size;
  162.  
  163. /*--------------------------------------------------------------------------------*/
  164.  
  165. /*!------------------------------------------------------------------------
  166.  * \fn     check_core(unsigned core_mask)
  167.  * \brief  check whether active target uses given core
  168.  * \param  core_mask list of allowed cores
  169.  * \return True if OK
  170.  * ------------------------------------------------------------------------ */
  171.  
  172. static Boolean check_core(unsigned core_mask)
  173. {
  174.   if ((core_mask & core_mask_cmos) && !(pCurrCPUProps->Flags & eFlagCMOS))
  175.     return False;
  176.   return !!((core_mask >> pCurrCPUProps->Core) & 1);
  177. }
  178.  
  179. /*!------------------------------------------------------------------------
  180.  * \fn     decode_reg8(const char *p_arg, Byte *p_res)
  181.  * \brief  decode 8 bit register
  182.  * \param  p_arg source argument
  183.  * \param  p_res encoded name
  184.  * \return True if valid name
  185.  * ------------------------------------------------------------------------ */
  186.  
  187. static Boolean decode_reg8(const char *p_arg, Byte *p_res)
  188. {
  189.   switch (strlen(p_arg))
  190.   {
  191.     case 1:
  192.     {
  193.       static const char names[] = "VABCDEHL";
  194.       const char *p;
  195.       int no_v = !(pCurrCPUProps->Flags & eFlagHasV);
  196.  
  197.       p = strchr(&names[no_v], as_toupper(*p_arg));
  198.       if (!p)
  199.         return False;
  200.       *p_res = p - names;
  201.       return True;
  202.     }
  203.     case 3:
  204.       if (!is_7807_781x
  205.        || (as_toupper(p_arg[0]) != 'E')
  206.        || (as_toupper(p_arg[1]) != 'A'))
  207.         return False;
  208.       if (as_toupper(p_arg[2]) == 'L')
  209.         *p_res = REG_EAH + 1;
  210.       else if (as_toupper(p_arg[2]) == 'H')
  211.         *p_res = REG_EAH;
  212.       else
  213.         return False;
  214.       return True;
  215.     default:
  216.       return False;
  217.   }
  218. }
  219.  
  220. /*!------------------------------------------------------------------------
  221.  * \fn     decode_r(const tStrComp *p_arg, Byte *p_res)
  222.  * \brief  decode name of 8 bit register
  223.  * \param  p_arg source argument
  224.  * \param  p_res return buffer
  225.  * \return e_decode_reg_ok -> register known & OK
  226.  * ------------------------------------------------------------------------ */
  227.  
  228. static decode_reg_res_t decode_r(const tStrComp *p_arg, Byte *p_res)
  229. {
  230.   if (!decode_reg8(p_arg->str.p_str, p_res))
  231.     return e_decode_reg_unknown;
  232.   if (*p_res >= 8)
  233.   {
  234.     WrStrErrorPos(ErrNum_InvReg, p_arg);
  235.     return e_decode_reg_error;
  236.   }
  237.   else
  238.     return e_decode_reg_ok;
  239. }
  240.  
  241. /*!------------------------------------------------------------------------
  242.  * \fn     decode_r1(const tStrComp *p_arg, Byte *p_res)
  243.  * \brief  decode name of 8 bit register, plus EAL/H on 78C1x
  244.  * \param  p_arg source argument
  245.  * \param  p_res return buffer
  246.  * \return e_decode_reg_ok -> register known & OK
  247.  * ------------------------------------------------------------------------ */
  248.  
  249. static decode_reg_res_t decode_r1(const tStrComp *p_arg, Byte *p_res)
  250. {
  251.   if (!decode_reg8(p_arg->str.p_str, p_res))
  252.     return e_decode_reg_unknown;
  253.   if (*p_res < 2)
  254.   {
  255.     WrStrErrorPos(ErrNum_InvReg, p_arg);
  256.     return e_decode_reg_error;
  257.   }
  258.   *p_res &= 7;
  259.   return e_decode_reg_ok;
  260. }
  261.  
  262. /*!------------------------------------------------------------------------
  263.  * \fn     decode_r2(const tStrComp *p_arg, Byte *p_res)
  264.  * \brief  decode name of 8 bit register A, B, or C
  265.  * \param  p_arg source argument
  266.  * \param  p_res return buffer
  267.  * \return e_decode_reg_ok -> register known & OK
  268.  * ------------------------------------------------------------------------ */
  269.  
  270. static decode_reg_res_t decode_r2(const tStrComp *p_arg, Byte *p_res)
  271. {
  272.   if (!decode_reg8(p_arg->str.p_str, p_res))
  273.     return e_decode_reg_unknown;
  274.   if ((*p_res == 0) || (*p_res >= 4))
  275.   {
  276.     WrStrErrorPos(ErrNum_InvReg, p_arg);
  277.     return e_decode_reg_error;
  278.   }
  279.   return e_decode_reg_ok;
  280. }
  281.  
  282. /*!------------------------------------------------------------------------
  283.  * \fn     decode_reg16(char *p_arg, Byte *p_res, Boolean allow_single_letter)
  284.  * \brief  decode 16 bit register argument
  285.  * \param  p_arg source argument
  286.  * \param  p_res result value
  287.  * \param  allow_single_letter allow register names with single letters (not for Z80 syntax)
  288.  * \return True if success
  289.  * ------------------------------------------------------------------------ */
  290.  
  291. static Boolean decode_reg16(char *p_arg, Byte *p_res, Boolean allow_single_letter)
  292. {
  293.   static const reg_t regs[] =
  294.   {
  295.     { "SP" , 0, 0 },
  296.     { "B"  , REG_BC, 0 },
  297.     { "BC" , REG_BC, 0 },
  298.     { "D"  , REG_DE, 0 },
  299.     { "DE" , REG_DE, 0 },
  300.     { "H"  , REG_HL, 0 },
  301.     { "HL" , REG_HL, 0 },
  302.     { "EA" , REG_EA, 0 },
  303.     { ""   , 0, 0 },
  304.   };
  305.  
  306.   for (*p_res = 0; regs[*p_res].name[0]; (*p_res)++)
  307.     if (!as_strcasecmp(p_arg, regs[*p_res].name))
  308.     {
  309.       if (!p_arg[1] && !allow_single_letter)
  310.         return False;
  311.       *p_res = regs[*p_res].code;
  312.       return True;
  313.     }
  314.   return False;
  315. }
  316.  
  317. /*!------------------------------------------------------------------------
  318.  * \fn     Decode_rp(char *Asc, Byte *Erg)
  319.  * \brief  decode rp2 argument (SP/BC/DE/HL/EA)
  320.  * \param  Asc source argument
  321.  * \param  Erg resulting register #
  322.  * \return True if success
  323.  * ------------------------------------------------------------------------ */
  324.  
  325. static Boolean Decode_rp2(char *p_arg, Byte *p_res)
  326. {
  327.   return decode_reg16(p_arg, p_res, True);
  328. }
  329.  
  330. /*!------------------------------------------------------------------------
  331.  * \fn     Decode_rp(char *Asc, Byte *Erg)
  332.  * \brief  decode rp argument (SP/BC/DE/HL)
  333.  * \param  Asc source argument
  334.  * \param  Erg resulting register #
  335.  * \return True if success
  336.  * ------------------------------------------------------------------------ */
  337.  
  338. static Boolean Decode_rp(char *Asc, Byte *Erg)
  339. {
  340.   if (!Decode_rp2(Asc, Erg)) return False;
  341.   return (*Erg < 4);
  342. }
  343.  
  344. /*!------------------------------------------------------------------------
  345.  * \fn     Decode_rp1(char *Asc, Byte *Erg)
  346.  * \brief  decode rp1 argument (VA/BC/DE/HL/EA)
  347.  * \param  Asc source argument
  348.  * \param  Erg resulting register #
  349.  * \return True if success
  350.  * ------------------------------------------------------------------------ */
  351.  
  352. static Boolean Decode_rp1(char *Asc, Byte *Erg)
  353. {
  354.   if (!as_strcasecmp(Asc, "V")) *Erg = 0;
  355.   else
  356.   {
  357.     if (!Decode_rp2(Asc, Erg)) return False;
  358.     return (*Erg != 0);
  359.   }
  360.   return True;
  361. }
  362.  
  363. /*!------------------------------------------------------------------------
  364.  * \fn     Decode_rp3(char *Asc, Byte *Erg)
  365.  * \brief  decode rp3 argument (BC/DE/HL)
  366.  * \param  Asc source argument
  367.  * \param  Erg resulting register #
  368.  * \return True if success
  369.  * ------------------------------------------------------------------------ */
  370.  
  371. static Boolean Decode_rp3(char *Asc, Byte *Erg)
  372. {
  373.   if (!Decode_rp2(Asc, Erg)) return False;
  374.   return ((*Erg < 4) && (*Erg > 0));
  375. }
  376.  
  377. /*!------------------------------------------------------------------------
  378.  * \fn     parse_rpa(const tStrComp *p_arg, z80_adr_vals_t *p_vals, unsigned mode_mask, int *p_auto_val, Boolean force)
  379.  * \brief  parse indirect address expression
  380.  * \param  p_arg source argument
  381.  * \param  p_vals buffer for parse result
  382.  * \param  mode_mask allowed addressing modes
  383.  * \param  p_auto_val returns auto-in/decrement value
  384.  * \param  force assume expression is indirect, even without outer (...)
  385.  * \return True if expression was detected as indirect (parsing may still have failed)
  386.  * ------------------------------------------------------------------------ */
  387.  
  388. static int split_auto_val(tStrComp *p_arg)
  389. {
  390.   int l = strlen(p_arg->str.p_str);
  391.  
  392.   if (l >= 2)
  393.   {
  394.     if (!strcmp(p_arg->str.p_str + l - 2, "--"))
  395.     {
  396.       StrCompShorten(p_arg, 2);
  397.       return - 2;
  398.     }
  399.     if (!strcmp(p_arg->str.p_str + l - 2, "++"))
  400.     {
  401.       StrCompShorten(p_arg, 2);
  402.       return + 2;
  403.     }
  404.   }
  405.  
  406.   if (l >= 1)
  407.   {
  408.     if (p_arg->str.p_str[l - 1] == '-')
  409.     {
  410.       StrCompShorten(p_arg, 1);
  411.       return -1;
  412.     }
  413.     if (p_arg->str.p_str[l - 1] == '+')
  414.     {
  415.       StrCompShorten(p_arg, 1);
  416.       return +1;
  417.     }
  418.   }
  419.  
  420.   return 0;
  421. }
  422.  
  423. typedef struct
  424. {
  425.   as_eval_cb_data_t cb_data;
  426.   Byte base, index;
  427. } upd78_eval_cb_data_t;
  428.  
  429. DECLARE_AS_EVAL_CB(upd78_eval_cb)
  430. {
  431.   upd78_eval_cb_data_t *p_upd78_eval_cb_data = (upd78_eval_cb_data_t*)p_data;
  432.   Byte reg;
  433.   Boolean bad_reg = False;
  434.  
  435.   /* 8 bit register? Note that a B/D/H may actually mean BC/DE/HL
  436.      in 'old syntax': */
  437.  
  438.   if (decode_reg8(p_arg->str.p_str, &reg))
  439.   {
  440.     if (!as_eval_cb_data_stack_plain_add(p_data->p_stack))
  441.       bad_reg = True;
  442.     else switch (reg)
  443.     {
  444.       case REG_A:
  445.         if (p_upd78_eval_cb_data->index)
  446.           bad_reg = True;
  447.         else
  448.           p_upd78_eval_cb_data->index = reg;
  449.         break;
  450.       case REG_B:
  451.         if (!p_upd78_eval_cb_data->index)
  452.           p_upd78_eval_cb_data->index = reg;
  453.         else if (!p_upd78_eval_cb_data->base)
  454.           p_upd78_eval_cb_data->base = REG_BC;
  455.         else
  456.           bad_reg = True;
  457.         break;
  458.       case REG_D:
  459.         if (!p_upd78_eval_cb_data->base)
  460.           p_upd78_eval_cb_data->base = REG_DE;
  461.         else
  462.           bad_reg = True;
  463.         break;
  464.       case REG_H:
  465.         if (!p_upd78_eval_cb_data->base)
  466.           p_upd78_eval_cb_data->base = REG_HL;
  467.         else
  468.           bad_reg = True;
  469.         break;
  470.       default:
  471.         bad_reg = True;
  472.     }
  473.   }
  474.  
  475.   /* 16 bit register? */
  476.  
  477.   else if (decode_reg16(p_arg->str.p_str, &reg, False))
  478.   {
  479.     if (!as_eval_cb_data_stack_plain_add(p_data->p_stack))
  480.       bad_reg = True;
  481.     else switch (reg)
  482.     {
  483.       case REG_EA:
  484.         if (p_upd78_eval_cb_data->index)
  485.           bad_reg = True;
  486.         else
  487.           p_upd78_eval_cb_data->index = reg;
  488.         break;
  489.       case REG_BC:
  490.       case REG_DE:
  491.       case REG_HL:
  492.         if (p_upd78_eval_cb_data->base)
  493.           bad_reg = True;
  494.         else
  495.           p_upd78_eval_cb_data->base = reg;
  496.         break;
  497.       default:
  498.         bad_reg = True;
  499.     }
  500.   }
  501.  
  502.   /* neither -> tell parser to evaluate as displacement */
  503.  
  504.   else
  505.     return e_eval_none;
  506.  
  507.   /* register, but invalid usage -> tell parser to terminate */
  508.  
  509.   if (bad_reg)
  510.   {
  511.     WrStrErrorPos(ErrNum_InvReg, p_arg);
  512.     return e_eval_fail;
  513.   }
  514.  
  515.   /* all fine -> tell parser to treat as zero */
  516.  
  517.   as_tempres_set_int(p_res, 0);
  518.   return e_eval_ok;
  519. }
  520.  
  521. static void parse_indirect_list(z80_adr_vals_t *p_vals, const tStrComp *p_arg, unsigned mode_mask, int auto_val)
  522. {
  523.   tEvalResult eval_result;
  524.   upd78_eval_cb_data_t upd78_eval_cb_data;
  525.   LongInt disp_acc = 0;
  526.   Boolean first_unknown;
  527.  
  528.   as_eval_cb_data_ini(&upd78_eval_cb_data.cb_data, upd78_eval_cb);
  529.   upd78_eval_cb_data.base =
  530.   upd78_eval_cb_data.index = 0;
  531.  
  532.   /* Parse expression and filter out register components by callback */
  533.  
  534.   disp_acc = EvalStrIntExprWithResultAndCallback(p_arg, Int16, &eval_result, &upd78_eval_cb_data.cb_data);
  535.   if (!eval_result.OK)
  536.     return;
  537.   first_unknown = mFirstPassUnknownOrQuestionable(eval_result.Flags);
  538.  
  539.   /* Dissolve ambiguities */
  540.  
  541.   if ((upd78_eval_cb_data.index == REG_B) && !upd78_eval_cb_data.base)
  542.   {
  543.     upd78_eval_cb_data.index = 0;
  544.     upd78_eval_cb_data.base = REG_BC;
  545.   }
  546.  
  547.   /* For auto-in/decrement, only a plain base register DE/HL is allowed.
  548.      Furthermore, (..)-- is not implemented: */
  549.  
  550.   if (auto_val)
  551.   {
  552.     if (upd78_eval_cb_data.index || (upd78_eval_cb_data.base < REG_BC) || (upd78_eval_cb_data.base > REG_HL) || disp_acc || (auto_val == -2))
  553.       WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  554.     else
  555.     {
  556.       p_vals->val = (upd78_eval_cb_data.base + 2) + (2 * !!(auto_val < 0));
  557.       p_vals->mode = e_mod_indir;
  558.     }
  559.   }
  560.   else
  561.   {
  562.     /* (BC) (DE) (HL) */
  563.     if ((upd78_eval_cb_data.base >= REG_BC) && (upd78_eval_cb_data.base <= REG_HL) && !upd78_eval_cb_data.index && !disp_acc)
  564.     {
  565.       p_vals->val = upd78_eval_cb_data.base;
  566.       p_vals->mode = e_mod_indir;
  567.     }
  568.     /* (DE+byte) (HL+byte) */
  569.     else if ((upd78_eval_cb_data.base >= REG_DE) && (upd78_eval_cb_data.base <= REG_HL) && !upd78_eval_cb_data.index)
  570.     {
  571.       if (first_unknown)
  572.         disp_acc &= 0xff;
  573.       if ((disp_acc > 0xff) || (disp_acc < -0x80))
  574.       {
  575.         WrStrErrorPos(ErrNum_OverRange, p_arg);
  576.         return;
  577.       }
  578.       p_vals->val = (upd78_eval_cb_data.base << 2) + 3;
  579.       p_vals->mode = e_mod_indir;
  580.       p_vals->vals[p_vals->count++] = Lo(disp_acc);
  581.     }
  582.     /* (HL+A) (HL+B) */
  583.     else if ((upd78_eval_cb_data.base == REG_HL) && (upd78_eval_cb_data.index >= REG_A) && (upd78_eval_cb_data.index <= REG_B) && !disp_acc)
  584.     {
  585.       p_vals->val = upd78_eval_cb_data.index + 11;
  586.       p_vals->mode = e_mod_indir;
  587.     }
  588.     /* (HL+EA) */
  589.     else if ((upd78_eval_cb_data.base == REG_HL) && (upd78_eval_cb_data.index == REG_EA) && !disp_acc)
  590.     {
  591.       p_vals->val = 14;
  592.       p_vals->mode = e_mod_indir;
  593.     }
  594.     /* abs/wa */
  595.     else if (!upd78_eval_cb_data.base && !upd78_eval_cb_data.index)
  596.     {
  597.       Boolean is_wa, may_wa = !!(mode_mask & MModWA);
  598.  
  599.       if (first_unknown)
  600.         disp_acc &= 0xff;
  601.       if ((disp_acc > 0xffff) || (disp_acc < 0))
  602.       {
  603.         WrStrErrorPos(ErrNum_OverRange, p_arg);
  604.         return;
  605.       }
  606.       is_wa = (Hi(disp_acc) == WorkArea);
  607.  
  608.       p_vals->vals[p_vals->count++] = Lo(disp_acc);
  609.       if ((may_wa && is_wa) || (!may_wa && first_unknown))
  610.         p_vals->mode = e_mod_wa;
  611.       else
  612.       {
  613.         p_vals->vals[p_vals->count++] = Hi(disp_acc);
  614.         p_vals->mode = e_mod_abs;
  615.       }
  616.     }
  617.     else
  618.       WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  619.   }
  620. }
  621.  
  622. static Boolean parse_rpa(const tStrComp *p_arg, z80_adr_vals_t *p_vals, unsigned mode_mask, int *p_auto_val, Boolean force)
  623. {
  624.   tStrComp arg;
  625.   Boolean is_indirect;
  626.  
  627.   /* split off auto-in/decrement */
  628.  
  629.   StrCompRefRight(&arg, p_arg, 0);
  630.   *p_auto_val = split_auto_val(&arg);
  631.  
  632.   /* Indirect? */
  633.  
  634.   is_indirect = IsIndirect(arg.str.p_str);
  635.   if (is_indirect)
  636.   {
  637.     StrCompIncRefLeft(&arg, 1);
  638.     StrCompShorten(&arg, 1);
  639.     KillPostBlanksStrComp(&arg);
  640.     if (!*p_auto_val)
  641.       *p_auto_val = split_auto_val(&arg);
  642.   }
  643.  
  644.   /* Auto-in/decrement enforces indirect parsing: */
  645.  
  646.   if (is_indirect || *p_auto_val || force)
  647.   {
  648.     parse_indirect_list(p_vals, &arg, mode_mask, *p_auto_val);
  649.     return True;
  650.   }
  651.   else
  652.     return False;
  653. }
  654.  
  655. /*!------------------------------------------------------------------------
  656.  * \fn     reset_z80_adr_vals(z80_adr_vals_t *p_vals)
  657.  * \brief  clear encoded addressing mode container
  658.  * \param  p_vals container to clear
  659.  * ------------------------------------------------------------------------ */
  660.  
  661. static void reset_z80_adr_vals(z80_adr_vals_t *p_vals)
  662. {
  663.   p_vals->mode = e_mod_none;
  664.   p_vals->force_long = 0;
  665.   p_vals->val = 0;
  666.   p_vals->count = 0;
  667. }
  668.  
  669. /*!------------------------------------------------------------------------
  670.  * \fn     Decode_rpa2(const tStrComp *pArg, Byte *Erg, Byte *Disp)
  671.  * \brief  Decode rpa2 argument (indirect 8 bit argument in memory)
  672.  * \param  pArg source argument
  673.  * \param  Erg resulting addressing mode
  674.  * \param  Disp resulting addressing displacement
  675.  * \return True if success
  676.  * ------------------------------------------------------------------------ */
  677.  
  678. static Boolean Decode_rpa2(const tStrComp *pArg, Byte *Erg, Byte *Disp)
  679. {
  680.   z80_adr_vals_t vals;
  681.   int auto_val;
  682.  
  683.   /* We force parsing as indirect, so the return value is always true: */
  684.  
  685.   reset_z80_adr_vals(&vals);
  686.   (void)parse_rpa(pArg, &vals, MModIndir, &auto_val, True);
  687.   switch (vals.mode)
  688.   {
  689.     case e_mod_indir:
  690.       if ((auto_val < -1) || (auto_val > 1))
  691.         goto bad_mode;
  692.       *Erg = vals.val;
  693.       *Disp = (vals.count > 0) ? vals.vals[0] : 0;
  694.       return True;
  695.     case e_mod_wa:
  696.     case e_mod_abs:
  697.     bad_mode:
  698.       WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  699.       return False;
  700.     default:
  701.       return False;
  702.   }
  703. }
  704.  
  705. /*!------------------------------------------------------------------------
  706.  * \fn     Decode_rpa(const tStrComp *pArg, Byte *Erg)
  707.  * \brief  Decode rpa argument (indirect 8 bit argument in memory, without index)
  708.  * \param  pArg source argument
  709.  * \param  Erg resulting addressing mode
  710.  * \return True if success
  711.  * ------------------------------------------------------------------------ */
  712.  
  713. static Boolean is_rpa(Byte value)
  714. {
  715.   return (value >= 1) && (value <= 7);
  716. }
  717.  
  718. static Boolean Decode_rpa(const tStrComp *pArg, Byte *Erg)
  719. {
  720.   Byte Dummy;
  721.  
  722.   if (!Decode_rpa2(pArg, Erg, &Dummy)) return False;
  723.   if (!is_rpa(*Erg))
  724.   {
  725.     WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  726.     return False;
  727.   }
  728.   return True;
  729. }
  730.  
  731. /*!------------------------------------------------------------------------
  732.  * \fn     Decode_rpa1(const tStrComp *pArg, Byte *Erg)
  733.  * \brief  Decode rpa1 argument (indirect 8 bit argument in memory, without index or auto-in/decrement)
  734.  * \param  pArg source argument
  735.  * \param  Erg resulting addressing mode
  736.  * \return True if success
  737.  * ------------------------------------------------------------------------ */
  738.  
  739. static Boolean is_rpa1(Byte value)
  740. {
  741.   return (value >= 1) && (value <= 3);
  742. }
  743.  
  744. static Boolean Decode_rpa1(const tStrComp *pArg, Byte *Erg)
  745. {
  746.   Byte Dummy;
  747.  
  748.   if (!Decode_rpa2(pArg, Erg, &Dummy)) return False;
  749.   if (!is_rpa1(*Erg))
  750.   {
  751.     WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  752.     return False;
  753.   }
  754.   return True;
  755. }
  756.  
  757. /*!------------------------------------------------------------------------
  758.  * \fn     Decode_rpa3(const tStrComp *pArg, Byte *Erg, ShortInt *Disp)
  759.  * \brief  Decode rpa3 argument (indirect 16 bit argument in memory)
  760.  * \param  pArg source argument
  761.  * \param  Erg resulting addressing mode
  762.  * \param  Disp resulting addressing displacement
  763.  * \return True if success
  764.  * ------------------------------------------------------------------------ */
  765.  
  766. static Boolean is_rpa3(Byte value)
  767. {
  768.   return ((value >= 2) && (value <= 5))
  769.       || ((value >= 11) && (value <= 15));
  770. }
  771.  
  772. static Boolean Decode_rpa3(const tStrComp *pArg, Byte *Erg, Byte *Disp)
  773. {
  774.   z80_adr_vals_t vals;
  775.   int auto_val;
  776.  
  777.   /* We force parsing as indirect, so the return value is always true: */
  778.  
  779.   reset_z80_adr_vals(&vals);
  780.   (void)parse_rpa(pArg, &vals, MModIndir, &auto_val, True);
  781.   switch (vals.mode)
  782.   {
  783.     case e_mod_indir:
  784.       if ((auto_val != -2) && (auto_val != 0) && (auto_val != 2))
  785.         goto bad_mode;
  786.       if (!is_rpa3(vals.val))
  787.         goto bad_mode;
  788.       *Erg = vals.val;
  789.       *Disp = (vals.count > 0) ? vals.vals[0] : 0;
  790.       return True;
  791.     case e_mod_wa:
  792.     case e_mod_abs:
  793.     bad_mode:
  794.       WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  795.       return False;
  796.     default:
  797.       return False;
  798.   }
  799. }
  800.  
  801. /*!------------------------------------------------------------------------
  802.  * \fn     Decode_f(char *Asc, Byte *Erg)
  803.  * \brief  descode status flag
  804.  * \param  Asc source argument
  805.  * \param  Erg returns encoded flag
  806.  * \return True if success
  807.  * ------------------------------------------------------------------------ */
  808.  
  809. static Boolean Decode_f(char *Asc, Byte *Erg)
  810. {
  811. #define FlagCnt 3
  812.   static const char Flags[FlagCnt][3] = {"CY", "HC", "Z"};
  813.  
  814.   for (*Erg = 0; *Erg < FlagCnt; (*Erg)++)
  815.    if (!as_strcasecmp(Flags[*Erg], Asc)) break;
  816.   *Erg += 2; return (*Erg <= 4);
  817. }
  818.  
  819. /*!------------------------------------------------------------------------
  820.  * \fn     decode_sr_core(const tStrComp *p_arg)
  821.  * \brief  core register list decode
  822.  * \param  p_arg source argument
  823.  * \return * to record of decoded register
  824.  * ------------------------------------------------------------------------ */
  825.  
  826. static const sreg_t *decode_sr_core(const sreg_t *p_sregs, const tStrComp *p_arg)
  827. {
  828.   for (; p_sregs->p_name; p_sregs++)
  829.     if (check_core(p_sregs->core_mask) && !as_strcasecmp(p_arg->str.p_str, p_sregs->p_name))
  830.       return p_sregs;
  831.   return NULL;
  832. }
  833.  
  834. /*!------------------------------------------------------------------------
  835.  * \fn     check_sr_flag(Byte reg_flags, Byte req_flag, const tStrComp *p_arg)
  836.  * \brief  check whether special register's flags fulfill requirement, and
  837.            issue error if not
  838.  * \param  reg_flags register's suppoerted flags
  839.  * \param  req_flag required flag
  840.  * \param  p_arg source argument
  841.  * \return True if OK
  842.  * ------------------------------------------------------------------------ */
  843.  
  844. static Boolean check_sr_flag(Byte reg_flags, Byte req_flag, const tStrComp *p_arg)
  845. {
  846.   if (reg_flags & req_flag)
  847.     return True;
  848.   WrStrErrorPos(reg_flags ? ErrNum_InvOpOnReg : ErrNum_InvReg, p_arg);
  849.   return False;
  850. }
  851.  
  852. static decode_reg_res_t decode_sr_flag(const tStrComp *p_arg, const sreg_t *p_sregs, Byte *p_res, Byte flag)
  853. {
  854.   const sreg_t *p_reg = decode_sr_core(p_sregs, p_arg);
  855.  
  856.   if (p_reg)
  857.   {
  858.     if (check_sr_flag(p_reg->flags, flag, p_arg))
  859.     {
  860.       *p_res = p_reg->code;
  861.       return e_decode_reg_ok;
  862.     }
  863.     else
  864.       return e_decode_reg_error;
  865.   }
  866.   else
  867.     return e_decode_reg_unknown;
  868. }
  869.  
  870. #define decode_sr1(p_arg, p_res) decode_sr_flag(p_arg, s_regs8, p_res, eFlagSR1)
  871. #define decode_sr(p_arg, p_res) decode_sr_flag(p_arg, s_regs8, p_res, eFlagSR)
  872. #define decode_sr2(p_arg, p_res) decode_sr_flag(p_arg, s_regs8, p_res, eFlagSR2)
  873.  
  874. /*!------------------------------------------------------------------------
  875.  * \fn     Decode_irf(const tStrComp *p_arg, ShortInt *p_res)
  876.  * \brief  decode interrupt flag argument
  877.  * \param  p_arg source argument
  878.  * \param  p_res resulting flag #
  879.  * \return True if success
  880.  * ------------------------------------------------------------------------ */
  881.  
  882. static Boolean Decode_irf(const tStrComp *p_arg, ShortInt *p_res)
  883. {
  884.   for (*p_res = 0; int_flags[*p_res].p_name; (*p_res)++)
  885.     if (!as_strcasecmp(int_flags[*p_res].p_name, p_arg->str.p_str))
  886.     {
  887.       *p_res = int_flags[*p_res].code;
  888.       return True;
  889.     }
  890.   WrStrErrorPos(ErrNum_UnknownInt, p_arg);
  891.   return False;
  892. }
  893.  
  894. /*!------------------------------------------------------------------------
  895.  * \fn     Decode_wa(const tStrComp *pArg, Byte *Erg, Byte max_address)
  896.  * \brief  decode working area address argument
  897.  * \param  pArg source argument
  898.  * \param  Erg resulting (short) address
  899.  * \param  max_address range limit
  900.  * \return True if success
  901.  * ------------------------------------------------------------------------ */
  902.  
  903. static Boolean Decode_wa(const tStrComp *pArg, Byte *Erg, Byte max_address)
  904. {
  905.   Word Adr;
  906.   Boolean OK;
  907.   tSymbolFlags Flags;
  908.  
  909.   Adr = EvalStrIntExpressionWithFlags(pArg, Int16, &OK, &Flags);
  910.   if (!OK)
  911.     return False;
  912.  
  913.   if (!mFirstPassUnknown(Flags) && (Hi(Adr) != WorkArea)) WrStrErrorPos(ErrNum_InAccPage, pArg);
  914.   *Erg = Lo(Adr);
  915.  
  916.   if (mFirstPassUnknownOrQuestionable(Flags))
  917.     *Erg &= max_address;
  918.  
  919.   return ChkRangePos(*Erg, 0, max_address, pArg);
  920. }
  921.  
  922. static Boolean HasDisp(ShortInt Mode)
  923. {
  924.   return ((Mode & 11) == 11);
  925. }
  926.  
  927. /*!------------------------------------------------------------------------
  928.  * \fn     set_op_size(tSymbolSize new_op_size, const tStrComp *p_arg)
  929.  * \brief  Set operand size and throw error in case of conflict
  930.  * \param  new_op_size operand size to set
  931.  * \param  p_arg source argument carrying this size
  932.  * ------------------------------------------------------------------------ */
  933.  
  934. static Boolean set_op_size(tSymbolSize new_op_size, const tStrComp *p_arg)
  935. {
  936.   if (z80_op_size == eSymbolSizeUnknown)
  937.     z80_op_size = new_op_size;
  938.   else if (z80_op_size != new_op_size)
  939.   {
  940.     WrStrErrorPos(ErrNum_ConfOpSizes, p_arg);
  941.     return False;
  942.   }
  943.   return True;
  944. }
  945.  
  946. /*!------------------------------------------------------------------------
  947.  * \fn     decode_z80_adr(const tStrComp *p_arg, z80_adr_vals_t *p_vals, unsigned mode_mask)
  948.  * \brief  decode Z80 style address expression
  949.  * \param  p_arg source argument
  950.  * \param  p_vals encoded values
  951.  * \param  mode_mask bit mask of allowe daddressing modes
  952.  * \return resulting addressing mode
  953.  * ------------------------------------------------------------------------ */
  954.  
  955. static z80_adr_mode_t decode_z80_adr(const tStrComp *p_arg, z80_adr_vals_t *p_vals, unsigned mode_mask)
  956. {
  957.   Boolean ok;
  958.   int auto_val;
  959.   const sreg_t *p_sreg;
  960.  
  961.   reset_z80_adr_vals(p_vals);
  962.  
  963.   /* Registers: */
  964.  
  965.   if (!as_strcasecmp(p_arg->str.p_str, ">A"))
  966.   {
  967.     if (set_op_size(eSymbolSize8Bit, p_arg))
  968.     {
  969.       p_vals->force_long = True;
  970.       p_vals->val = REG_A;
  971.       p_vals->mode = e_mod_reg8;
  972.     }
  973.     goto found;
  974.   }
  975.  
  976.   if (decode_reg8(p_arg->str.p_str, &p_vals->val))
  977.   {
  978.     /* No V register on low function core */
  979.     if ((pCurrCPUProps->Core == eCore7800Low) && (p_vals->val == REG_V));
  980.     /* EA register only on 7807++ */
  981.     else if ((pCurrCPUProps->Core < eCore7807) && (p_vals->val >= REG_EAH));
  982.     else
  983.     {
  984.       if (set_op_size(eSymbolSize8Bit, p_arg))
  985.         p_vals->mode = e_mod_reg8;
  986.       goto found;
  987.     }
  988.   }
  989.  
  990.   if (decode_reg16(p_arg->str.p_str, &p_vals->val, False))
  991.   {
  992.     /* EA register only on 7807++ */
  993.     if ((pCurrCPUProps->Core < eCore7807) && (p_vals->val >= REG_EA));
  994.     else
  995.     {
  996.       if (set_op_size(eSymbolSize16Bit, p_arg))
  997.         p_vals->mode = e_mod_reg16;
  998.       goto found;
  999.     }
  1000.   }
  1001.  
  1002.   p_sreg = decode_sr_core(s_regs8, p_arg);
  1003.   if (p_sreg)
  1004.   {
  1005.     if (set_op_size(eSymbolSize8Bit, p_arg))
  1006.     {
  1007.       p_vals->mode = e_mod_sreg8;
  1008.       p_vals->val = p_sreg->code;
  1009.       p_vals->vals[0] = p_sreg->flags;
  1010.     }
  1011.     goto found;
  1012.   }
  1013.  
  1014.   p_sreg = decode_sr_core(s_regs16, p_arg);
  1015.   if (p_sreg)
  1016.   {
  1017.     if (set_op_size(eSymbolSize16Bit, p_arg))
  1018.     {
  1019.       p_vals->mode = e_mod_sreg16;
  1020.       p_vals->val = p_sreg->code;
  1021.       p_vals->vals[0] = p_sreg->flags;
  1022.     }
  1023.     goto found;
  1024.   }
  1025.  
  1026.   /* indirect stuff: */
  1027.  
  1028.   if (parse_rpa(p_arg, p_vals, mode_mask, &auto_val, False))
  1029.   {
  1030.     /* single or double auto-in/decrement implicitly describes operand size: */
  1031.  
  1032.     if (auto_val)
  1033.     {
  1034.       if (!set_op_size(((auto_val == 1) || (auto_val == -1)) ? eSymbolSize8Bit : eSymbolSize16Bit, p_arg))
  1035.         reset_z80_adr_vals(p_vals);
  1036.     }
  1037.     goto found;
  1038.   }
  1039.  
  1040.   /* Immediate: */
  1041.  
  1042.   if (!(mode_mask & MModImm))
  1043.   {
  1044.     WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  1045.     goto found;
  1046.   }
  1047.   if (z80_op_size == eSymbolSizeUnknown)
  1048.   {
  1049.     z80_op_size = z80_def_op_size;
  1050.     z80_def_op_size = eSymbolSizeUnknown;
  1051.   }
  1052.   switch (z80_op_size)
  1053.   {
  1054.     case eSymbolSize8Bit:
  1055.       p_vals->vals[0] = EvalStrIntExpression(p_arg, Int8, &ok);
  1056.       if (ok)
  1057.       {
  1058.         p_vals->count = 1;
  1059.         p_vals->mode = e_mod_imm;
  1060.       }
  1061.       break;
  1062.     case eSymbolSize16Bit:
  1063.     {
  1064.       Word tmp = EvalStrIntExpression(p_arg, Int16, &ok);
  1065.       if (ok)
  1066.       {
  1067.         p_vals->vals[p_vals->count++] = Lo(tmp);
  1068.         p_vals->vals[p_vals->count++] = Hi(tmp);
  1069.         p_vals->mode = e_mod_imm;
  1070.       }
  1071.       break;
  1072.     }
  1073.     default:
  1074.       WrStrErrorPos(ErrNum_UndefOpSizes, p_arg);
  1075.   }
  1076.  
  1077. found:
  1078.   if ((p_vals->mode != e_mod_none) && !((mode_mask >> p_vals->mode) & 1))
  1079.   {
  1080.     WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  1081.     reset_z80_adr_vals(p_vals);
  1082.   }
  1083.   return p_vals->mode;
  1084. }
  1085.  
  1086. /*!------------------------------------------------------------------------
  1087.  * \fn     append_adr_vals(const z80_adr_vals_t *p_vals)
  1088.  * \brief  append encoded addess extension bytes to instruction
  1089.  * \param  p_vals contains bytes to append
  1090.  * ------------------------------------------------------------------------ */
  1091.  
  1092. static void append_adr_vals(const z80_adr_vals_t *p_vals)
  1093. {
  1094.   memcpy(&BAsmCode[CodeLen], p_vals->vals, p_vals->count);
  1095.   CodeLen += p_vals->count;
  1096. }
  1097.  
  1098. /*--------------------------------------------------------------------------*/
  1099. /* Bit Symbol Handling (uPD7807...7809 only) */
  1100.  
  1101. /*
  1102.  * Compact representation of bits in symbol table:
  1103.  * bits 0..2: bit position
  1104.  * bits 3...6/18: address in I/O or memory space
  1105.  * bit 19: 0 for memory space, 1 for I/O space
  1106.  * bits 20..23: core type
  1107.  */
  1108.  
  1109. /*!------------------------------------------------------------------------
  1110.  * \fn     eval_bit_position(const tStrComp *p_arg, Boolean *p_ok)
  1111.  * \brief  evaluate bit position
  1112.  * \param  bit position argument
  1113.  * \param  p_ok parsing OK?
  1114.  * \return numeric bit position
  1115.  * ------------------------------------------------------------------------ */
  1116.  
  1117. static LongWord eval_bit_position(const tStrComp *p_arg, Boolean *p_ok)
  1118. {
  1119.   return EvalStrIntExpression(p_arg, UInt3, p_ok);
  1120. }
  1121.  
  1122. /*!------------------------------------------------------------------------
  1123.  * \fn     assemble_bit_symbol(Byte core, Boolean is_io, Word address, Byte bit_pos)
  1124.  * \brief  transform bit symbol components into compact representation
  1125.  * \param  core core used to define this bit
  1126.  * \param  is_io special register or memory bit?
  1127.  * \param  address (I/O) register address
  1128.  * \param  bit_pos bit position
  1129.  * \return compact storage value
  1130.  * ------------------------------------------------------------------------ */
  1131.  
  1132. static LongWord assemble_bit_symbol(Byte core, Boolean is_io, Word address, Byte bit_pos)
  1133. {
  1134.   LongWord result = bit_pos | ((LongWord)address << 3);
  1135.  
  1136.   if (is_io)
  1137.     result |= 1ul << 19;
  1138.   result |= ((LongWord)core) << 20;
  1139.   return result;
  1140. }
  1141.  
  1142. /*!------------------------------------------------------------------------
  1143.  * \fn     decode_bit_arg_2(LongWord *p_result, const tStrComp *p_reg_arg, const tStrComp *p_bit_arg)
  1144.  * \brief  encode a bit symbol, address & bit position separated
  1145.  * \param  p_result resulting encoded bit
  1146.  * \param  p_reg_arg register argument
  1147.  * \param  p_bit_arg bit argument
  1148.  * \return True if success
  1149.  * ------------------------------------------------------------------------ */
  1150.  
  1151. static Boolean decode_bit_arg_2(LongWord *p_result, const tStrComp *p_reg_arg, const tStrComp *p_bit_arg)
  1152. {
  1153.   Boolean ok;
  1154.   LongWord addr;
  1155.   Boolean is_io;
  1156.   Byte bit_pos;
  1157.   Byte s_reg;
  1158.  
  1159.   bit_pos = eval_bit_position(p_bit_arg, &ok);
  1160.   if (!ok)
  1161.     return False;
  1162.  
  1163.   if (decode_sr_flag(p_reg_arg, s_regs8, &s_reg, eFlagSR2) == e_decode_reg_ok)
  1164.   {
  1165.     if (s_reg > 0x0f)
  1166.     {
  1167.       WrStrErrorPos(ErrNum_InvReg, p_reg_arg);
  1168.       return False;
  1169.     }
  1170.     is_io = True;
  1171.     addr = s_reg;
  1172.   }
  1173.  
  1174.   else
  1175.   {
  1176.     addr = EvalStrIntExpression(p_reg_arg, UInt16, &ok);
  1177.     if (!ok)
  1178.       return False;
  1179.     is_io = False;
  1180.   }
  1181.  
  1182.   *p_result = assemble_bit_symbol(pCurrCPUProps->Core, is_io, addr, bit_pos);
  1183.   return True;
  1184. }
  1185.  
  1186. /*!------------------------------------------------------------------------
  1187.  * \fn     decode_bit_arg(LongWord *p_result, int start, int stop)
  1188.  * \brief  encode a bit symbol from instruction argument(s)
  1189.  * \param  p_result resulting encoded bit
  1190.  * \param  start first argument
  1191.  * \param  stop last argument
  1192.  * \return True if success
  1193.  * ------------------------------------------------------------------------ */
  1194.  
  1195. static Boolean decode_bit_arg(LongWord *p_result, int start, int stop)
  1196. {
  1197.   *p_result = 0;
  1198.  
  1199.   /* Just one argument -> parse as bit argument */
  1200.  
  1201.   if (start == stop)
  1202.   {
  1203.     char *p_sep = RQuotPos(ArgStr[start].str.p_str, '.');
  1204.  
  1205.     if (p_sep)
  1206.     {
  1207.       tStrComp reg_comp, bit_comp;
  1208.  
  1209.       StrCompSplitRef(&reg_comp, &bit_comp, &ArgStr[start], p_sep);
  1210.       return decode_bit_arg_2(p_result, &reg_comp, &bit_comp);
  1211.     }
  1212.     else
  1213.     {
  1214.       tEvalResult eval_result;
  1215.  
  1216.       *p_result = EvalStrIntExpressionWithResult(&ArgStr[start], UInt24, &eval_result);
  1217.       if (eval_result.OK)
  1218.         ChkSpace(SegBData, eval_result.AddrSpaceMask);
  1219.       return eval_result.OK;
  1220.     }
  1221.   }
  1222.  
  1223.   /* register & bit position are given as separate arguments */
  1224.  
  1225.   else if (stop == start + 1)
  1226.     return decode_bit_arg_2(p_result, &ArgStr[start], &ArgStr[stop]);
  1227.  
  1228.   /* other # of arguments not allowed */
  1229.  
  1230.   else
  1231.   {
  1232.     WrError(ErrNum_WrongArgCnt);
  1233.     return False;
  1234.   }
  1235. }
  1236.  
  1237. /*!------------------------------------------------------------------------
  1238.  * \fn     dissect_bit_symbol(LongWord bit_symbol, Byte *p_core, Boolean *p_is_io, Word *p_address, Byte *p_bit_pos)
  1239.  * \brief  transform compact representation of bit (field) symbol into components
  1240.  * \param  bit_symbol compact storage
  1241.  * \param  p_core core used to define bit
  1242.  * \param  p_is_io special register or memory bit?
  1243.  * \param  p_address (I/O) register address
  1244.  * \param  p_bit_pos (start) bit position
  1245.  * \return constant True
  1246.  * ------------------------------------------------------------------------ */
  1247.  
  1248. static Boolean dissect_bit_symbol(LongWord bit_symbol, Byte *p_core, Boolean *p_is_io, Word *p_address, Byte *p_bit_pos)
  1249. {
  1250.   *p_core = (bit_symbol >> 20) & 15;
  1251.   *p_is_io = (bit_symbol >> 19) & 1;
  1252.   *p_address = (bit_symbol >> 3) & (*p_is_io ? 0xf : 0xffff);
  1253.   *p_bit_pos = bit_symbol & 7;
  1254.   return True;
  1255. }
  1256.  
  1257. /*!------------------------------------------------------------------------
  1258.  * \fn     dissect_bit_7807(char *p_dest, size_t dest_size, LargeWord inp)
  1259.  * \brief  dissect compact storage of bit (field) into readable form for listing
  1260.  * \param  p_dest destination for ASCII representation
  1261.  * \param  dest_size destination buffer size
  1262.  * \param  inp compact storage
  1263.  * ------------------------------------------------------------------------ */
  1264.  
  1265. static void dissect_bit_7807(char *p_dest, size_t dest_size, LargeWord inp)
  1266. {
  1267.   Byte bit_pos, core;
  1268.   Word address;
  1269.   Boolean is_io;
  1270.  
  1271.   dissect_bit_symbol(inp, &core, &is_io, &address, &bit_pos);
  1272.  
  1273.   if (is_io)
  1274.   {
  1275.     const sreg_t *p_sreg;
  1276.  
  1277.     for (p_sreg = s_regs8; p_sreg->p_name; p_sreg++)
  1278.     {
  1279.       if (!((p_sreg->core_mask >> core) & 1))
  1280.         continue;
  1281.       if (address == p_sreg->code)
  1282.       {
  1283.         as_snprintf(p_dest, dest_size, "%s.%u", p_sreg->p_name, (unsigned)bit_pos);
  1284.         return;
  1285.       }
  1286.     }
  1287.     as_snprintf(p_dest, dest_size, "SR%u.%u", address, (unsigned)bit_pos);
  1288.   }
  1289.   else
  1290.     as_snprintf(p_dest, dest_size, "%~.*u%s.%u",
  1291.                 ListRadixBase, (unsigned)address, GetIntConstIntelSuffix(ListRadixBase),
  1292.                 (unsigned)bit_pos);
  1293. }
  1294.  
  1295. /*!------------------------------------------------------------------------
  1296.  * \fn     expand_bit_7807(const tStrComp *p_var_name, const struct sStructElem *p_struct_elem, LargeWord base)
  1297.  * \brief  expands bit definition when a structure is instantiated
  1298.  * \param  p_var_name desired symbol name
  1299.  * \param  p_struct_elem element definition
  1300.  * \param  base base address of instantiated structure
  1301.  * ------------------------------------------------------------------------ */
  1302.  
  1303. static void expand_bit_7807(const tStrComp *p_var_name, const struct sStructElem *p_struct_elem, LargeWord base)
  1304. {
  1305.   LongWord address = base + p_struct_elem->Offset;
  1306.  
  1307.   if (pInnermostNamedStruct)
  1308.   {
  1309.     PStructElem p_elem = CloneStructElem(p_var_name, p_struct_elem);
  1310.  
  1311.     if (!p_elem)
  1312.       return;
  1313.     p_elem->Offset = address;
  1314.     AddStructElem(pInnermostNamedStruct->StructRec, p_elem);
  1315.   }
  1316.   else
  1317.   {
  1318.     if (!ChkRange(address, 0, 0xffff)
  1319.      || !ChkRange(p_struct_elem->BitPos, 0, 7))
  1320.       return;
  1321.  
  1322.     PushLocHandle(-1);
  1323.     EnterIntSymbol(p_var_name, assemble_bit_symbol(pCurrCPUProps->Core, False, address, p_struct_elem->BitPos), SegBData, False);
  1324.     PopLocHandle();
  1325.     /* TODO: MakeUseList? */
  1326.   }
  1327. }
  1328.  
  1329. /*--------------------------------------------------------------------------------*/
  1330.  
  1331. static Boolean check_core_and_error(unsigned core_mask)
  1332. {
  1333.   Boolean ret = check_core(core_mask);
  1334.  
  1335.   if (!ret)
  1336.     WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  1337.   return ret;
  1338. }
  1339.  
  1340. static void PutCode(Word Code)
  1341. {
  1342.   if (Hi(Code) != 0)
  1343.     BAsmCode[CodeLen++] = Hi(Code);
  1344.   BAsmCode[CodeLen++] = Lo(Code);
  1345. }
  1346.  
  1347. /*!------------------------------------------------------------------------
  1348.  * \fn     decode_bit_7807_core(const tStrComp *p_arg, Byte code)
  1349.  * \brief  core routine for uPD7807 bit-oriented instructions
  1350.  * \param  p_arg source bit argument
  1351.  * \param  code machine code of instruction
  1352.  * ------------------------------------------------------------------------ */
  1353.  
  1354. static void decode_bit_7807_core(int arg_idx, Byte code)
  1355. {
  1356.   LongWord packed_bit;
  1357.   Boolean is_io;
  1358.   Word address;
  1359.   Byte bit_pos, core;
  1360.  
  1361.   if (!decode_bit_arg(&packed_bit, arg_idx, arg_idx))
  1362.     return;
  1363.   dissect_bit_symbol(packed_bit, &core, &is_io, &address, &bit_pos);
  1364.  
  1365.   if (!is_io)
  1366.   {
  1367.     if ((Hi(address) != WorkArea) || (Lo(address) > 15))
  1368.       WrStrErrorPos(ErrNum_InAccPage, &ArgStr[arg_idx]);
  1369.   }
  1370.  
  1371.   BAsmCode[1] = (is_io ? 0x80 : 0x00)
  1372.               | ((address & 15) << 3)
  1373.               | (bit_pos & 7);
  1374.   BAsmCode[0] = code;
  1375.   CodeLen = 2;
  1376. }
  1377.  
  1378. /*!------------------------------------------------------------------------
  1379.  * \fn     DecodeFixed(Word Code)
  1380.  * \brief  Handle instructions without arguments
  1381.  * \param  index index into instruction table
  1382.  * ------------------------------------------------------------------------ */
  1383.  
  1384. static void DecodeFixed(Word index)
  1385. {
  1386.   const order_t *p_order = &fixed_orders[index];
  1387.  
  1388.   if (ChkArgCnt(0, 0) && check_core_and_error(p_order->core_mask))
  1389.     PutCode(p_order->code);
  1390. }
  1391.  
  1392. /*!------------------------------------------------------------------------
  1393.  * \fn     DecodeMOV(Word Code)
  1394.  * \brief  handle MOV instruction
  1395.  * ------------------------------------------------------------------------ */
  1396.  
  1397. static void DecodeMOV(Word Code)
  1398. {
  1399.   Boolean OK;
  1400.   Byte HReg;
  1401.   Integer AdrInt;
  1402.   decode_reg_res_t res1;
  1403.  
  1404.   UNUSED(Code);
  1405.  
  1406.   if (!ChkArgCnt(2, 2));
  1407.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "A"))
  1408.   {
  1409.     decode_reg_res_t res2;
  1410.  
  1411.     if ((res2 = decode_sr1(&ArgStr[2], &HReg)) != e_decode_reg_unknown)
  1412.     {
  1413.       if (res2 == e_decode_reg_ok)
  1414.       {
  1415.         CodeLen = 2;
  1416.         BAsmCode[0] = 0x4c;
  1417.         BAsmCode[1] = 0xc0 + HReg;
  1418.       }
  1419.     }
  1420.     else if ((res2 = decode_r1(&ArgStr[2], &HReg)) != e_decode_reg_unknown)
  1421.     {
  1422.       if (res2 == e_decode_reg_ok)
  1423.       {
  1424.         CodeLen = 1;
  1425.         BAsmCode[0] = 0x08 + HReg;
  1426.       }
  1427.     }
  1428.     else
  1429.     {
  1430.       AdrInt = EvalStrIntExpression(&ArgStr[2], Int16, &OK);
  1431.       if (OK)
  1432.       {
  1433.         CodeLen = 4;
  1434.         BAsmCode[0] = 0x70;
  1435.         BAsmCode[1] = 0x69;
  1436.         BAsmCode[2] = Lo(AdrInt);
  1437.         BAsmCode[3] = Hi(AdrInt);
  1438.       }
  1439.     }
  1440.   }
  1441.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "A"))
  1442.   {
  1443.     decode_reg_res_t res2;
  1444.  
  1445.     if ((res2 = decode_sr(&ArgStr[1], &HReg)) != e_decode_reg_unknown)
  1446.     {
  1447.       if (res2 == e_decode_reg_ok)
  1448.       {
  1449.         CodeLen = 2;
  1450.         BAsmCode[0] = 0x4d;
  1451.         BAsmCode[1] = 0xc0 + HReg;
  1452.       }
  1453.     }
  1454.     else if ((res2 = decode_r1(&ArgStr[1], &HReg)) != e_decode_reg_unknown)
  1455.     {
  1456.       if (res2 == e_decode_reg_ok)
  1457.       {
  1458.         CodeLen = 1;
  1459.         BAsmCode[0] = 0x18 + HReg;
  1460.       }
  1461.     }
  1462.     else
  1463.     {
  1464.       AdrInt = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
  1465.       if (OK)
  1466.       {
  1467.         CodeLen = 4;
  1468.         BAsmCode[0] = 0x70;
  1469.         BAsmCode[1] = 0x79;
  1470.         BAsmCode[2] = Lo(AdrInt);
  1471.         BAsmCode[3] = Hi(AdrInt);
  1472.       }
  1473.     }
  1474.   }
  1475.   else if ((pCurrCPUProps->Core == eCore7807) && !as_strcasecmp(ArgStr[1].str.p_str, "CY"))
  1476.     decode_bit_7807_core(2, 0x5f);
  1477.   else if ((pCurrCPUProps->Core == eCore7807) && !as_strcasecmp(ArgStr[2].str.p_str, "CY"))
  1478.     decode_bit_7807_core(1, 0x5a);
  1479.   else if ((res1 = decode_r(&ArgStr[1], &HReg)) != e_decode_reg_unknown)
  1480.   {
  1481.     if (res1 == e_decode_reg_ok)
  1482.     {
  1483.       AdrInt = EvalStrIntExpression(&ArgStr[2], Int16, &OK);
  1484.       if (OK)
  1485.       {
  1486.         CodeLen = 4;
  1487.         BAsmCode[0] = 0x70;
  1488.         BAsmCode[1] = 0x68 + HReg;
  1489.         BAsmCode[2] = Lo(AdrInt);
  1490.         BAsmCode[3] = Hi(AdrInt);
  1491.       }
  1492.     }
  1493.   }
  1494.   else if ((res1 = decode_r(&ArgStr[2], &HReg)) != e_decode_reg_unknown)
  1495.   {
  1496.     if (res1 == e_decode_reg_ok)
  1497.     {
  1498.       AdrInt = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
  1499.       if (OK)
  1500.       {
  1501.         CodeLen = 4;
  1502.         BAsmCode[0] = 0x70;
  1503.         BAsmCode[1] = 0x78 + HReg;
  1504.         BAsmCode[2] = Lo(AdrInt);
  1505.         BAsmCode[3] = Hi(AdrInt);
  1506.       }
  1507.     }
  1508.   }
  1509.  
  1510.   /* Cannot say in this case if src or dest is invalid register: */
  1511.  
  1512.   else
  1513.     WrError(ErrNum_InvReg);
  1514. }
  1515.  
  1516. /*!------------------------------------------------------------------------
  1517.  * \fn     DecodeMVI(Word Code)
  1518.  * \brief  handle MVI instruction
  1519.  * ------------------------------------------------------------------------ */
  1520.  
  1521. static void DecodeMVI(Word Code)
  1522. {
  1523.   UNUSED(Code);
  1524.  
  1525.   if (ChkArgCnt(2, 2))
  1526.   {
  1527.     Byte HReg;
  1528.     Boolean OK;
  1529.  
  1530.     BAsmCode[1] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
  1531.     if (OK)
  1532.     {
  1533.       decode_reg_res_t res;
  1534.  
  1535.       if ((res = decode_r(&ArgStr[1], &HReg)) != e_decode_reg_unknown)
  1536.       {
  1537.         if (res == e_decode_reg_ok)
  1538.         {
  1539.           CodeLen = 2;
  1540.           BAsmCode[0] = 0x68 + HReg;
  1541.         }
  1542.       }
  1543.       else if ((res = decode_sr2(&ArgStr[1], &HReg)) != e_decode_reg_unknown)
  1544.       {
  1545.         if (res == e_decode_reg_ok)
  1546.         {
  1547.           if (!is_7807_781x) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  1548.           else
  1549.           {
  1550.             CodeLen = 3;
  1551.             BAsmCode[2] = BAsmCode[1];
  1552.             BAsmCode[0] = 0x64;
  1553.             BAsmCode[1] = (HReg & 7) + ((HReg & 8) << 4);
  1554.           }
  1555.         }
  1556.       }
  1557.       else WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  1558.     }
  1559.   }
  1560. }
  1561.  
  1562. /*!------------------------------------------------------------------------
  1563.  * \fn     DecodeMVIW(Word Code)
  1564.  * \brief  handle MVIW instruction
  1565.  * ------------------------------------------------------------------------ */
  1566.  
  1567. static void DecodeMVIW(Word Code)
  1568. {
  1569.   Boolean OK;
  1570.  
  1571.   UNUSED(Code);
  1572.  
  1573.   if (!ChkArgCnt(2, 2) || !check_core_and_error(core_mask_no_low));
  1574.   else if (Decode_wa(&ArgStr[1], BAsmCode + 1, 0xff))
  1575.   {
  1576.     BAsmCode[2] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
  1577.     if (OK)
  1578.     {
  1579.       CodeLen = 3;
  1580.       BAsmCode[0] = 0x71;
  1581.     }
  1582.   }
  1583. }
  1584.  
  1585. /*!------------------------------------------------------------------------
  1586.  * \fn     DecodeMVIX(Word Code)
  1587.  * \brief  handle MVIX instruction
  1588.  * ------------------------------------------------------------------------ */
  1589.  
  1590. static void DecodeMVIX(Word Code)
  1591. {
  1592.   Boolean OK;
  1593.   Byte HReg;
  1594.  
  1595.   UNUSED(Code);
  1596.  
  1597.   if (!ChkArgCnt(2, 2) || !check_core_and_error(core_mask_no_low));
  1598.   else if (Decode_rpa1(&ArgStr[1], &HReg))
  1599.   {
  1600.     BAsmCode[1] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
  1601.     if (OK)
  1602.     {
  1603.       BAsmCode[0] = 0x48 + HReg;
  1604.       CodeLen = 2;
  1605.     }
  1606.   }
  1607. }
  1608.  
  1609. /*!------------------------------------------------------------------------
  1610.  * \fn     DecodeLDAX_STAX(Word Code)
  1611.  * \brief  handle LDAX/STAX instructions
  1612.  * \param  Code machine code
  1613.  * ------------------------------------------------------------------------ */
  1614.  
  1615. static void DecodeLDAX_STAX(Word Code)
  1616. {
  1617.   Byte HReg;
  1618.  
  1619.   if (ChkArgCnt(1, 1))
  1620.   {
  1621.     Boolean ok = is_7807_781x
  1622.                ? Decode_rpa2(&ArgStr[1], &HReg, &BAsmCode[1])
  1623.                : Decode_rpa(&ArgStr[1], &HReg);
  1624.  
  1625.     if (ok)
  1626.     {
  1627.       CodeLen = 1 + Ord(HasDisp(HReg));
  1628.       BAsmCode[0] = Code + ((HReg & 8) << 4) + (HReg & 7);
  1629.     }
  1630.   }
  1631. }
  1632.  
  1633. /*!------------------------------------------------------------------------
  1634.  * \fn     DecodeLDEAX_STEAX(Word Code)
  1635.  * \brief  handle LDEAX/STEAX instructions
  1636.  * \param  Code machine code
  1637.  * ------------------------------------------------------------------------ */
  1638.  
  1639. static void DecodeLDEAX_STEAX(Word Code)
  1640. {
  1641.   Byte HReg;
  1642.  
  1643.   if (ChkArgCnt(1, 1)
  1644.    && check_core_and_error(core_mask_7807_7810)
  1645.    && Decode_rpa3(&ArgStr[1], &HReg, &BAsmCode[2]))
  1646.   {
  1647.     CodeLen = 2 + Ord(HasDisp(HReg));
  1648.     BAsmCode[0] = 0x48;
  1649.     BAsmCode[1] = Code + HReg;
  1650.   }
  1651. }
  1652.  
  1653. /*!------------------------------------------------------------------------
  1654.  * \fn     DecodeLXI(Word Code)
  1655.  * \brief  Handle LXI instruction
  1656.  * \param  Code machine code
  1657.  * ------------------------------------------------------------------------ */
  1658.  
  1659. static void DecodeLXI(Word Code)
  1660. {
  1661.   Byte HReg;
  1662.   Integer AdrInt;
  1663.   Boolean OK;
  1664.  
  1665.   UNUSED(Code);
  1666.  
  1667.   if (!ChkArgCnt(2, 2))
  1668.     return;
  1669.   OK = (pCurrCPUProps->Core >= eCore7807)
  1670.      ? Decode_rp2(ArgStr[1].str.p_str, &HReg)
  1671.      : Decode_rp(ArgStr[1].str.p_str, &HReg);
  1672.   if (!OK) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  1673.   else
  1674.   {
  1675.     AdrInt = EvalStrIntExpression(&ArgStr[2], Int16, &OK);
  1676.     if (OK)
  1677.     {
  1678.       CodeLen = 3;
  1679.       BAsmCode[0] = 0x04 + (HReg << 4);
  1680.       BAsmCode[1] = Lo(AdrInt);
  1681.       BAsmCode[2] = Hi(AdrInt);
  1682.     }
  1683.   }
  1684. }
  1685.  
  1686. /*!------------------------------------------------------------------------
  1687.  * \fn     DecodePUSH_POP(Word Code)
  1688.  * \brief  Handle PUSH/POP instruction
  1689.  * \param  Code machine code
  1690.  * ------------------------------------------------------------------------ */
  1691.  
  1692. static void DecodePUSH_POP(Word Code)
  1693. {
  1694.   Byte HReg;
  1695.  
  1696.   if (!ChkArgCnt(1, 1));
  1697.   else if (!Decode_rp1(ArgStr[1].str.p_str, &HReg)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  1698.   else
  1699.     PutCode(Code | (HReg << (Hi(Code) ? 4 : 0)));
  1700. }
  1701.  
  1702. /*!------------------------------------------------------------------------
  1703.  * \fn     DecodeDMOV(Word Code)
  1704.  * \brief  Handle DMOV instruction
  1705.  * ------------------------------------------------------------------------ */
  1706.  
  1707. static void DecodeDMOV(Word Code)
  1708. {
  1709.   Byte HReg, SReg;
  1710.  
  1711.   UNUSED(Code);
  1712.  
  1713.   if (ChkArgCnt(2, 2) && check_core_and_error(core_mask_7807_7810))
  1714.   {
  1715.     Boolean Swap = as_strcasecmp(ArgStr[1].str.p_str, "EA") || False;
  1716.     const tStrComp *pArg1 = Swap ? &ArgStr[2] : &ArgStr[1],
  1717.                    *pArg2 = Swap ? &ArgStr[1] : &ArgStr[2];
  1718.  
  1719.     if (as_strcasecmp(pArg1->str.p_str, "EA")) WrStrErrorPos(ErrNum_InvAddrMode, pArg1);
  1720.     else if (Decode_rp3(pArg2->str.p_str, &HReg))
  1721.     {
  1722.       CodeLen = 1;
  1723.       BAsmCode[0] = 0xa4 + HReg;
  1724.       if (Swap)
  1725.         BAsmCode[0] += 0x10;
  1726.     }
  1727.     else switch (decode_sr_flag(pArg2, s_regs16, &SReg, Swap ? eFlagSR3 : eFlagSR4))
  1728.     {
  1729.       case e_decode_reg_ok:
  1730.         CodeLen = 2;
  1731.         BAsmCode[0] = 0x48;
  1732.         BAsmCode[1] = 0xc0 + SReg;
  1733.         if (Swap)
  1734.           BAsmCode[1] += 0x12;
  1735.         break;
  1736.       case e_decode_reg_error:
  1737.         WrStrErrorPos(ErrNum_InvCtrlReg, pArg2);
  1738.         break;
  1739.       default:
  1740.         WrStrErrorPos(ErrNum_InvAddrMode, pArg2);
  1741.     }
  1742.   }
  1743. }
  1744.  
  1745. /*!------------------------------------------------------------------------
  1746.  * \fn     decode_alu_z80(Word code)
  1747.  * \brief  handle ALU instruction, Z80-style
  1748.  * \param  code machine code & flags
  1749.  * ------------------------------------------------------------------------ */
  1750.  
  1751. static void decode_alu_z80(Word code)
  1752. {
  1753.   if (ChkArgCnt(2, 2)
  1754.    && ChkZ80Syntax(eSyntaxZ80))
  1755.   {
  1756.     const Byte flags = Hi(code);
  1757.     z80_adr_vals_t src_adr_vals, dest_adr_vals;
  1758.     code = Lo(code);
  1759.  
  1760.     switch (decode_z80_adr(&ArgStr[1], &dest_adr_vals,
  1761.                            MModReg8 | MModReg16 | MModSReg8
  1762.                          | ((code & 1) ? MModWA : 0)))
  1763.     {
  1764.       case e_mod_reg8:
  1765.         switch (decode_z80_adr(&ArgStr[2], &src_adr_vals,
  1766.                                MModReg8
  1767.                              | MModImm
  1768.                              | ((dest_adr_vals.val == REG_A) ? MModIndir : 0)
  1769.                              | (((dest_adr_vals.val == REG_A) && (pCurrCPUProps->Core >= eCore7800High)) ? MModWA : 0)))
  1770.         {
  1771.           case e_mod_reg8:
  1772.             if ((dest_adr_vals.val == REG_A) && !dest_adr_vals.force_long && (src_adr_vals.val < 8) && (flags & ALUReg_Src))
  1773.             {
  1774.               BAsmCode[CodeLen++] = 0x60;
  1775.               BAsmCode[CodeLen++] = 0x80 | (code << 3) | src_adr_vals.val;
  1776.             }
  1777.             else if ((src_adr_vals.val == REG_A) && !src_adr_vals.force_long && (dest_adr_vals.val  < 8) && (flags & ALUReg_Dest))
  1778.             {
  1779.               BAsmCode[CodeLen++] = 0x60;
  1780.               BAsmCode[CodeLen++] = (code << 3) | dest_adr_vals.val;
  1781.               /* ONA/OFFA only exist as A,r, but since binary AND is commutative, we can just swap operands: */
  1782.               if ((code == 9) || (code == 11))
  1783.                 BAsmCode[CodeLen - 1] |= 0x80;
  1784.             }
  1785.             else
  1786.               WrError(ErrNum_InvAddrMode);
  1787.             break;
  1788.           case e_mod_imm:
  1789.             if ((dest_adr_vals.val == REG_A) && !dest_adr_vals.force_long)
  1790.               BAsmCode[CodeLen++] = 0x06 | ((code & 14) << 3) | (code & 1);
  1791.             else if (pCurrCPUProps->Core < eCore7800High) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  1792.             else
  1793.             {
  1794.               BAsmCode[CodeLen++] = 0x74;
  1795.               BAsmCode[CodeLen++] = (code << 3) | dest_adr_vals.val;
  1796.             }
  1797.             if (CodeLen > 0)
  1798.               BAsmCode[CodeLen++] = src_adr_vals.vals[0];
  1799.             break;
  1800.           case e_mod_indir:
  1801.             if (!is_rpa(src_adr_vals.val)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  1802.             else
  1803.             {
  1804.               BAsmCode[CodeLen++] = 0x70;
  1805.               BAsmCode[CodeLen++] = 0x80 | (code << 3) | src_adr_vals.val;
  1806.             }
  1807.             break;
  1808.           case e_mod_wa:
  1809.             BAsmCode[CodeLen++] = 0x74;
  1810.             BAsmCode[CodeLen++] = 0x80 | (code << 3);
  1811.             BAsmCode[CodeLen++] = src_adr_vals.vals[0];
  1812.             break;
  1813.           default:
  1814.             break;
  1815.         }
  1816.         break;
  1817.       case e_mod_reg16:
  1818.       {
  1819.         unsigned mask = MModReg16;
  1820.  
  1821.         if (dest_adr_vals.val != REG_EA)
  1822.         {
  1823.           WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  1824.           return;
  1825.         }
  1826.         if ((code == 8) || (code == 12))
  1827.         {
  1828.           mask |= MModReg8;
  1829.           z80_op_size = eSymbolSizeUnknown;
  1830.         }
  1831.         switch (decode_z80_adr(&ArgStr[2], &src_adr_vals, mask))
  1832.         {
  1833.           case e_mod_reg8:
  1834.             if ((src_adr_vals.val < REG_A) || (src_adr_vals.val > REG_C)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  1835.             else
  1836.             {
  1837.               BAsmCode[CodeLen++] = 0x70;
  1838.               BAsmCode[CodeLen++] = (code << 3) | src_adr_vals.val;
  1839.             }
  1840.             break;
  1841.           case e_mod_reg16:
  1842.             if ((src_adr_vals.val < REG_BC) || (src_adr_vals.val > REG_HL)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  1843.             else
  1844.             {
  1845.               BAsmCode[CodeLen++] = 0x74;
  1846.               BAsmCode[CodeLen++] = 0x84 | (code << 3) | src_adr_vals.val;
  1847.             }
  1848.             break;
  1849.           default:
  1850.             break;
  1851.         }
  1852.         break;
  1853.       }
  1854.       case e_mod_sreg8:
  1855.         switch (decode_z80_adr(&ArgStr[2], &src_adr_vals, (flags & ALUImm_SR) ? MModImm : 0))
  1856.         {
  1857.           case e_mod_imm:
  1858.             if (check_sr_flag(dest_adr_vals.vals[0], eFlagSR2, &ArgStr[1]))
  1859.             {
  1860.               BAsmCode[CodeLen++] = 0x64;
  1861.               BAsmCode[CodeLen++] = (code << 3)
  1862.                                   | ((pCurrCPUProps->Core < eCore7800High) ? 0x80 : 0x00)
  1863.                                   | (dest_adr_vals.val & 7)
  1864.                                   | ((dest_adr_vals.val & 8) << 4);
  1865.               BAsmCode[CodeLen++] = src_adr_vals.vals[0];
  1866.             }
  1867.             break;
  1868.           default:
  1869.             break;
  1870.         }
  1871.         break;
  1872.       case e_mod_wa:
  1873.         z80_def_op_size = eSymbolSize8Bit;
  1874.         switch (decode_z80_adr(&ArgStr[2], &src_adr_vals, MModImm))
  1875.         {
  1876.           case e_mod_imm:
  1877.             BAsmCode[CodeLen++] = ((code & 0x0e) << 3) | 0x05;
  1878.             BAsmCode[CodeLen++] = dest_adr_vals.vals[0];
  1879.             BAsmCode[CodeLen++] = src_adr_vals.vals[0];
  1880.             break;
  1881.           default:
  1882.             break;
  1883.         }
  1884.         break;
  1885.       default:
  1886.         break;
  1887.     }
  1888.   }
  1889. }
  1890.  
  1891. /*!------------------------------------------------------------------------
  1892.  * \fn     DecodeALUImm(Word Code)
  1893.  * \brief  handle 8 Bit ALU instructions with immediate source
  1894.  * \param  Code machine code
  1895.  * ------------------------------------------------------------------------ */
  1896.  
  1897. static void DecodeALUImm(Word Code)
  1898. {
  1899.   ShortInt HVal8;
  1900.   Byte HReg;
  1901.   Boolean OK;
  1902.   Byte Flags;
  1903.  
  1904.   Flags = Hi(Code);
  1905.   Code = Lo(Code);
  1906.  
  1907.   if (ChkArgCnt(2, 2))
  1908.   {
  1909.     HVal8 = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
  1910.     if (OK)
  1911.     {
  1912.       tStrComp Arg1;
  1913.       decode_reg_res_t res;
  1914.  
  1915.       /* allow >A to enforce long addressing */
  1916.  
  1917.       StrCompRefRight(&Arg1, &ArgStr[1], as_strcasecmp(ArgStr[1].str.p_str, ">A") ? 0 : 1);
  1918.       if (!as_strcasecmp(ArgStr[1].str.p_str, "A"))
  1919.       {
  1920.         CodeLen = 2;
  1921.         BAsmCode[0] = 0x06 + ((Code & 14) << 3) + (Code & 1);
  1922.         BAsmCode[1] = HVal8;
  1923.       }
  1924.       else if ((res = decode_r(&Arg1, &HReg)) != e_decode_reg_unknown)
  1925.       {
  1926.         if (res != e_decode_reg_ok);
  1927.         else if (pCurrCPUProps->Core == eCore7800Low) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  1928.         else
  1929.         {
  1930.           CodeLen = 3;
  1931.           BAsmCode[0] = is_7807_781x ? 0x74 : 0x64;
  1932.           BAsmCode[2] = HVal8;
  1933.           BAsmCode[1] = HReg + (Code << 3);
  1934.         }
  1935.       }
  1936.       else if ((res = decode_sr2(&ArgStr[1], &HReg)) != e_decode_reg_unknown)
  1937.       {
  1938.         if (res != e_decode_reg_ok);
  1939.         else if (!(Flags & ALUImm_SR)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  1940.         else
  1941.         {
  1942.           CodeLen = 3;
  1943.           BAsmCode[0] = 0x64;
  1944.           BAsmCode[1] = (HReg & 7) | (Code << 3)
  1945.                       | (is_7807_781x ? ((HReg & 8) << 4) : 0x80);
  1946.           BAsmCode[2] = HVal8;
  1947.         }
  1948.       }
  1949.       else WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  1950.     }
  1951.   }
  1952. }
  1953.  
  1954. /*!------------------------------------------------------------------------
  1955.  * \fn     DecodeALUReg(Word Code)
  1956.  * \brief  Handle ALU instructions with A and register as argument
  1957.  * \param  Code machine code
  1958.  * ------------------------------------------------------------------------ */
  1959.  
  1960. static void DecodeALUReg(Word Code)
  1961. {
  1962.   Byte HReg;
  1963.   Byte Flags;
  1964.  
  1965.   Flags = Hi(Code);
  1966.   if ((CurrZ80Syntax & eSyntaxZ80) && (Flags & ALUReg_MayZ80))
  1967.   {
  1968.     decode_alu_z80(Code);
  1969.     return;
  1970.   }
  1971.   Code = Lo(Code);
  1972.  
  1973.   if (ChkArgCnt(2, 2))
  1974.   {
  1975.     Boolean NoSwap = !as_strcasecmp(ArgStr[1].str.p_str, "A");
  1976.     tStrComp *pArg1 = NoSwap ? &ArgStr[1] : &ArgStr[2],
  1977.              *pArg2 = NoSwap ? &ArgStr[2] : &ArgStr[1],
  1978.              Arg2;
  1979.     decode_reg_res_t res;
  1980.  
  1981.     /* allow >A to enforce <op> r,A instrad of <op> A,r */
  1982.  
  1983.     StrCompRefRight(&Arg2, pArg2, as_strcasecmp(pArg2->str.p_str, ">A") ? 0 : 1);
  1984.  
  1985.     if (as_strcasecmp(pArg1->str.p_str, "A")) WrStrErrorPos(ErrNum_InvAddrMode, pArg1);
  1986.     else if ((res = decode_r(&Arg2, &HReg)) == e_decode_reg_unknown) WrStrErrorPos(ErrNum_InvReg, &Arg2);
  1987.     else if (res == e_decode_reg_ok)
  1988.     {
  1989.       if (NoSwap && !(Flags & ALUReg_Src)) WrStrErrorPos(ErrNum_InvAddrMode, &Arg2);
  1990.       else if (!NoSwap && !(Flags & ALUReg_Dest)) WrStrErrorPos(ErrNum_InvAddrMode, &Arg2);
  1991.       else
  1992.       {
  1993.         CodeLen = 2;
  1994.         BAsmCode[0] = 0x60;
  1995.         BAsmCode[1] = (Code << 3) + HReg;
  1996.         if ((NoSwap) || (Memo("ONA")) || (Memo("OFFA")))
  1997.           BAsmCode[1] += 0x80;
  1998.       }
  1999.     }
  2000.   }
  2001. }
  2002.  
  2003. static void DecodeALURegW(Word Code)
  2004. {
  2005.   if (ChkArgCnt(1, 1)
  2006.    && check_core_and_error(core_mask_no_low)
  2007.    && Decode_wa(&ArgStr[1], BAsmCode + 2, 0xff))
  2008.   {
  2009.     CodeLen = 3;
  2010.     BAsmCode[0] = 0x74;
  2011.     BAsmCode[1] = 0x80 + (Code << 3);
  2012.   }
  2013. }
  2014.  
  2015. static void DecodeALURegX(Word Code)
  2016. {
  2017.   Byte HReg;
  2018.  
  2019.   if (!ChkArgCnt(1, 1));
  2020.   else if (Decode_rpa(&ArgStr[1], &HReg))
  2021.   {
  2022.     CodeLen = 2;
  2023.     BAsmCode[0] = 0x70;
  2024.     BAsmCode[1] = 0x80 + (Code << 3) + HReg;
  2025.   }
  2026. }
  2027.  
  2028. static void DecodeALUEA(Word Code)
  2029. {
  2030.   Byte HReg;
  2031.  
  2032.   if (!ChkArgCnt(2, 2));
  2033.   else if (!check_core_and_error(core_mask_7807_7810));
  2034.   else if (as_strcasecmp(ArgStr[1].str.p_str, "EA")) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  2035.   else if (!Decode_rp3(ArgStr[2].str.p_str, &HReg)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2036.   else
  2037.   {
  2038.     CodeLen = 2;
  2039.     BAsmCode[0] = 0x74;
  2040.     BAsmCode[1] = 0x84 + (Code << 3) + HReg;
  2041.   }
  2042. }
  2043.  
  2044. static void DecodeALUImmW(Word Code)
  2045. {
  2046.   Boolean OK;
  2047.  
  2048.   if (!ChkArgCnt(2, 2));
  2049.   else if (Decode_wa(&ArgStr[1], BAsmCode + 1, 0xff))
  2050.   {
  2051.     BAsmCode[2] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
  2052.     if (OK)
  2053.     {
  2054.       CodeLen = 3;
  2055.       BAsmCode[0] = 0x05 + ((Code >> 1) << 4);
  2056.     }
  2057.   }
  2058. }
  2059.  
  2060. /*!------------------------------------------------------------------------
  2061.  * \fn     DecodeAbs(Word Code)
  2062.  * \brief  Handle instructions with absolute address as argument
  2063.  * \param  Code machine code
  2064.  * ------------------------------------------------------------------------ */
  2065.  
  2066. static void DecodeAbs(Word Code)
  2067. {
  2068.   if (!ChkArgCnt(1, 1));
  2069.   else
  2070.   {
  2071.     Boolean OK;
  2072.     Integer AdrInt;
  2073.  
  2074.     AdrInt = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
  2075.     if (OK)
  2076.     {
  2077.       PutCode(Code);
  2078.       BAsmCode[CodeLen++] = Lo(AdrInt);
  2079.       BAsmCode[CodeLen++] = Hi(AdrInt);
  2080.     }
  2081.   }
  2082. }
  2083.  
  2084. /*!------------------------------------------------------------------------
  2085.  * \fn     DecodeReg2(Word index)
  2086.  * \brief  Handle instructions with r2 as argument
  2087.  * \param  index index into instruction table
  2088.  * ------------------------------------------------------------------------ */
  2089.  
  2090. static void DecodeReg2(Word index)
  2091. {
  2092.   const order_t *p_order = &reg2_orders[index];
  2093.   Byte HReg;
  2094.   decode_reg_res_t res;
  2095.  
  2096.   if (!ChkArgCnt(1, 1) || !check_core_and_error(p_order->core_mask));
  2097.   else if ((res = decode_r2(&ArgStr[1], &HReg)) == e_decode_reg_unknown) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  2098.   else if (res == e_decode_reg_ok)
  2099.     PutCode(p_order->code + HReg);
  2100. }
  2101.  
  2102. /*!------------------------------------------------------------------------
  2103.  * \fn     DecodeWA(Word Code)
  2104.  * \brief  Handle instructions with work area address as argument
  2105.  * \param  Code machine code
  2106.  * ------------------------------------------------------------------------ */
  2107.  
  2108. static void DecodeWork(Word Code)
  2109. {
  2110.   if (ChkArgCnt(1, 1)
  2111.    && Decode_wa(&ArgStr[1], BAsmCode + 1, 0xff))
  2112.   {
  2113.     CodeLen = 2;
  2114.     BAsmCode[0] = Code;
  2115.   }
  2116. }
  2117.  
  2118. /*!------------------------------------------------------------------------
  2119.  * \fn     DecodeA(Word Code)
  2120.  * \brief  Handle instructions with A as argument
  2121.  * \param  Code machine code
  2122.  * ------------------------------------------------------------------------ */
  2123.  
  2124. static void DecodeA(Word Code)
  2125. {
  2126.   if (!ChkArgCnt(1, 1));
  2127.   else if (as_strcasecmp(ArgStr[1].str.p_str, "A")) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  2128.   else
  2129.     PutCode(Code);
  2130. }
  2131.  
  2132. /*!------------------------------------------------------------------------
  2133.  * \fn     DecodeEA(Word Code)
  2134.  * \brief  Handle instructions with EA as argument
  2135.  * \param  Code machine code
  2136.  * ------------------------------------------------------------------------ */
  2137.  
  2138. static void DecodeEA(Word Code)
  2139. {
  2140.   if (!ChkArgCnt(1, 1) || !check_core_and_error(core_mask_7807_7810));
  2141.   else if (as_strcasecmp(ArgStr[1].str.p_str, "EA")) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  2142.   else
  2143.   {
  2144.     CodeLen = 2;
  2145.     BAsmCode[0] = Hi(Code);
  2146.     BAsmCode[1] = Lo(Code);
  2147.   }
  2148. }
  2149.  
  2150. /*!------------------------------------------------------------------------
  2151.  * \fn     DecodeDCX_INX(Word Code)
  2152.  * \brief  Handle INX/DCX Instructions
  2153.  * \param  Code machine code
  2154.  * ------------------------------------------------------------------------ */
  2155.  
  2156. static void DecodeDCX_INX(Word Code)
  2157. {
  2158.   Byte HReg;
  2159.  
  2160.   if (!ChkArgCnt(1, 1));
  2161.   else if (check_core(core_mask_7807_7810) && !as_strcasecmp(ArgStr[1].str.p_str, "EA"))
  2162.   {
  2163.     CodeLen = 1;
  2164.     BAsmCode[0] = 0xa8 + Code;
  2165.   }
  2166.   else if (Decode_rp(ArgStr[1].str.p_str, &HReg))
  2167.   {
  2168.     CodeLen = 1;
  2169.     BAsmCode[0] = 0x02 + Code + (HReg << 4);
  2170.   }
  2171.   else
  2172.     WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  2173. }
  2174.  
  2175. /*!------------------------------------------------------------------------
  2176.  * \fn     decode_inc_dec(word code)
  2177.  * \brief  Handle Z80-style INC/DEC instructions
  2178.  * \param  code machine code
  2179.  * ------------------------------------------------------------------------ */
  2180.  
  2181. static void decode_inc_dec(Word code)
  2182. {
  2183.   if (ChkArgCnt(1, 1)
  2184.    && ChkZ80Syntax(eSyntaxZ80))
  2185.   {
  2186.     z80_adr_vals_t adr_vals;
  2187.  
  2188.     switch (decode_z80_adr(&ArgStr[1], &adr_vals, MModReg8 | MModReg16 | MModWA))
  2189.     {
  2190.       case e_mod_reg8:
  2191.         if ((adr_vals.val < REG_A) || (adr_vals.val > REG_C)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  2192.         else
  2193.           BAsmCode[CodeLen++] = 0x40 | (code << 4) | adr_vals.val;
  2194.         break;
  2195.       case e_mod_reg16:
  2196.         BAsmCode[CodeLen++] = (adr_vals.val == REG_EA)
  2197.                             ? 0xa8 | code
  2198.                             : 0x02 | code | (adr_vals.val << 4);
  2199.         break;
  2200.       case e_mod_wa:
  2201.         BAsmCode[CodeLen++] = 0x20 | (code << 4);
  2202.         BAsmCode[CodeLen++] = adr_vals.vals[0];
  2203.         break;
  2204.       default:
  2205.         break;
  2206.     }
  2207.   }
  2208. }
  2209.  
  2210. static void DecodeEADD_ESUB(Word Code)
  2211. {
  2212.   Byte HReg;
  2213.   decode_reg_res_t res;
  2214.  
  2215.   if (!ChkArgCnt(2, 2) || !check_core_and_error(core_mask_7807_7810));
  2216.   else if (as_strcasecmp(ArgStr[1].str.p_str, "EA")) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  2217.   else if ((res = decode_r2(&ArgStr[2], &HReg)) == e_decode_reg_unknown) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2218.   else if (res == e_decode_reg_ok)
  2219.   {
  2220.     CodeLen = 2;
  2221.     BAsmCode[0] = 0x70;
  2222.     BAsmCode[1] = Code + HReg;
  2223.   }
  2224. }
  2225.  
  2226. static void DecodeJ_JR_JRE(Word Type)
  2227. {
  2228.   Boolean OK;
  2229.   Integer AdrInt;
  2230.   tSymbolFlags Flags;
  2231.  
  2232.   if (!ChkArgCnt(1, 1))
  2233.     return;
  2234.  
  2235.   AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags) - (EProgCounter() + 1);
  2236.   if (!OK)
  2237.     return;
  2238.  
  2239.   if (!Type) /* generic J */
  2240.     Type = RangeCheck(AdrInt, SInt6) ? 1 : 2;
  2241.  
  2242.   switch (Type)
  2243.   {
  2244.     case 1: /* JR */
  2245.       if (!mSymbolQuestionable(Flags) && !RangeCheck(AdrInt, SInt6)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
  2246.       else
  2247.       {
  2248.         CodeLen = 1;
  2249.         BAsmCode[0] = 0xc0 + (AdrInt & 0x3f);
  2250.       }
  2251.       break;
  2252.     case 2:
  2253.       AdrInt--; /* JRE is 2 bytes long */
  2254.       if (!mSymbolQuestionable(Flags) && !RangeCheck(AdrInt, SInt9)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
  2255.       else
  2256.       {
  2257.         CodeLen = 2;
  2258.         BAsmCode[0] = 0x4e + (Hi(AdrInt) & 1);
  2259.         BAsmCode[1] = Lo(AdrInt);
  2260.       }
  2261.       break;
  2262.   }
  2263. }
  2264.  
  2265. static void DecodeCALF(Word Code)
  2266. {
  2267.   UNUSED(Code);
  2268.  
  2269.   if (ChkArgCnt(1, 1))
  2270.   {
  2271.     Boolean OK;
  2272.     Integer AdrInt;
  2273.     tSymbolFlags Flags;
  2274.  
  2275.     AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
  2276.     if (OK)
  2277.     {
  2278.       if (!mFirstPassUnknown(Flags) && ((AdrInt >> 11) != 1)) WrStrErrorPos(ErrNum_NotFromThisAddress, &ArgStr[1]);
  2279.       else
  2280.       {
  2281.         CodeLen = 2;
  2282.         BAsmCode[0] = Hi(AdrInt) + 0x70;
  2283.         BAsmCode[1] = Lo(AdrInt);
  2284.       }
  2285.     }
  2286.   }
  2287. }
  2288.  
  2289. static void DecodeCALT(Word Code)
  2290. {
  2291.   UNUSED(Code);
  2292.  
  2293.   if (ChkArgCnt(1, 1))
  2294.   {
  2295.     Boolean OK;
  2296.     Integer AdrInt;
  2297.     tSymbolFlags Flags;
  2298.  
  2299.     AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
  2300.     if (OK)
  2301.     {
  2302.       Word AdrMask = is_7807_781x ? 0xffc1 : 0xff81;
  2303.  
  2304.       if (!mFirstPassUnknown(Flags) && ((AdrInt & AdrMask) != 0x80)) WrStrErrorPos(ErrNum_NotFromThisAddress, &ArgStr[1]);
  2305.       else
  2306.       {
  2307.         CodeLen = 1;
  2308.         BAsmCode[0] = 0x80 + ((AdrInt & ~AdrMask) >> 1);
  2309.       }
  2310.     }
  2311.   }
  2312. }
  2313.  
  2314. static void DecodeBIT(Word Code)
  2315. {
  2316.   UNUSED(Code);
  2317.  
  2318.   if (ChkArgCnt(2, 2) && check_core_and_error(core_mask_no_low))
  2319.   {
  2320.     Boolean OK;
  2321.     ShortInt HReg;
  2322.  
  2323.     HReg = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
  2324.     if (OK)
  2325.      if (Decode_wa(&ArgStr[2], BAsmCode + 1, 0xff))
  2326.      {
  2327.        CodeLen = 2; BAsmCode[0] = 0x58 + HReg;
  2328.      }
  2329.   }
  2330. }
  2331.  
  2332. static void DecodeSK_SKN(Word Code)
  2333. {
  2334.   Byte HReg;
  2335.  
  2336.   if (!ChkArgCnt(1, 1) || !check_core_and_error(Hi(Code)));
  2337.   else if (Decode_f(ArgStr[1].str.p_str, &HReg))
  2338.   {
  2339.     CodeLen = 2;
  2340.     BAsmCode[0] = 0x48;
  2341.     BAsmCode[1] = Lo(Code) + HReg;
  2342.   }
  2343.   else if (pCurrCPUProps->Core == eCore7807)
  2344.     decode_bit_7807_core(1, (Code & 0x10) ? 0x50 :0x5d);
  2345.   else
  2346.     WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  2347. }
  2348.  
  2349. static void DecodeSKIT_SKNIT(Word Code)
  2350. {
  2351.   ShortInt HReg;
  2352.  
  2353.   if (ChkArgCnt(1, 1)
  2354.    && check_core_and_error(Hi(Code))
  2355.    && Decode_irf(&ArgStr[1], &HReg))
  2356.   {
  2357.     CodeLen = 2;
  2358.     BAsmCode[0] = 0x48;
  2359.     BAsmCode[1] = Lo(Code) + HReg;
  2360.   }
  2361. }
  2362.  
  2363. static void DecodeIN_OUT(Word Code)
  2364. {
  2365.   const tStrComp *p_port_arg;
  2366.  
  2367.   switch (ArgCnt)
  2368.   {
  2369.     case 2:
  2370.     {
  2371.       const tStrComp *p_acc_arg = &ArgStr[(Code & 1) + 1];
  2372.  
  2373.       if (as_strcasecmp(p_acc_arg->str.p_str, "A"))
  2374.       {
  2375.         WrStrErrorPos(ErrNum_InvAddrMode, p_acc_arg);
  2376.         return;
  2377.       }
  2378.       p_port_arg = &ArgStr[2 - (Code & 1)];
  2379.       goto common;
  2380.     }
  2381.     case 1:
  2382.       p_port_arg = &ArgStr[1];
  2383.       /* fall-thru */
  2384.     common:
  2385.     {
  2386.       Boolean OK;
  2387.  
  2388.       BAsmCode[1] = EvalStrIntExpression(p_port_arg, UInt8, &OK);
  2389.       if (OK)
  2390.       {
  2391.         BAsmCode[0] = Code;
  2392.         CodeLen = 2;
  2393.       }
  2394.       break;
  2395.     }
  2396.     default:
  2397.       (void)ChkArgCnt(1, 2);
  2398.   }
  2399. }
  2400.  
  2401. /*!------------------------------------------------------------------------
  2402.  * \fn     DecodeBLOCK_7807(Word code)
  2403.  * \brief  Handle 7807-style BLOCK instruction
  2404.  * \param  code machine code
  2405.  * ------------------------------------------------------------------------ */
  2406.  
  2407. static void DecodeBLOCK_7807(Word code)
  2408. {
  2409.   if (ChkArgCnt(1, 1))
  2410.   {
  2411.     Byte mode;
  2412.  
  2413.     if (Decode_rpa(&ArgStr[1], &mode))
  2414.     {
  2415.       if ((mode != 4) && (mode != 6)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  2416.       else
  2417.       {
  2418.         BAsmCode[0] = code | ((mode >> 1) & 1);
  2419.         CodeLen = 1;
  2420.       }
  2421.     }
  2422.   }
  2423. }
  2424.  
  2425. /*!------------------------------------------------------------------------
  2426.  * \fn     DecodeBit1_7807(Word code)
  2427.  * \brief  handle 7807-specific bit operations with one operand
  2428.  * \param  code machine code
  2429.  * ------------------------------------------------------------------------ */
  2430.  
  2431. static void DecodeBit1_7807(Word code)
  2432. {
  2433.   if (!ChkArgCnt(1, 1));
  2434.   else if (!check_core_and_error(core_mask_7807));
  2435.   else
  2436.     decode_bit_7807_core(1, code);
  2437. }
  2438.  
  2439. /*!------------------------------------------------------------------------
  2440.  * \fn     DecodeBit2_7807(Word code)
  2441.  * \brief  handle 7807-specific bit operations with two operands,
  2442.            and Z80-style logical instructions
  2443.  * \param  code machine code
  2444.  * ------------------------------------------------------------------------ */
  2445.  
  2446. static void DecodeBit2_7807(Word code)
  2447. {
  2448.   if (!ChkArgCnt(2, 2));
  2449.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "CY"))
  2450.   {
  2451.     if (check_core_and_error(core_mask_7807))
  2452.       decode_bit_7807_core(2, Lo(code));
  2453.   }
  2454.   else if (CurrZ80Syntax & eSyntaxZ80)
  2455.   {
  2456.     Word Flags = ALUReg_Src;
  2457.     if (pCurrCPUProps->Core != eCore7800Low)
  2458.       Flags |= ALUReg_Dest | ALUImm_SR;
  2459.     else if (Hi(code) != 2)
  2460.       Flags |= ALUImm_SR;
  2461.     decode_alu_z80((Flags << 8) | Hi(code));
  2462.   }
  2463.   else
  2464.     WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  2465. }
  2466.  
  2467. /*!------------------------------------------------------------------------
  2468.  * \fn     DecodeDEFBIT(Word code)
  2469.  * \brief  handle DEFBIT instruction (7807...7809 only)
  2470.  * ------------------------------------------------------------------------ */
  2471.  
  2472. static void DecodeDEFBIT(Word code)
  2473. {
  2474.   LongWord BitSpec;
  2475.  
  2476.   UNUSED(code);
  2477.  
  2478.   /* if in structure definition, add special element to structure */
  2479.  
  2480.   if (ActPC == StructSeg)
  2481.   {
  2482.     Boolean OK;
  2483.     Byte BitPos;
  2484.     PStructElem pElement;
  2485.  
  2486.     if (!ChkArgCnt(2, 2))
  2487.       return;
  2488.     BitPos = eval_bit_position(&ArgStr[2], &OK);
  2489.     if (!OK)
  2490.       return;
  2491.     pElement = CreateStructElem(&LabPart);
  2492.     if (!pElement)
  2493.       return;
  2494.     pElement->pRefElemName = as_strdup(ArgStr[1].str.p_str);
  2495.     pElement->OpSize = eSymbolSize8Bit;
  2496.     pElement->BitPos = BitPos;
  2497.     pElement->ExpandFnc = expand_bit_7807;
  2498.     AddStructElem(pInnermostNamedStruct->StructRec, pElement);
  2499.   }
  2500.   else
  2501.   {
  2502.     if (decode_bit_arg(&BitSpec, 1, ArgCnt))
  2503.     {
  2504.       *ListLine = '=';
  2505.       dissect_bit_7807(ListLine + 1, STRINGSIZE - 3, BitSpec);
  2506.       PushLocHandle(-1);
  2507.       EnterIntSymbol(&LabPart, BitSpec, SegBData, False);
  2508.       PopLocHandle();
  2509.       /* TODO: MakeUseList? */
  2510.     }
  2511.   }
  2512. }
  2513.  
  2514. /*!------------------------------------------------------------------------
  2515.  * \fn     decode_ld(Word code)
  2516.  * \brief  handle LD (Z80 style) instruction
  2517.  * ------------------------------------------------------------------------ */
  2518.  
  2519. static void decode_ld(Word code)
  2520. {
  2521.   UNUSED(code);
  2522.  
  2523.   if (ChkArgCnt(2, 2)
  2524.    && ChkZ80Syntax(eSyntaxZ80))
  2525.   {
  2526.     z80_adr_vals_t dest_adr_vals, src_adr_vals;
  2527.  
  2528.     switch (decode_z80_adr(&ArgStr[1], &dest_adr_vals, MModReg8 | MModReg16 | MModAbs | MModWA | MModIndir | MModSReg8 | MModSReg16))
  2529.     {
  2530.       case e_mod_reg8:
  2531.         switch (decode_z80_adr(&ArgStr[2], &src_adr_vals,
  2532.                                MModReg8
  2533.                              | ((dest_adr_vals.val < 8) ? MModImm : 0)
  2534.                              | ((dest_adr_vals.val < 8) ? MModAbs : 0)
  2535.                              | ((dest_adr_vals.val == REG_A) ? MModWA : 0)
  2536.                              | ((dest_adr_vals.val == REG_A) ? MModIndir : 0)
  2537.                              | ((dest_adr_vals.val == REG_A) ? MModSReg8 : 0)))
  2538.         {
  2539.           case e_mod_imm:
  2540.             BAsmCode[CodeLen++] = 0x68 + dest_adr_vals.val;
  2541.             BAsmCode[CodeLen++] = src_adr_vals.vals[0];
  2542.             break;
  2543.           case e_mod_abs:
  2544.             BAsmCode[CodeLen++] = 0x70;
  2545.             BAsmCode[CodeLen++] = 0x68 + dest_adr_vals.val;
  2546.             BAsmCode[CodeLen++] = src_adr_vals.vals[0];
  2547.             BAsmCode[CodeLen++] = src_adr_vals.vals[1];
  2548.             break;
  2549.           case e_mod_wa:
  2550.             BAsmCode[CodeLen++] = (pCurrCPUProps->Core >= eCore7800High) ? 0x01 : 0x28;
  2551.             BAsmCode[CodeLen++] = src_adr_vals.vals[0];
  2552.             break;
  2553.           case e_mod_reg8:
  2554.             if ((src_adr_vals.val == REG_A) && (dest_adr_vals.val >= 2))
  2555.               BAsmCode[CodeLen++] = 0x18 | (dest_adr_vals.val & 7);
  2556.             else if ((dest_adr_vals.val == REG_A) && (src_adr_vals.val >= 2))
  2557.               BAsmCode[CodeLen++] = 0x08 | (src_adr_vals.val & 7);
  2558.             else
  2559.               WrError(ErrNum_InvAddrMode);
  2560.             break;
  2561.           case e_mod_indir:
  2562.             if ((pCurrCPUProps->Core <= eCore7800High) && !is_rpa(src_adr_vals.val)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2563.             else
  2564.             {
  2565.               BAsmCode[CodeLen++] = 0x28 | (src_adr_vals.val & 0x07) | ((src_adr_vals.val & 0x08) << 4);
  2566.               append_adr_vals(&src_adr_vals);
  2567.             }
  2568.             break;
  2569.           case e_mod_sreg8:
  2570.             if (check_sr_flag(src_adr_vals.vals[0], eFlagSR1, &ArgStr[2]))
  2571.             {
  2572.               BAsmCode[CodeLen++] = 0x4c;
  2573.               BAsmCode[CodeLen++] = 0xc0 | src_adr_vals.val;
  2574.             }
  2575.             break;
  2576.           default:
  2577.             break;
  2578.         }
  2579.         break;
  2580.       case e_mod_reg16:
  2581.         switch (decode_z80_adr(&ArgStr[2], &src_adr_vals,
  2582.                                MModImm
  2583.                              | MModReg16
  2584.                              | ((dest_adr_vals.val < REG_EA) ? MModAbs : 0)
  2585.                              | ((dest_adr_vals.val == REG_EA) ? MModIndir : 0)
  2586.                              | ((dest_adr_vals.val == REG_EA) ? MModSReg16 : 0)))
  2587.         {
  2588.           case e_mod_imm:
  2589.             BAsmCode[CodeLen++] = 0x04 | (dest_adr_vals.val << 4);
  2590.             BAsmCode[CodeLen++] = src_adr_vals.vals[0];
  2591.             BAsmCode[CodeLen++] = src_adr_vals.vals[1];
  2592.             break;
  2593.           case e_mod_reg16:
  2594.             if ((dest_adr_vals.val == REG_EA) && (src_adr_vals.val >= REG_BC) && (src_adr_vals.val <= REG_HL))
  2595.               BAsmCode[CodeLen++] = 0xa4 | src_adr_vals.val;
  2596.             else if ((src_adr_vals.val == REG_EA) && (dest_adr_vals.val >= REG_BC) && (dest_adr_vals.val <= REG_HL))
  2597.               BAsmCode[CodeLen++] = 0xb4 | dest_adr_vals.val;
  2598.             else
  2599.               WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2600.             break;
  2601.           case e_mod_abs:
  2602.             BAsmCode[CodeLen++] = 0x70;
  2603.             BAsmCode[CodeLen++] = 0x0f | (dest_adr_vals.val << 4);
  2604.             BAsmCode[CodeLen++] = src_adr_vals.vals[0];
  2605.             BAsmCode[CodeLen++] = src_adr_vals.vals[1];
  2606.             break;
  2607.           case e_mod_indir:
  2608.             if (!is_rpa3(src_adr_vals.val)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2609.             else
  2610.             {
  2611.               BAsmCode[CodeLen++] = 0x48;
  2612.               BAsmCode[CodeLen++] = 0x80 | src_adr_vals.val;
  2613.               append_adr_vals(&src_adr_vals);
  2614.             }
  2615.             break;
  2616.           case e_mod_sreg16:
  2617.             if (check_sr_flag(src_adr_vals.vals[0], eFlagSR4, &ArgStr[2]))
  2618.             {
  2619.               BAsmCode[CodeLen++] = 0x48;
  2620.               BAsmCode[CodeLen++] = 0xc0 | src_adr_vals.val;
  2621.             }
  2622.             break;
  2623.           default:
  2624.             break;
  2625.         }
  2626.         break;
  2627.       case e_mod_abs:
  2628.         switch (decode_z80_adr(&ArgStr[2], &src_adr_vals, MModReg8 | MModReg16))
  2629.         {
  2630.           case e_mod_reg8:
  2631.             if (src_adr_vals.val > 7) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2632.             else
  2633.             {
  2634.               BAsmCode[CodeLen++] = 0x70;
  2635.               BAsmCode[CodeLen++] = 0x78 | src_adr_vals.val;
  2636.               append_adr_vals(&dest_adr_vals);
  2637.             }
  2638.             break;
  2639.           case e_mod_reg16:
  2640.             if (src_adr_vals.val >= REG_EA) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2641.             else
  2642.             {
  2643.               BAsmCode[CodeLen++] = 0x70;
  2644.               BAsmCode[CodeLen++] = 0x0e | (src_adr_vals.val << 4);
  2645.               append_adr_vals(&dest_adr_vals);
  2646.             }
  2647.             break;
  2648.           default:
  2649.             break;
  2650.         }
  2651.         break;
  2652.       case e_mod_wa:
  2653.         z80_def_op_size = eSymbolSize8Bit;
  2654.         switch (decode_z80_adr(&ArgStr[2], &src_adr_vals, MModReg8 | MModReg16
  2655.                                | ((pCurrCPUProps->Core >= eCore7800High) ? MModImm : 0)
  2656.                               ))
  2657.         {
  2658.           case e_mod_reg8:
  2659.             if (src_adr_vals.val == REG_A)
  2660.             {
  2661.               BAsmCode[CodeLen++] = (pCurrCPUProps->Core >= eCore7800High) ? 0x63 : 0x38;
  2662.               BAsmCode[CodeLen++] = dest_adr_vals.vals[0];
  2663.             }
  2664.             else if (src_adr_vals.val <= 7) /* map to absolute addressing */
  2665.             {
  2666.               BAsmCode[CodeLen++] = 0x70;
  2667.               BAsmCode[CodeLen++] = 0x78 | src_adr_vals.val;
  2668.               BAsmCode[CodeLen++] = dest_adr_vals.vals[0];
  2669.               BAsmCode[CodeLen++] = WorkArea;
  2670.             }
  2671.             else
  2672.               WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2673.             break;
  2674.           case e_mod_reg16: /* map to absolute addressing */
  2675.             if (src_adr_vals.val >= REG_EA) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2676.             else
  2677.             {
  2678.               BAsmCode[CodeLen++] = 0x70;
  2679.               BAsmCode[CodeLen++] = 0x0e | (src_adr_vals.val << 4);
  2680.               BAsmCode[CodeLen++] = dest_adr_vals.vals[0];
  2681.               BAsmCode[CodeLen++] = WorkArea;
  2682.             }
  2683.             break;
  2684.           case e_mod_imm:
  2685.             BAsmCode[CodeLen++] = 0x71;
  2686.             BAsmCode[CodeLen++] = dest_adr_vals.vals[0];
  2687.             BAsmCode[CodeLen++] = src_adr_vals.vals[0];
  2688.             break;
  2689.           default:
  2690.             break;
  2691.         }
  2692.         break;
  2693.       case e_mod_indir:
  2694.         z80_def_op_size = eSymbolSize8Bit;
  2695.         switch (decode_z80_adr(&ArgStr[2], &src_adr_vals, MModReg8 | MModReg16
  2696.                             | ((pCurrCPUProps->Core >= eCore7800High) ? MModImm : 0)))
  2697.         {
  2698.           case e_mod_reg8:
  2699.             if (src_adr_vals.val != REG_A) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2700.             else if ((pCurrCPUProps->Core <= eCore7800High) && !is_rpa(dest_adr_vals.val)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  2701.             else
  2702.             {
  2703.               BAsmCode[CodeLen++] = 0x38 | (dest_adr_vals.val & 0x07) | ((dest_adr_vals.val & 0x08) << 4);
  2704.               append_adr_vals(&dest_adr_vals);
  2705.             }
  2706.             break;
  2707.           case e_mod_reg16:
  2708.             if (src_adr_vals.val != REG_EA) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2709.             else if (!is_rpa3(dest_adr_vals.val)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  2710.             else
  2711.             {
  2712.               BAsmCode[CodeLen++] = 0x48;
  2713.               BAsmCode[CodeLen++] = 0x90 | dest_adr_vals.val;
  2714.               append_adr_vals(&dest_adr_vals);
  2715.             }
  2716.             break;
  2717.           case e_mod_imm:
  2718.             if (!is_rpa1(dest_adr_vals.val)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  2719.             else
  2720.             {
  2721.               BAsmCode[CodeLen++] = 0x48 | dest_adr_vals.val;
  2722.               BAsmCode[CodeLen++] = src_adr_vals.vals[0];
  2723.             }
  2724.             break;
  2725.           default:
  2726.             break;
  2727.         }
  2728.         break;
  2729.       case e_mod_sreg8:
  2730.         switch (decode_z80_adr(&ArgStr[2], &src_adr_vals, MModReg8 | MModImm))
  2731.         {
  2732.           case e_mod_reg8:
  2733.             if (src_adr_vals.val != REG_A) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2734.             else if (check_sr_flag(dest_adr_vals.vals[0], eFlagSR, &ArgStr[1]))
  2735.             {
  2736.               BAsmCode[CodeLen++] = 0x4d;
  2737.               BAsmCode[CodeLen++] = 0xc0 | dest_adr_vals.val;
  2738.             }
  2739.             break;
  2740.           case e_mod_imm:
  2741.             if (check_sr_flag(dest_adr_vals.vals[0], eFlagSR2, &ArgStr[1]))
  2742.             {
  2743.               BAsmCode[CodeLen++] = 0x64;
  2744.               BAsmCode[CodeLen++] = (dest_adr_vals.val & 0x07) | ((dest_adr_vals.val & 0x08) << 4);
  2745.               BAsmCode[CodeLen++] = src_adr_vals.vals[0];
  2746.             }
  2747.           default:
  2748.             break;
  2749.         }
  2750.         break;
  2751.       case e_mod_sreg16:
  2752.         switch (decode_z80_adr(&ArgStr[2], &src_adr_vals, MModReg16))
  2753.         {
  2754.           case e_mod_reg16:
  2755.             if (src_adr_vals.val != REG_EA) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2756.             else if (check_sr_flag(dest_adr_vals.vals[0], eFlagSR3, &ArgStr[1]))
  2757.             {
  2758.               BAsmCode[CodeLen++] = 0x48;
  2759.               BAsmCode[CodeLen++] = 0xd2 | dest_adr_vals.val;
  2760.             }
  2761.             break;
  2762.           default:
  2763.             break;
  2764.         }
  2765.         break;
  2766.       default:
  2767.         break;
  2768.     }
  2769.   }
  2770. }
  2771.  
  2772. /*--------------------------------------------------------------------------------*/
  2773. /* Dynamic Code Table Handling */
  2774.  
  2775. static void AddFixed(const char *p_name, Word code, unsigned core_mask)
  2776. {
  2777.   order_array_rsv_end(fixed_orders, order_t);
  2778.   fixed_orders[InstrZ].code = code;
  2779.   fixed_orders[InstrZ].core_mask = core_mask;
  2780.   AddInstTable(InstTable, p_name, InstrZ++, DecodeFixed);
  2781. }
  2782.  
  2783. static void AddIntFlag(const char *p_name, Byte code)
  2784. {
  2785.   order_array_rsv_end(int_flags, intflag_t);
  2786.   int_flags[InstrZ].p_name = p_name;
  2787.   int_flags[InstrZ++].code = code;
  2788. }
  2789.  
  2790. static void AddALU(Byte NCode, Word Flags, const char *NNameI, const char *NNameReg, const char *NNameEA, const char *NNameZ80)
  2791. {
  2792.   char Name[20];
  2793.  
  2794.   AddInstTable(InstTable, NNameI, ((Flags & ALUImm_SR) << 8) | NCode, DecodeALUImm);
  2795.   AddInstTable(InstTable, NNameReg, ((Flags & (ALUReg_Src | ALUReg_Dest | ALUImm_SR | ALUReg_MayZ80)) << 8) | NCode, DecodeALUReg);
  2796.   AddInstTable(InstTable, NNameEA, NCode, DecodeALUEA);
  2797.   as_snprintf(Name, sizeof(Name), "%sW", NNameReg);
  2798.   AddInstTable(InstTable, Name, NCode, DecodeALURegW);
  2799.   as_snprintf(Name, sizeof(Name), "%sX", NNameReg);
  2800.   AddInstTable(InstTable, Name, NCode, DecodeALURegX);
  2801.   if (NCode & 1)
  2802.   {
  2803.     as_snprintf(Name, sizeof(Name), "%sW", NNameI);
  2804.     AddInstTable(InstTable, Name, NCode, DecodeALUImmW);
  2805.   }
  2806.   if (NNameZ80)
  2807.     AddInstTable(InstTable, NNameZ80, NCode, decode_alu_z80);
  2808. }
  2809.  
  2810. static void add_alu_z80(const char *p_name, Byte code, Word flags)
  2811. {
  2812.   AddInstTable(InstTable, p_name, (flags << 8) | code, decode_alu_z80);
  2813. }
  2814.  
  2815. static void AddAbs(const char *NName, Word NCode)
  2816. {
  2817.   AddInstTable(InstTable, NName, NCode, DecodeAbs);
  2818. }
  2819.  
  2820. static void AddReg2(const char *p_name, Word code, unsigned core_mask)
  2821. {
  2822.   order_array_rsv_end(reg2_orders, order_t);
  2823.   reg2_orders[InstrZ].code = code;
  2824.   reg2_orders[InstrZ].core_mask = core_mask;
  2825.   AddInstTable(InstTable, p_name, InstrZ++, DecodeReg2);
  2826. }
  2827.  
  2828. static void add_sreg8(const char *p_name, Byte code, Byte flags, Byte core_mask)
  2829. {
  2830.   order_array_rsv_end(s_regs8, sreg_t);
  2831.   s_regs8[InstrZ].p_name = p_name;
  2832.   s_regs8[InstrZ].code = code;
  2833.   s_regs8[InstrZ].flags = flags;
  2834.   s_regs8[InstrZ].core_mask = core_mask;
  2835.   InstrZ++;
  2836. }
  2837.  
  2838. static void add_sreg16(const char *p_name, Byte code, Byte flags, Byte core_mask)
  2839. {
  2840.   order_array_rsv_end(s_regs16, sreg_t);
  2841.   s_regs16[InstrZ].p_name = p_name;
  2842.   s_regs16[InstrZ].code = code;
  2843.   s_regs16[InstrZ].flags = flags;
  2844.   s_regs16[InstrZ].core_mask = core_mask;
  2845.   InstrZ++;
  2846. }
  2847.  
  2848. static void AddWork(const char *NName, Word NCode)
  2849. {
  2850.   AddInstTable(InstTable, NName, NCode, DecodeWork);
  2851. }
  2852.  
  2853. static void AddA(const char *NName, Word NCode)
  2854. {
  2855.   AddInstTable(InstTable, NName, NCode, DecodeA);
  2856. }
  2857.  
  2858. static void AddEA(const char *NName, Word NCode)
  2859. {
  2860.   AddInstTable(InstTable, NName, NCode, DecodeEA);
  2861. }
  2862.  
  2863. static void InitFields(void)
  2864. {
  2865.   Boolean IsLow = pCurrCPUProps->Core == eCore7800Low,
  2866.           IsHigh = pCurrCPUProps->Core == eCore7800High,
  2867.           Is7807 = pCurrCPUProps->Core == eCore7807,
  2868.           Is781x = pCurrCPUProps->Core == eCore7810;
  2869.  
  2870.   InstTable = CreateInstTable(301);
  2871.   SetDynamicInstTable(InstTable);
  2872.  
  2873.   add_null_pseudo(InstTable);
  2874.  
  2875.   AddInstTable(InstTable, "MOV", 0, DecodeMOV);
  2876.   AddInstTable(InstTable, "MVI", 0, DecodeMVI);
  2877.   AddInstTable(InstTable, "MVIW", 0, DecodeMVIW);
  2878.   AddInstTable(InstTable, "MVIX", 0, DecodeMVIX);
  2879.   AddInstTable(InstTable, "LDAX", 0x28, DecodeLDAX_STAX);
  2880.   AddInstTable(InstTable, "STAX", 0x38, DecodeLDAX_STAX);
  2881.   AddInstTable(InstTable, "LDEAX", 0x80, DecodeLDEAX_STEAX);
  2882.   AddInstTable(InstTable, "STEAX", 0x90, DecodeLDEAX_STEAX);
  2883.   AddInstTable(InstTable, "LXI", 0, DecodeLXI);
  2884.   AddInstTable(InstTable, "PUSH", is_7807_781x ? 0xb0 : 0x480e, DecodePUSH_POP);
  2885.   AddInstTable(InstTable, "POP", is_7807_781x ? 0xa0 : 0x480f, DecodePUSH_POP);
  2886.   AddInstTable(InstTable, "DMOV", 0, DecodeDMOV);
  2887.   AddInstTable(InstTable, "DCX", 1, DecodeDCX_INX);
  2888.   AddInstTable(InstTable, "INX", 0, DecodeDCX_INX);
  2889.   AddInstTable(InstTable, "EADD", 0x40, DecodeEADD_ESUB);
  2890.   AddInstTable(InstTable, "ESUB", 0x60, DecodeEADD_ESUB);
  2891.   AddInstTable(InstTable, "JR", 1, DecodeJ_JR_JRE);
  2892.   AddInstTable(InstTable, "JRE", 2, DecodeJ_JR_JRE);
  2893.   AddInstTable(InstTable, "J", 0, DecodeJ_JR_JRE);
  2894.   AddInstTable(InstTable, "CALF", 0, DecodeCALF);
  2895.   AddInstTable(InstTable, "CALT", 0, DecodeCALT);
  2896.   AddInstTable(InstTable, "BIT", 0, DecodeBIT);
  2897.   AddInstTable(InstTable, "SK" , (core_mask_no_low << 8) | 0x08, DecodeSK_SKN);
  2898.   AddInstTable(InstTable, "SKN", (core_mask_all    << 8) | 0x18, DecodeSK_SKN);
  2899.   AddInstTable(InstTable, "SKIT" , (core_mask_no_low << 8) | (is_7807_781x ? 0x40 : 0x00), DecodeSKIT_SKNIT);
  2900.   AddInstTable(InstTable, "SKNIT", (core_mask_all    << 8) | (is_7807_781x ? 0x60 : 0x10), DecodeSKIT_SKNIT);
  2901.  
  2902.   InstrZ = 0;
  2903.   AddFixed("EX"   , 0x0010                   , (1 << eCore7800High));
  2904.   AddFixed("PEN"  , 0x482c                   , (1 << eCore7800High));
  2905.   AddFixed("RCL"  , 0x4832                   , (1 << eCore7800High));
  2906.   AddFixed("RCR"  , 0x4833                   , (1 << eCore7800High));
  2907.   AddFixed("SHAL" , 0x4834                   , (1 << eCore7800High));
  2908.   AddFixed("SHAR" , 0x4835                   , (1 << eCore7800High));
  2909.   AddFixed("SHCL" , 0x4836                   , (1 << eCore7800High));
  2910.   AddFixed("SHCR" , 0x4837                   , (1 << eCore7800High));
  2911.   AddFixed("EXX"  , Is7807 ? 0x48af : 0x0011 , core_mask_no_low);
  2912.   AddFixed("EXA"  , Is7807 ? 0x48ac : 0x0010 , core_mask_all);
  2913.   AddFixed("EXH"  , Is7807 ? 0x48ae : 0x0050 , core_mask_all);
  2914.   AddFixed("EXR"  , 0x48ad                   , core_mask_7807);
  2915.   if (Is7807)
  2916.     AddInstTable(InstTable, "BLOCK", 0x0010, DecodeBLOCK_7807);
  2917.   else
  2918.     AddFixed("BLOCK", 0x0031                   , core_mask_no_low);
  2919.   AddFixed("TABLE", is_7807_781x ? 0x48a8 : 0x0021 , core_mask_no_low);
  2920.   AddFixed("DAA"  , 0x0061                   , core_mask_all);
  2921.   AddFixed("STC"  , 0x482b                   , core_mask_all);
  2922.   AddFixed("CLC"  , 0x482a                   , core_mask_all);
  2923.   AddFixed("CMC"  , 0x48aa                   , core_mask_7807);
  2924.   AddFixed("NEGA" , 0x483a                   , core_mask_all);
  2925.   AddFixed("RLD"  , 0x4838                   , core_mask_all);
  2926.   AddFixed("RRD"  , 0x4839                   , core_mask_all);
  2927.   AddFixed("JB"   , is_7807_781x ? 0x0021 : 0x0073 , core_mask_all);
  2928.   AddFixed("JEA"  , 0x4828                   , core_mask_all);
  2929.   AddFixed("CALB" , is_7807_781x ? 0x4829 : 0x0063 , core_mask_no_low);
  2930.   AddFixed("SOFTI", 0x0072                   , core_mask_no_low);
  2931.   AddFixed("RET"  , is_7807_781x ? 0x00b8 : 0x0008 , core_mask_all);
  2932.   AddFixed("RETS" , is_7807_781x ? 0x00b9 : 0x0018 , core_mask_all);
  2933.   AddFixed("RETI" , 0x0062                   , core_mask_all);
  2934.   AddFixed("NOP"  , 0x0000                   , core_mask_all);
  2935.   AddFixed("EI"   , is_7807_781x ? 0x00aa : 0x4820 , core_mask_all);
  2936.   AddFixed("DI"   , is_7807_781x ? 0x00ba : 0x4824 , core_mask_all);
  2937.   AddFixed("HLT"  , is_7807_781x ? 0x483b : 0x0001 , core_mask_no_low);
  2938.   AddFixed("SIO"  , 0x0009                   , core_mask_7800);
  2939.   AddFixed("STM"  , 0x0019                   , core_mask_7800);
  2940.   AddFixed("PEX"  , 0x482d                   , core_mask_7800);
  2941.   AddFixed("RAL"  , is_7807_781x ? 0x4835 : 0x4830 , core_mask_all);
  2942.   AddFixed("RAR"  , 0x4831                   , core_mask_all);
  2943.   AddFixed("PER"  , 0x483c                   , core_mask_7800);
  2944.   if (pCurrCPUProps->Flags & eFlagCMOS)
  2945.     AddFixed("STOP" , 0x48bb, core_mask_all);
  2946.  
  2947.   if (is_7807_781x)
  2948.   {
  2949.     if (Is781x)
  2950.     {
  2951.     }
  2952.     else
  2953.     {
  2954.     }
  2955.     /* 0x28 eFlagSR ? */
  2956.   }
  2957.   else
  2958.   {
  2959.   }
  2960.  
  2961.   InstrZ = 0;
  2962.   if (is_7807_781x)
  2963.   {
  2964.     AddIntFlag("NMI" , 0);
  2965.     AddIntFlag("FT0" , 1);
  2966.     AddIntFlag("FT1" , 2);
  2967.     AddIntFlag("F1"  , 3);
  2968.     AddIntFlag("F2"  , 4);
  2969.     AddIntFlag("FE0" , 5);
  2970.     AddIntFlag("FE1" , 6);
  2971.     AddIntFlag("FEIN", 7);
  2972.     AddIntFlag("FSR" , 9);
  2973.     AddIntFlag("FST" ,10);
  2974.     AddIntFlag("ER"  ,11);
  2975.     AddIntFlag("OV"  ,12);
  2976.     AddIntFlag("SB"  ,20);
  2977.     if (Is781x)
  2978.     {
  2979.       AddIntFlag("FAD" , 8);
  2980.       AddIntFlag("AN4" ,16);
  2981.       AddIntFlag("AN5" ,17);
  2982.       AddIntFlag("AN6" ,18);
  2983.       AddIntFlag("AN7" ,19);
  2984.     }
  2985.     else
  2986.     {
  2987.       /* value yet unknown */
  2988.       /* AddIntFlag("IFE2", ...); */
  2989.     }
  2990.   }
  2991.   else
  2992.   {
  2993.     AddIntFlag("F0"  , 0);
  2994.     AddIntFlag("FT"  , 1);
  2995.     AddIntFlag("F1"  , 2);
  2996.     if (IsHigh)
  2997.       AddIntFlag("F2"  , 3);
  2998.     AddIntFlag("FS"  , 4);
  2999.   }
  3000.   AddIntFlag(NULL, 0);
  3001.  
  3002.   AddALU(10, IsLow ?             ALUReg_Src | ALUReg_MayZ80 : ALUImm_SR | ALUReg_Src | ALUReg_Dest | ALUReg_MayZ80, "ACI"  , "ADC"  , "DADC"  , NULL );
  3003.   AddALU( 4, IsLow ?             ALUReg_Src | ALUReg_MayZ80 : ALUImm_SR | ALUReg_Src | ALUReg_Dest | ALUReg_MayZ80, "ADINC", "ADDNC", "DADDNC", NULL );
  3004.   AddALU( 8, IsLow ?             ALUReg_Src | ALUReg_MayZ80 : ALUImm_SR | ALUReg_Src | ALUReg_Dest | ALUReg_MayZ80, "ADI"  , "ADD"  , "DADD"  , NULL );
  3005.   AddALU( 1, IsLow ? ALUImm_SR | ALUReg_Src                 : ALUImm_SR | ALUReg_Src | ALUReg_Dest                , "ANI"  , "ANA"  , "DAN"   , NULL );
  3006.   AddALU(15, IsLow ?             ALUReg_Src                 : ALUImm_SR | ALUReg_Src | ALUReg_Dest                , "EQI"  , "EQA"  , "DEQ"   , NULL );
  3007.   AddALU( 5, IsLow ?             ALUReg_Src                 : ALUImm_SR | ALUReg_Src | ALUReg_Dest                , "GTI"  , "GTA"  , "DGT"   , NULL );
  3008.   AddALU( 7, IsLow ?             ALUReg_Src                 : ALUImm_SR | ALUReg_Src | ALUReg_Dest                , "LTI"  , "LTA"  , "DLT"   , NULL );
  3009.   AddALU(13, IsLow ?             ALUReg_Src                 : ALUImm_SR | ALUReg_Src | ALUReg_Dest                , "NEI"  , "NEA"  , "DNE"   , NULL );
  3010.   AddALU(11, IsLow ? ALUImm_SR                              : ALUImm_SR | ALUReg_Src | ALUReg_Dest                , "OFFI" , "OFFA" , "DOFF"  , NULL );
  3011.   AddALU( 9, IsLow ? ALUImm_SR                              : ALUImm_SR | ALUReg_Src | ALUReg_Dest                , "ONI"  , "ONA"  , "DON"   , NULL );
  3012.   AddALU( 3, IsLow ? ALUImm_SR | ALUReg_Src                 : ALUImm_SR | ALUReg_Src | ALUReg_Dest                , "ORI"  , "ORA"  , "DOR"   , NULL );
  3013.   AddALU(14, IsLow ?             ALUReg_Src | ALUReg_MayZ80 : ALUImm_SR | ALUReg_Src | ALUReg_Dest | ALUReg_MayZ80, "SBI"  , "SBB"  , "DSBB"  , NULL );
  3014.   AddALU( 6, IsLow ?             ALUReg_Src | ALUReg_MayZ80 : ALUImm_SR | ALUReg_Src | ALUReg_Dest | ALUReg_MayZ80, "SUINB", "SUBNB", "DSUBNB", NULL );
  3015.   AddALU(12, IsLow ?             ALUReg_Src | ALUReg_MayZ80 : ALUImm_SR | ALUReg_Src | ALUReg_Dest | ALUReg_MayZ80, "SUI"  , "SUB"  , "DSUB"  , NULL );
  3016.   AddALU( 2, IsLow ?             ALUReg_Src                 : ALUImm_SR | ALUReg_Src | ALUReg_Dest                , "XRI"  , "XRA"  , "DXR"   , NULL );
  3017.  
  3018.   AddAbs("CALL", is_7807_781x ? 0x0040 : 0x0044);
  3019.   AddAbs("JMP" , 0x0054);
  3020.   AddAbs("LBCD", 0x701f);
  3021.   AddAbs("LDED", 0x702f);
  3022.   AddAbs("LHLD", 0x703f);
  3023.   AddAbs("LSPD", 0x700f);
  3024.   AddAbs("SBCD", 0x701e);
  3025.   AddAbs("SDED", 0x702e);
  3026.   AddAbs("SHLD", 0x703e);
  3027.   AddAbs("SSPD", 0x700e);
  3028.  
  3029.   InstrZ = 0;
  3030.   AddReg2("DCR" , 0x0050, core_mask_all);
  3031.   AddReg2("DIV" , 0x483c, core_mask_7807_7810);
  3032.   AddReg2("INR" , 0x0040, core_mask_all);
  3033.   AddReg2("MUL" , 0x482c, core_mask_7807_7810);
  3034.   if (is_7807_781x)
  3035.   {
  3036.     AddReg2("RLL" , 0x4834, core_mask_7807_7810);
  3037.     AddReg2("RLR" , 0x4830, core_mask_7807_7810);
  3038.   }
  3039.   else
  3040.   {
  3041.     AddA("RLL", 0x4830);
  3042.     AddA("RLR", 0x4831);
  3043.   }
  3044.   AddReg2("SLL" , 0x4824, core_mask_7807_7810);
  3045.   AddReg2("SLR" , 0x4820, core_mask_7807_7810);
  3046.   AddReg2("SLLC", 0x4804, core_mask_7807_7810);
  3047.   AddReg2("SLRC", 0x4800, core_mask_7807_7810);
  3048.  
  3049.   AddWork("DCRW", 0x30);
  3050.   AddWork("INRW", 0x20);
  3051.   AddWork("LDAW", is_7807_781x ? 0x01 : 0x28);
  3052.   AddWork("STAW", is_7807_781x ? 0x63 : 0x38);
  3053.  
  3054.   AddEA("DRLL", 0x48b4); AddEA("DRLR", 0x48b0);
  3055.   AddEA("DSLL", 0x48a4); AddEA("DSLR", 0x48a0);
  3056.  
  3057.   if (!is_7807_781x)
  3058.   {
  3059.     AddInstTable(InstTable, "IN" , 0x4c, DecodeIN_OUT);
  3060.     AddInstTable(InstTable, "OUT", 0x4d, DecodeIN_OUT);
  3061.   }
  3062.  
  3063.   AddInstTable(InstTable, "AND" , 0x0131, DecodeBit2_7807);
  3064.   AddInstTable(InstTable, "OR"  , 0x035c, DecodeBit2_7807);
  3065.   AddInstTable(InstTable, "XOR" , 0x025e, DecodeBit2_7807);
  3066.   AddInstTable(InstTable, "SETB", 0x58, DecodeBit1_7807);
  3067.   AddInstTable(InstTable, "CLR" , 0x5b, DecodeBit1_7807);
  3068.   AddInstTable(InstTable, "NOT" , 0x59, DecodeBit1_7807);
  3069.  
  3070.   /* Array with special regs is created upon first usage and remains
  3071.      allocated, because we need it in dissect_bit_7807(), which may
  3072.      be called after we switched away fro mtarget (e.g. when printing
  3073.      symbol table: */
  3074.  
  3075.   if (!s_regs8)
  3076.   {
  3077.     InstrZ = 0;
  3078.     add_sreg8("PA"  , 0x00, eFlagSR | eFlagSR1 | eFlagSR2, core_mask_all);
  3079.     add_sreg8("PB"  , 0x01, eFlagSR | eFlagSR1 | eFlagSR2, core_mask_all);
  3080.     add_sreg8("PC"  , 0x02, eFlagSR | eFlagSR1 | eFlagSR2, core_mask_7807_7810);
  3081.     add_sreg8("PD"  , 0x03, eFlagSR | eFlagSR1 | eFlagSR2, core_mask_7807_7810);
  3082.     add_sreg8("PF"  , 0x05, eFlagSR | eFlagSR1 | eFlagSR2, core_mask_7807_7810);
  3083.     add_sreg8("MKH" , 0x06, eFlagSR | eFlagSR1 | eFlagSR2, core_mask_7807_7810);
  3084.     add_sreg8("MKL" , 0x07, eFlagSR | eFlagSR1 | eFlagSR2, core_mask_7807_7810);
  3085.     add_sreg8("SMH" , 0x09, eFlagSR | eFlagSR1 | eFlagSR2, core_mask_7807_7810);
  3086.     add_sreg8("SML" , 0x0a, eFlagSR                      , core_mask_7807_7810);
  3087.     add_sreg8("EOM" , 0x0b, eFlagSR | eFlagSR1 | eFlagSR2, core_mask_7807_7810);
  3088.     add_sreg8("ETMM", 0x0c, eFlagSR                      , core_mask_7807_7810);
  3089.     add_sreg8("TMM" , 0x0d, eFlagSR | eFlagSR1 | eFlagSR2, core_mask_7807_7810);
  3090.     add_sreg8("MM"  , 0x10, eFlagSR                      , core_mask_7807_7810);
  3091.     add_sreg8("MCC" , 0x11, eFlagSR                      , core_mask_7807_7810);
  3092.     add_sreg8("MA"  , 0x12, eFlagSR                      , core_mask_7807_7810);
  3093.     add_sreg8("MB"  , 0x13, eFlagSR                      , core_mask_7807_7810);
  3094.     add_sreg8("MC"  , 0x14, eFlagSR                      , core_mask_7807_7810);
  3095.     add_sreg8("MF"  , 0x17, eFlagSR                      , core_mask_7807_7810);
  3096.     add_sreg8("TXB" , 0x18, eFlagSR                      , core_mask_7807_7810);
  3097.     add_sreg8("RXB" , 0x19, eFlagSR1                     , core_mask_7807_7810);
  3098.     add_sreg8("TM0" , 0x1a, eFlagSR                      , core_mask_7807_7810);
  3099.     add_sreg8("TM1" , 0x1b, eFlagSR                      , core_mask_7807_7810);
  3100.     add_sreg8("ZCM" , 0x28, eFlagSR                      , core_mask_7807_7810 | core_mask_cmos);
  3101.     add_sreg8("ANM" , 0x08, eFlagSR | eFlagSR1 | eFlagSR2, core_mask_7810     );
  3102.     add_sreg8("CR0" , 0x20, eFlagSR1                     , core_mask_7810     );
  3103.     add_sreg8("CR1" , 0x21, eFlagSR1                     , core_mask_7810     );
  3104.     add_sreg8("CR2" , 0x22, eFlagSR1                     , core_mask_7810     );
  3105.     add_sreg8("CR3" , 0x23, eFlagSR1                     , core_mask_7810     );
  3106.     add_sreg8("PT"  , 0x0e, eFlagSR | eFlagSR1 | eFlagSR2, core_mask_7807     );
  3107.     add_sreg8("WDM" , 0x20, eFlagSR | eFlagSR1           , core_mask_7807     );
  3108.     add_sreg8("MT"  , 0x21, eFlagSR | eFlagSR1           , core_mask_7807     );
  3109.     add_sreg8("MK"  , 0x03, eFlagSR | eFlagSR1 | eFlagSR2, core_mask_7800     );
  3110.     add_sreg8("MB"  , 0x04, eFlagSR                      , core_mask_7800     );
  3111.     add_sreg8("PC"  , 0x02, eFlagSR | eFlagSR1 | eFlagSR2, core_mask_7800_high);
  3112.     add_sreg8("PC"  , 0x02, eFlagSR1 | eFlagSR2          , core_mask_7800_low );
  3113.     add_sreg8("MC"  , 0x05, eFlagSR                      , core_mask_7800_high);
  3114.     add_sreg8("MC"  , 0x05, 0                            , core_mask_7800_low );
  3115.     add_sreg8("TM0" , 0x06, eFlagSR                      , core_mask_7800_high);
  3116.     add_sreg8("TM0" , 0x06, 0                            , core_mask_7800_low );
  3117.     add_sreg8("TM1" , 0x07, eFlagSR                      , core_mask_7800_high);
  3118.     add_sreg8("TM1" , 0x07, 0                            , core_mask_7800_low );
  3119.     add_sreg8("TM"  , 0x06, eFlagSR                      , core_mask_7800_low );
  3120.     add_sreg8("TM"  , 0x06, 0                            , core_mask_7800_high);
  3121.     add_sreg8("SM"  , 0x0a, eFlagSR | eFlagSR1           , core_mask_7800_low );
  3122.     add_sreg8("SM"  , 0x0a, 0                            , core_mask_7800_high);
  3123.     add_sreg8("SC"  , 0x0b, eFlagSR | eFlagSR1           , core_mask_7800_low );
  3124.     add_sreg8("SC"  , 0x0b, 0                            , core_mask_7800_high);
  3125.     add_sreg8("S"   , 0x08, eFlagSR | eFlagSR1           , core_mask_7800     );
  3126.     add_sreg8("TMM" , 0x09, eFlagSR | eFlagSR1           , core_mask_7800     );
  3127.     add_sreg8(NULL  , 0x00, 0                            , 0                  );
  3128.   }
  3129.  
  3130.   InstrZ = 0;
  3131.   add_sreg16("ETM0" , 0x00, eFlagSR3, core_mask_all );
  3132.   add_sreg16("ETM1" , 0x01, eFlagSR3, core_mask_all );
  3133.   add_sreg16("ECNT" , 0x00, eFlagSR4, core_mask_all );
  3134.   add_sreg16("ECPT" , 0x01, eFlagSR4, core_mask_7810);
  3135.   add_sreg16("ECPT0", 0x01, eFlagSR4, core_mask_7807);
  3136.   add_sreg16("ECPT1", 0x02, eFlagSR4, core_mask_7807);
  3137.   add_sreg16(NULL   , 0x00, 0       , 0             );
  3138.  
  3139.   if (Is7807)
  3140.     AddInstTable(InstTable, "DEFBIT", 0, DecodeDEFBIT);
  3141.  
  3142.   AddZ80Syntax(InstTable);
  3143.   AddInstTable(InstTable, "LD", 0, decode_ld);
  3144.   AddInstTable(InstTable, "INC", 0, decode_inc_dec);
  3145.   AddInstTable(InstTable, "DEC", 1, decode_inc_dec);
  3146.   add_alu_z80("SKGT", 5, IsLow ? ALUReg_Src : ALUImm_SR | ALUReg_Src | ALUReg_Dest);
  3147.   add_alu_z80("SKLT", 7, IsLow ? ALUReg_Src : ALUImm_SR | ALUReg_Src | ALUReg_Dest);
  3148.   add_alu_z80("SKNE",13, IsLow ? ALUReg_Src : ALUImm_SR | ALUReg_Src | ALUReg_Dest);
  3149.   add_alu_z80("SKEQ",15, IsLow ? ALUReg_Src : ALUImm_SR | ALUReg_Src | ALUReg_Dest);
  3150.   add_alu_z80("SKON", 9, IsLow ? ALUImm_SR  : ALUImm_SR | ALUReg_Src | ALUReg_Dest);
  3151.   add_alu_z80("SKOFF",11, IsLow ? ALUImm_SR  : ALUImm_SR | ALUReg_Src | ALUReg_Dest);
  3152.  
  3153.   AddIntelPseudo(InstTable, eIntPseudoFlag_LittleEndian);
  3154. }
  3155.  
  3156. static void DeinitFields(void)
  3157. {
  3158.   DestroyInstTable(InstTable);
  3159.   order_array_free(int_flags);
  3160.   order_array_free(fixed_orders);
  3161.   order_array_free(reg2_orders);
  3162.   /* See above why s_regs8 does not get freed upon deinit: */
  3163.   /*order_array_free(s_regs8);*/
  3164.   order_array_free(s_regs16);
  3165. }
  3166.  
  3167. /*--------------------------------------------------------------------------*/
  3168.  
  3169. /*!------------------------------------------------------------------------
  3170.  * \fn     MakeCode_78C10(void)
  3171.  * \brief  generate code from source code line
  3172.  * ------------------------------------------------------------------------ */
  3173.  
  3174. static void MakeCode_78C10(void)
  3175. {
  3176.   z80_op_size =
  3177.   z80_def_op_size = eSymbolSizeUnknown;
  3178.  
  3179.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  3180.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  3181. }
  3182.  
  3183. /*!------------------------------------------------------------------------
  3184.  * \fn     InitCode_78C10(void)
  3185.  * \brief  target-specific initializations at begin of pass
  3186.  * ------------------------------------------------------------------------ */
  3187.  
  3188. static void InitCode_78C10(void)
  3189. {
  3190.   WorkArea = 0x100;
  3191. }
  3192.  
  3193. /*!------------------------------------------------------------------------
  3194.  * \fn     IsDef_78C10(void)
  3195.  * \brief  check whether instruction consumes label field itself
  3196.  * \return True if yes
  3197.  * ------------------------------------------------------------------------ */
  3198.  
  3199. static Boolean IsDef_78C10(void)
  3200. {
  3201.   return (pCurrCPUProps->Core == eCore7807) && Memo("DEFBIT");
  3202. }
  3203.  
  3204. /*!------------------------------------------------------------------------
  3205.  * \fn     SwitchFrom_78C10(void)
  3206.  * \brief  cleanups when switching away from target
  3207.  * ------------------------------------------------------------------------ */
  3208.  
  3209. static void SwitchFrom_78C10(void)
  3210. {
  3211.   DeinitFields();
  3212. }
  3213.  
  3214. /*!------------------------------------------------------------------------
  3215.  * \fn     SwitchTo_78C10(void *pUser)
  3216.  * \brief  initializations when switching to target
  3217.  * \param  pUser * to target details
  3218.  * ------------------------------------------------------------------------ */
  3219.  
  3220. static void SwitchTo_78C10(void *pUser)
  3221. {
  3222.   const TFamilyDescr *pDescr = FindFamilyByName("78(C)xx");
  3223.  
  3224.   pCurrCPUProps = (const tCPUProps*)pUser;
  3225.   TurnWords = False;
  3226.   SetIntConstMode(eIntConstModeIntel);
  3227.  
  3228.   PCSymbol = "$"; HeaderID = pDescr->Id; NOPCode = 0x00;
  3229.   DivideChars = ","; HasAttrs = False;
  3230.  
  3231.   ValidSegs = 1 << SegCode;
  3232.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  3233.   SegLimits[SegCode] = 0xffff;
  3234.  
  3235.   if (pCurrCPUProps->Flags & eFlagHasV)
  3236.   {
  3237.     static ASSUMERec ASSUME78C10s[] =
  3238.     {
  3239.       {"V" , &WorkArea, 0, 0xff, 0x100, NULL}
  3240.     };
  3241.  
  3242.     pASSUMERecs = ASSUME78C10s;
  3243.     ASSUMERecCnt = sizeof(ASSUME78C10s) / sizeof(*ASSUME78C10s);
  3244.   }
  3245.   else
  3246.     WorkArea = 0xff;
  3247.   is_7807_781x = (pCurrCPUProps->Core == eCore7807) || (pCurrCPUProps->Core == eCore7810);
  3248.  
  3249.   MakeCode = MakeCode_78C10; IsDef = IsDef_78C10;
  3250.   SwitchFrom = SwitchFrom_78C10;
  3251.   if (pCurrCPUProps->Core == eCore7807)
  3252.     DissectBit = dissect_bit_7807;
  3253.   InitFields();
  3254. }
  3255.  
  3256. /*!------------------------------------------------------------------------
  3257.  * \fn     code78c10_init(void)
  3258.  * \brief  Attach 78Cxx target
  3259.  * ------------------------------------------------------------------------ */
  3260.  
  3261. static const tCPUProps CPUProps[] =
  3262. {
  3263.   { "7800" , eCore7800High, eFlagHasV             }, /* ROMless , 128B RAM */
  3264.   { "7801" , eCore7800High, eFlagHasV             }, /* 4KB ROM , 128B RAM */
  3265.   { "7802" , eCore7800High, eFlagHasV             }, /* 6KB ROM , 128B RAM */
  3266.   { "78C05", eCore7800Low,  0                     }, /* ROMless , 128B RAM */
  3267.   { "78C06", eCore7800Low,  0                     }, /* 4KB ROM , 128B RAM */
  3268.   { "7807" , eCore7807,     eFlagHasV             }, /* ROMless , 256B RAM */
  3269.   { "7808" , eCore7807,     eFlagHasV             }, /* 4KB ROM , 256B RAM */
  3270.   { "7809" , eCore7807,     eFlagHasV             }, /* 8KB ROM , 256B RAM */
  3271.   { "7810" , eCore7810,     eFlagHasV             }, /* ROMless , 256B RAM */
  3272.   { "78C10", eCore7810,     eFlagHasV | eFlagCMOS }, /* ROMless , 256B RAM */
  3273.   { "78C11", eCore7810,     eFlagHasV | eFlagCMOS }, /* 4KB ROM , 256B RAM */
  3274.   { "78C12", eCore7810,     eFlagHasV | eFlagCMOS }, /* 8KB ROM , 256B RAM */
  3275.   { "78C14", eCore7810,     eFlagHasV | eFlagCMOS }, /* 16KB ROM, 256B RAM */
  3276.   { "78C17", eCore7810,     eFlagHasV | eFlagCMOS }, /* ROMless ,  1KB RAM */
  3277.   { "78C18", eCore7810,     eFlagHasV | eFlagCMOS }, /* 32KB ROM,  1KB RAM */
  3278.   { ""     , eCoreNone,     0                     },
  3279. };
  3280.  
  3281. void code78c10_init(void)
  3282. {
  3283.   const tCPUProps *pProp;
  3284.  
  3285.   for (pProp = CPUProps; pProp->Name[0]; pProp++)
  3286.     (void)AddCPUUserWithArgs(pProp->Name, SwitchTo_78C10, (void*)pProp, NULL, NULL);
  3287.  
  3288.   AddInitPassProc(InitCode_78C10);
  3289. }
  3290.