Subversion Repositories pentevo

Rev

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

  1. /* codepdp11.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS                                                                        */
  6. /*                                                                           */
  7. /* Code Generator PDP-11                                                     */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13.  
  14. #include "bpemu.h"
  15. #include "strutil.h"
  16. #include "headids.h"
  17. #include "asmdef.h"
  18. #include "asmsub.h"
  19. #include "asmpars.h"
  20. #include "asmallg.h"
  21. #include "asmcode.h"
  22. #include "asmitree.h"
  23. #include "codevars.h"
  24. #include "codepseudo.h"
  25. #include "errmsg.h"
  26. #include "intpseudo.h"
  27. #include "motpseudo.h"
  28. #include "onoff_common.h"
  29. #include "cpu2phys.h"
  30. #include "decfloat.h"
  31. #include "codepdp11.h"
  32.  
  33. #define default_regsyms_name "DEFAULT_REGSYMS"
  34.  
  35. #define REG_PC 7
  36. #define REG_SP 6
  37.  
  38. #define APR_COUNT 8
  39. #define ASSUME_COUNT (2 * APR_COUNT)
  40.  
  41. typedef enum
  42. {
  43.   ModReg = 0,
  44.   ModImm = 1,
  45.   ModMem = 2
  46. } adr_mode_t;
  47.  
  48. #define MModReg (1 << ModReg)
  49. #define MModImm (1 << ModImm)
  50. #define MModMem (1 << ModMem)
  51.  
  52. #define CODE_FLAG_GEN_IMM (1 << 0)
  53. #define CODE_FLAG_16BIT (1 << 1)
  54.  
  55. /* only used for FP11 insns */
  56.  
  57. #define CODE_FLAG_32BIT (1 << 2)
  58. #define CODE_FLAG_F64BIT (1 << 3)
  59. #define CODE_FLAG_ARGSWAP (1 << 4)
  60.  
  61. typedef struct
  62. {
  63.   Word mode;
  64.   unsigned count;
  65.   Word vals[4];
  66. } adr_vals_t;
  67.  
  68. enum
  69. {
  70.   e_ext_eis = 0, /* MUL, DIV, ASH, ASHC */
  71.   e_ext_fis = 1, /* FADD, FSUB, FDIV, FMUL */
  72.   e_ext_fp11 = 2,
  73.   e_ext_cis = 3,
  74.   e_ext_opt_cnt,
  75.   e_ext_sob_sxt = e_ext_opt_cnt,
  76.   e_ext_xor = 5,
  77.   e_ext_rtt = 6,
  78.   e_ext_mark = 7,
  79.   e_ext_mfpt = 8,
  80.   e_ext_mfp_mtp = 9,
  81.   e_ext_spl = 10,
  82.   e_ext_csm = 11,
  83.   e_ext_wrtlck = 12,
  84.   e_ext_tstset = 13,
  85.   e_ext_mfps_mtps = 14,
  86.   e_ext_wd16 = 15, /* not a real extension, but an instruction set discriminator */
  87.   e_ext_cnt
  88. };
  89.  
  90. #define e_cpu_flag_eis (1 << e_ext_eis)
  91. #define e_cpu_flag_fis (1 << e_ext_fis)
  92. #define e_cpu_flag_fp11 (1 << e_ext_fp11)
  93. #define e_cpu_flag_cis (1 << e_ext_cis)
  94. #define e_cpu_flag_sob_sxt (1 << e_ext_sob_sxt)
  95. #define e_cpu_flag_xor (1 << e_ext_xor)
  96. #define e_cpu_flag_rtt (1 << e_ext_rtt)
  97. #define e_cpu_flag_mark (1 << e_ext_mark)
  98. #define e_cpu_flag_mfpt (1 << e_ext_mfpt)
  99. #define e_cpu_flag_mfp_mtp (1 << e_ext_mfp_mtp)
  100. #define e_cpu_flag_spl (1 << e_ext_spl)
  101. #define e_cpu_flag_csm (1 << e_ext_csm)
  102. #define e_cpu_flag_wrtlck (1 << e_ext_wrtlck)
  103. #define e_cpu_flag_tstset (1 << e_ext_tstset)
  104. #define e_cpu_flag_mfps_mtps (1 << e_ext_mfps_mtps)
  105. #define e_cpu_flag_wd16 (1 << e_ext_wd16)
  106.  
  107. typedef struct
  108. {
  109.   char name[15];
  110.   Byte addr_space, opt_flags;
  111.   Word flags;
  112. } cpu_props_t;
  113.  
  114. static const cpu_props_t *p_curr_cpu_props;
  115. static tSymbolSize op_size;
  116. static Boolean default_regsyms;
  117. static LongInt *reg_par, *reg_pdr;
  118.  
  119. static Boolean is_wd16(void)
  120. {
  121.   return !!(p_curr_cpu_props->flags & e_cpu_flag_wd16);
  122. }
  123.  
  124. /*-------------------------------------------------------------------------*/
  125. /* Register Symbols */
  126.  
  127. /*!------------------------------------------------------------------------
  128.  * \fn     decode_reg_core(const char *p_arg, Word *p_result, tSymbolSize *p_size)
  129.  * \brief  check whether argument is a CPU register
  130.  * \param  p_arg argument to check
  131.  * \param  p_result numeric register value if yes
  132.  * \param  p_size returns register size
  133.  * \return True if yes
  134.  * ------------------------------------------------------------------------ */
  135.  
  136. static Boolean decode_reg_core(const char *p_arg, Word *p_result, tSymbolSize *p_size)
  137. {
  138.   if (!as_strcasecmp(p_arg, "PC") && default_regsyms)
  139.   {
  140.     *p_result = REG_PC | REGSYM_FLAG_ALIAS;
  141.     *p_size = eSymbolSize16Bit;
  142.     return True;
  143.   }
  144.   else if (!as_strcasecmp(p_arg, "SP") && default_regsyms)
  145.   {
  146.     *p_result = REG_SP | REGSYM_FLAG_ALIAS;
  147.     *p_size = eSymbolSize16Bit;
  148.     return True;
  149.   }
  150.  
  151.   switch (strlen(p_arg))
  152.   {
  153.     case 2:
  154.       if ((((as_toupper(*p_arg) == 'R') && default_regsyms)
  155.         || (*p_arg == '%'))
  156.        && isdigit(p_arg[1])
  157.        && (p_arg[1] < '8'))
  158.       {
  159.         *p_result = p_arg[1] - '0';
  160.         *p_size = eSymbolSize16Bit;
  161.         return True;
  162.       }
  163.       break;
  164.     case 3:
  165.       if ((as_toupper(*p_arg) == 'A')
  166.        && (as_toupper(p_arg[1]) == 'C')
  167.        && isdigit(p_arg[2])
  168.        && (p_arg[2] < '6'))
  169.       {
  170.         *p_result = p_arg[2] - '0';
  171.         *p_size = eSymbolSizeFloat64Bit;
  172.         return True;
  173.       }
  174.       break;
  175.     default:
  176.       break;
  177.   }
  178.   return False;
  179. }
  180.  
  181. /*!------------------------------------------------------------------------
  182.  * \fn     dissect_reg_pdp11(char *p_dest, size_t dest_size, tRegInt value, tSymbolSize inp_size)
  183.  * \brief  dissect register symbols - PDP-11 variant
  184.  * \param  p_dest destination buffer
  185.  * \param  dest_size destination buffer size
  186.  * \param  value numeric register value
  187.  * \param  inp_size register size
  188.  * ------------------------------------------------------------------------ */
  189.  
  190. static void dissect_reg_pdp11(char *p_dest, size_t dest_size, tRegInt value, tSymbolSize inp_size)
  191. {
  192.   switch (inp_size)
  193.   {
  194.     case eSymbolSize16Bit:
  195.       switch (value)
  196.       {
  197.         case REGSYM_FLAG_ALIAS | REG_PC:
  198.           as_snprintf(p_dest, dest_size, "PC");
  199.           break;
  200.         case REGSYM_FLAG_ALIAS | REG_SP:
  201.           as_snprintf(p_dest, dest_size, "SP");
  202.           break;
  203.         default:
  204.           as_snprintf(p_dest, dest_size, "R%u", (unsigned)(value & 7));
  205.       }
  206.       break;
  207.     case eSymbolSizeFloat64Bit:
  208.       as_snprintf(p_dest, dest_size, "AC%u", (unsigned)(value & 7));
  209.       break;
  210.     default:
  211.       as_snprintf(p_dest, dest_size, "%d-%u", (int)inp_size, (unsigned)value);
  212.   }
  213. }
  214.  
  215. /*--------------------------------------------------------------------------*/
  216. /* PDP-11 specific flags */
  217.  
  218. /*!------------------------------------------------------------------------
  219.  * \fn     onoff_ext_add(Boolean def_value)
  220.  * \brief  register on/off command for specific instruction set extension
  221.  * \param  def_value default value of flag upon first use
  222.  * ------------------------------------------------------------------------ */
  223.  
  224. static Byte ext_registered = 0;
  225.  
  226. unsigned ext_test_and_set(unsigned mask)
  227. {
  228.   unsigned curr = ext_registered;
  229.  
  230.   ext_registered |= mask;
  231.   return curr & mask;
  232. }
  233.  
  234. static const char ext_names[e_ext_opt_cnt][5] = { "EIS", "FIS", "FP11", "CIS" };
  235. static Boolean ext_avail[e_ext_opt_cnt];
  236.  
  237. /* default value setting only upon first registration, similar to scheme in
  238.    onoff_common.c: */
  239.  
  240. static void onoff_ext_add(unsigned ext, Boolean def_value)
  241. {
  242.   Byte ext_mask = 1 << ext;
  243.  
  244.   if (!ext_test_and_set(ext_mask))
  245.     SetFlag(&ext_avail[ext], ext_names[ext], def_value);
  246.   AddONOFF(ext_names[ext], &ext_avail[ext], ext_names[ext], False);
  247. }
  248.  
  249. /*!------------------------------------------------------------------------
  250.  * \fn     check_cpu_ext(unsigned ext)
  251.  * \brief  check whether instruction is allowed on CPU
  252.  * \param  ext request instruction set extension
  253.  * \return True if usage is OK
  254.  * ------------------------------------------------------------------------ */
  255.  
  256. static Boolean check_cpu_ext(unsigned ext)
  257. {
  258.   unsigned mask = 1 << ext;
  259.  
  260.   if (p_curr_cpu_props->flags & mask)
  261.     return True;
  262.   else if ((ext < e_ext_opt_cnt) && (p_curr_cpu_props->opt_flags & mask) && ext_avail[ext])
  263.     return True;
  264.   else
  265.   {
  266.     if (ext < e_ext_opt_cnt)
  267.       WrXErrorPos(ErrNum_InstructionNotSupported, ext_names[ext], &OpPart.Pos);
  268.     else
  269.       WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  270.     return False;
  271.   }
  272. }
  273.  
  274. /*--------------------------------------------------------------------------*/
  275. /* Address Mode Parser */
  276.  
  277. /*!------------------------------------------------------------------------
  278.  * \fn     check_sup_mode(void)
  279.  * \brief  check for CPU in supervisor mode
  280.  * \return constant true
  281.  * ------------------------------------------------------------------------ */
  282.  
  283. static Boolean check_sup_mode(void)
  284. {
  285.   if (!SupAllowed)
  286.     WrStrErrorPos(ErrNum_PrivOrder, &OpPart);
  287.   return True;
  288. }
  289.  
  290. /*!------------------------------------------------------------------------
  291.  * \fn     reset_adr_vals(adr_vals_t *p_vals)
  292.  * \brief  clear encoded addressing mode
  293.  * \param  p_vals encoded mode to reset
  294.  * ------------------------------------------------------------------------ */
  295.  
  296. static void reset_adr_vals(adr_vals_t *p_vals)
  297. {
  298.   p_vals->mode = 0;
  299.   p_vals->count = 0;
  300.   p_vals->vals[0] = 0;
  301. }
  302.  
  303. /*!------------------------------------------------------------------------
  304.  * \fn     decode_reg(const tStrComp *p_arg, Word *p_result, tSymbolSize *p_size, tSymbolSize req_size, Boolean must_be_reg)
  305.  * \brief  check whether argument is a CPU register or register alias
  306.  * \param  p_arg argument to check
  307.  * \param  p_result numeric register value if yes
  308.  * \param  p_size returns operand size of register (I16 or F64)
  309.  * \param  req_size request specific operand/register size
  310.  * \param  must_be_reg argument is expected to be a register
  311.  * \return RegEvalResult
  312.  * ------------------------------------------------------------------------ */
  313.  
  314. static tErrorNum chk_reg_size(tSymbolSize req_size, tSymbolSize act_size)
  315. {
  316.   if ((act_size == eSymbolSizeUnknown)
  317.    || (req_size == eSymbolSizeUnknown)
  318.    || (req_size == act_size))
  319.     return ErrNum_None;
  320.   else if ((req_size == eSymbolSize16Bit) && (act_size == eSymbolSizeFloat64Bit))
  321.     return ErrNum_IntButFloat;
  322.   else if ((req_size == eSymbolSizeFloat64Bit) && (act_size == eSymbolSize16Bit))
  323.     return ErrNum_FloatButInt;
  324.   else
  325.     return ErrNum_InvOpSize;
  326. }
  327.  
  328. static tRegEvalResult decode_reg(const tStrComp *p_arg, Word *p_result, tSymbolSize *p_size, tSymbolSize req_size, Boolean must_be_reg)
  329. {
  330.   tRegDescr reg_descr;
  331.   tEvalResult eval_result;
  332.   tRegEvalResult reg_eval_result;
  333.  
  334.   if (decode_reg_core(p_arg->str.p_str, p_result, &eval_result.DataSize))
  335.   {
  336.     reg_descr.Reg = *p_result;
  337.     reg_eval_result = eIsReg;
  338.   }
  339.   else
  340.     reg_eval_result = EvalStrRegExpressionAsOperand(p_arg, &reg_descr, &eval_result, eSymbolSizeUnknown, must_be_reg);
  341.  
  342.   if (reg_eval_result == eIsReg)
  343.   {
  344.     tErrorNum error_num = chk_reg_size(req_size, eval_result.DataSize);
  345.  
  346.     if (error_num)
  347.     {
  348.       WrStrErrorPos(error_num, p_arg);
  349.       reg_eval_result = must_be_reg ? eIsNoReg : eRegAbort;
  350.     }
  351.   }
  352.  
  353.   *p_result = reg_descr.Reg & ~REGSYM_FLAG_ALIAS;
  354.   if (p_size) *p_size = eval_result.DataSize;
  355.   return reg_eval_result;
  356. }
  357.  
  358. static Boolean decode_reg_or_const(const tStrComp *p_arg, Word *p_result)
  359. {
  360.   switch (decode_reg(p_arg, p_result, NULL, eSymbolSize16Bit, False))
  361.   {
  362.     case eIsReg:
  363.       return True;
  364.     case eIsNoReg:
  365.     {
  366.       Boolean ok;
  367.       *p_result = EvalStrIntExpression(p_arg, UInt3, &ok);
  368.       return ok;
  369.     }
  370.     default:
  371.       return False;
  372.   }
  373. }
  374.  
  375. /*!------------------------------------------------------------------------
  376.  * \fn     decode_adr(tStrComp *p_arg, adr_vals_t *p_result, Word pc_value, unsigned mode_mask)
  377.  * \brief  parse address expression
  378.  * \param  p_arg source argument
  379.  * \param  p_result parsed result
  380.  * \param  pc_value value of PC to be used in PC-relative calculation
  381.  * \param  mode_mask bit mask of allowed addressing modes
  382.  * \return True if success
  383.  * ------------------------------------------------------------------------ */
  384.  
  385. static Boolean is_pre_decrement(const tStrComp *p_arg, Word *p_result, tRegEvalResult *p_reg_eval_result)
  386. {
  387.   String reg;
  388.   tStrComp reg_comp;
  389.   size_t arg_len = strlen(p_arg->str.p_str);
  390.  
  391.   if ((arg_len < 4)
  392.    || (p_arg->str.p_str[0] != '-')
  393.    || (p_arg->str.p_str[1] != '(')
  394.    || (p_arg->str.p_str[arg_len - 1] != ')'))
  395.     return False;
  396.   StrCompMkTemp(&reg_comp, reg, sizeof(reg));
  397.   StrCompCopySub(&reg_comp, p_arg, 2, arg_len - 3);
  398.   KillPrefBlanksStrComp(&reg_comp);
  399.   KillPostBlanksStrComp(&reg_comp);
  400.   *p_reg_eval_result = decode_reg(&reg_comp, p_result, NULL, eSymbolSize16Bit, False);
  401.   return (*p_reg_eval_result != eIsNoReg);
  402. }
  403.  
  404. static Boolean is_post_increment(const tStrComp *p_arg, Word *p_result, tRegEvalResult *p_reg_eval_result)
  405. {
  406.   String reg;
  407.   tStrComp reg_comp;
  408.   size_t arg_len = strlen(p_arg->str.p_str);
  409.  
  410.   if ((arg_len < 4)
  411.    || (p_arg->str.p_str[0] != '(')
  412.    || (p_arg->str.p_str[arg_len - 2] != ')')
  413.    || (p_arg->str.p_str[arg_len - 1] != '+'))
  414.     return False;
  415.   StrCompMkTemp(&reg_comp, reg, sizeof(reg));
  416.   StrCompCopySub(&reg_comp, p_arg, 1, arg_len - 3);
  417.   KillPrefBlanksStrComp(&reg_comp);
  418.   KillPostBlanksStrComp(&reg_comp);
  419.  
  420.   /* Opposed to -(...), (...)+ cannot be interpreted as an arbitrary
  421.      arithmetic expression.  The expression in parentheses MUST be a
  422.      register: */
  423.  
  424.   *p_reg_eval_result = decode_reg(&reg_comp, p_result, NULL, eSymbolSize16Bit, True);
  425.   if (*p_reg_eval_result == eIsNoReg)
  426.     *p_reg_eval_result = eRegAbort;
  427.   return (*p_reg_eval_result != eIsNoReg);
  428. }
  429.  
  430. static Boolean decode_abs(const tStrComp *p_arg, Word *p_addr)
  431. {
  432.   Boolean ok;
  433.  
  434.   *p_addr = EvalStrIntExpression(p_arg, UInt16, &ok);
  435.   return ok;
  436. }
  437.  
  438. static Boolean decode_imm8(const tStrComp *p_arg, Word *p_value)
  439. {
  440.   Boolean ok;
  441.  
  442.   *p_value = EvalStrIntExpression(p_arg, Int8, &ok) & 0xff;
  443.   return ok;
  444. }
  445.  
  446. static Boolean check_mode_mask(unsigned mode_mask, unsigned act_mask, tStrComp *p_arg)
  447. {
  448.   if (!(mode_mask & act_mask))
  449.   {
  450.     WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  451.     return False;
  452.   }
  453.   else
  454.     return True;
  455. }
  456.  
  457. static Boolean decode_adr(tStrComp *p_arg, adr_vals_t *p_result, Word pc_value, unsigned mode_mask)
  458. {
  459.   tEvalResult eval_result;
  460.   tRegEvalResult reg_eval_result;
  461.   Boolean deferred;
  462.   tStrComp arg;
  463.   int arg_len, split_pos;
  464.  
  465.   reset_adr_vals(p_result);
  466.  
  467.   /* split off deferred flag? */
  468.  
  469.   deferred = (p_arg->str.p_str[0] == '@');
  470.   StrCompRefRight(&arg, p_arg, deferred);
  471.   if (deferred)
  472.     KillPrefBlanksStrCompRef(&arg);
  473.  
  474.   /* Rn, @Rn, ACn: */
  475.  
  476.   switch (decode_reg(&arg, &p_result->mode, NULL, (deferred || (op_size < eSymbolSizeFloat32Bit)) ? eSymbolSize16Bit : eSymbolSizeFloat64Bit, False))
  477.   {
  478.     case eIsReg:
  479.       p_result->mode |= deferred ? 010 : 000;
  480.       return check_mode_mask(mode_mask, deferred ? MModMem : MModReg, p_arg);
  481.     case eRegAbort:
  482.       return False;
  483.     default:
  484.       break;
  485.   }
  486.  
  487.   /* #imm, @#abs */
  488.  
  489.   if (*arg.str.p_str == '#')
  490.   {
  491.     tStrComp imm_arg;
  492.  
  493.     if (!deferred && !check_mode_mask(mode_mask, deferred ? MModMem : MModImm, p_arg))
  494.       return False;
  495.     StrCompRefRight(&imm_arg, &arg, 1);
  496.  
  497.     if (deferred)
  498.     {
  499.       eval_result.OK = decode_abs(&imm_arg, &p_result->vals[0]);
  500.       if (eval_result.OK)
  501.         p_result->count = 2;
  502.     }
  503.     else switch (op_size)
  504.     {
  505.       case eSymbolSize8Bit:
  506.         eval_result.OK = decode_imm8(&imm_arg, &p_result->vals[0]);
  507.         if (eval_result.OK)
  508.           p_result->count = 2;
  509.         break;
  510.       case eSymbolSize16Bit:
  511.         p_result->vals[0] = EvalStrIntExpressionWithResult(&imm_arg, Int16, &eval_result);
  512.         if (eval_result.OK)
  513.           p_result->count = 2;
  514.         break;
  515.       case eSymbolSize32Bit:
  516.       {
  517.         LongWord l_val = EvalStrIntExpressionWithResult(&imm_arg, Int32, &eval_result);
  518.         if (eval_result.OK)
  519.         {
  520.           p_result->vals[0] = (l_val >> 16) & 0xffff;
  521.           p_result->vals[1] = l_val & 0xffff;
  522.           p_result->count = 4;
  523.         }
  524.         break;
  525.       }
  526.       case eSymbolSizeFloat32Bit:
  527.       {
  528.         Double f_val = EvalStrFloatExpressionWithResult(&imm_arg, Float64, &eval_result);
  529.         if (eval_result.OK)
  530.         {
  531.           int ret = Double_2_dec4(f_val, p_result->vals);
  532.           eval_result.OK = check_dec_fp_dispose_result(ret, &imm_arg);
  533.         }
  534.         if (eval_result.OK)
  535.           p_result->count = 4;
  536.         break;
  537.       }  
  538.       case eSymbolSizeFloat64Bit:
  539.       {
  540.         Double f_val = EvalStrFloatExpressionWithResult(&imm_arg, Float64, &eval_result);
  541.         if (eval_result.OK)
  542.         {
  543.           int ret = Double_2_dec8(f_val, p_result->vals);
  544.           eval_result.OK = check_dec_fp_dispose_result(ret, &imm_arg);
  545.         }
  546.         if (eval_result.OK)
  547.           p_result->count = 8;
  548.         break;
  549.       }  
  550.       case eSymbolSizeUnknown:
  551.         WrStrErrorPos(ErrNum_UndefOpSizes, p_arg);
  552.         eval_result.OK = False;
  553.         break;
  554.       default:
  555.         WrStrErrorPos(ErrNum_InvOpSize, p_arg);
  556.         eval_result.OK = False;
  557.     }
  558.     if (eval_result.OK)
  559.     {
  560.       /* immediate is actually (PC)+, absolute is actually @(PC)+ */
  561.  
  562.       p_result->mode = (deferred ? 030 : 020) | REG_PC;
  563.     }
  564.     return eval_result.OK;
  565.   }
  566.  
  567.   /* (Rn)+, @(Rn)+ */
  568.  
  569.   if (is_post_increment(&arg, &p_result->mode, &reg_eval_result))
  570.   {
  571.     if (eRegAbort == reg_eval_result)
  572.       return False;
  573.     p_result->mode |= deferred ? 030 : 020;
  574.     return check_mode_mask(mode_mask, MModMem, p_arg);
  575.   }
  576.  
  577.   /* -(Rn), @-(Rn) */
  578.  
  579.   if (is_pre_decrement(&arg, &p_result->mode, &reg_eval_result))
  580.   {
  581.     if (eRegAbort == reg_eval_result)
  582.       return False;
  583.     p_result->mode |= (deferred ? 050 : 040);
  584.     return check_mode_mask(mode_mask, MModMem, p_arg);
  585.   }
  586.  
  587.   /* (Rn), X(Rn) */
  588.  
  589.   split_pos = FindDispBaseSplitWithQualifier(arg.str.p_str, &arg_len, NULL, "()");
  590.   if (split_pos >= 0)
  591.   {
  592.     tStrComp disp_arg, reg_arg;
  593.  
  594.     StrCompSplitRef(&disp_arg, &reg_arg, &arg, &arg.str.p_str[split_pos]);
  595.     KillPostBlanksStrComp(&disp_arg);
  596.     KillPrefBlanksStrCompRef(&reg_arg);
  597.     StrCompShorten(&reg_arg, 1);
  598.     KillPostBlanksStrComp(&reg_arg);
  599.  
  600.     if (!decode_reg_or_const(&reg_arg, &p_result->mode))
  601.       return False;
  602.     if (!*disp_arg.str.p_str && !deferred)
  603.       p_result->mode |= 010;
  604.     else
  605.     {
  606.       p_result->vals[0] = EvalStrIntExpressionWithResult(&disp_arg, Int16, &eval_result);
  607.       if (!eval_result.OK)
  608.         return False;
  609.       p_result->mode |= deferred ? 070 : 060;
  610.       p_result->count = 2;
  611.     }
  612.     return check_mode_mask(mode_mask, MModMem, p_arg);
  613.   }
  614.  
  615.   /* Remains: rel, @rel
  616.      PC value is the PC value after displacement was loaded: */
  617.  
  618.   p_result->vals[0] = EvalStrIntExpressionWithResult(&arg, UInt16, &eval_result) - (pc_value + 2);
  619.   if (!eval_result.OK)
  620.     return False;
  621.   p_result->mode = REG_PC | (deferred ? 070 : 060);
  622.   p_result->count = 2;
  623.   return check_mode_mask(mode_mask, MModMem, p_arg);
  624. }
  625.  
  626. /*!------------------------------------------------------------------------
  627.  * \fn     decode_ac_03(tStrComp *p_arg, Word *p_result)
  628.  * \brief  handle FP11 argument that may only refer AC0...AC3
  629.  * \param  p_arg source argument
  630.  * \param  p_result resulting AC number
  631.  * \return True if valid argument
  632.  * ------------------------------------------------------------------------ */
  633.  
  634. static Boolean decode_ac_03(tStrComp *p_arg, Word *p_result)
  635. {
  636.   adr_vals_t adr_vals;
  637.  
  638.   /* operand size must have been set to a floating point type before */
  639.   if (!decode_adr(p_arg, &adr_vals, EProgCounter() + 2, MModReg))
  640.     return False;
  641.   *p_result = adr_vals.mode & 7;
  642.   if (*p_result > 3)
  643.   {
  644.     WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  645.     return False;
  646.   }
  647.   return True;
  648. }
  649.  
  650. /*--------------------------------------------------------------------------*/
  651. /* Instruction Handler Helpers */
  652.  
  653. static void append_word(Word code)
  654. {
  655.   WAsmCode[CodeLen >> 1] = code;
  656.   CodeLen += 2;
  657. }
  658.  
  659. static void append_adr_vals(const adr_vals_t *p_vals)
  660. {
  661.   if (p_vals->count >= 2)
  662.     append_word(p_vals->vals[0]);
  663.   if (p_vals->count >= 4)
  664.     append_word(p_vals->vals[1]);
  665.   if (p_vals->count >= 6)
  666.     append_word(p_vals->vals[2]);
  667.   if (p_vals->count >= 8)
  668.     append_word(p_vals->vals[3]);
  669. }
  670.  
  671. static unsigned imm_mask(Word code)
  672. {
  673.   return (code & CODE_FLAG_GEN_IMM) ? MModImm : 0;
  674. }
  675.  
  676. /*--------------------------------------------------------------------------*/
  677. /* Instruction Handlers */
  678.  
  679. /*!------------------------------------------------------------------------
  680.  * \fn     decode_fixed(Word code)
  681.  * \brief  handle instructions without argument
  682.  * \param  code machine code
  683.  * ------------------------------------------------------------------------ */
  684.  
  685. static void decode_fixed(Word code)
  686. {
  687.   if (ChkArgCnt(0, 0))
  688.     append_word(code);
  689. }
  690.  
  691. /*!------------------------------------------------------------------------
  692.  * \fn     decode_fixed_sup(Word code)
  693.  * \brief  handle privileged instructions without argument
  694.  * \param  code machine code
  695.  * ------------------------------------------------------------------------ */
  696.  
  697. static void decode_fixed_sup(Word code)
  698. {
  699.   if (ChkArgCnt(0, 0) && check_sup_mode())
  700.     append_word(code);
  701. }
  702.  
  703. /*!------------------------------------------------------------------------
  704.  * \fn     decode_mfpt(Word code)
  705.  * \brief  handle MFPT instruction
  706.  * \param  code machine code
  707.  * ------------------------------------------------------------------------ */
  708.  
  709. static void decode_mfpt(Word code)
  710. {
  711.   if (ChkArgCnt(0, 0) && check_cpu_ext(e_ext_mfpt))
  712.     append_word(code);
  713. }
  714.  
  715. /*!------------------------------------------------------------------------
  716.  * \fn     decode_rtt(Word code)
  717.  * \brief  handle RTT instruction
  718.  * \param  code machine code
  719.  * ------------------------------------------------------------------------ */
  720.  
  721. static void decode_rtt(Word code)
  722. {
  723.   if (ChkArgCnt(0, 0) && check_cpu_ext(e_ext_rtt))
  724.     append_word(code);
  725. }
  726.  
  727. /*!------------------------------------------------------------------------
  728.  * \fn     decode_one_reg(Word code)
  729.  * \brief  handle instructions with one register as argument
  730.  * \param  code machine code
  731.  * ------------------------------------------------------------------------ */
  732.  
  733. static void decode_one_reg(Word code)
  734. {
  735.   if (ChkArgCnt(1, 1))
  736.   {
  737.     adr_vals_t reg_adr_vals;
  738.  
  739.     op_size = eSymbolSize16Bit;
  740.     if (decode_adr(&ArgStr[1], &reg_adr_vals, EProgCounter() + 2, MModReg))
  741.       append_word((code & 0xfff8) | reg_adr_vals.mode);
  742.   }
  743. }
  744.  
  745. /*!------------------------------------------------------------------------
  746.  * \fn     decode_two_reg(Word code)
  747.  * \brief  handle instructions with two registers as argument
  748.  * \param  code machine code
  749.  * ------------------------------------------------------------------------ */
  750.  
  751. static void decode_two_reg(Word code)
  752. {
  753.   if (ChkArgCnt(2, 2))
  754.   {
  755.     adr_vals_t src_adr_vals, dest_adr_vals;
  756.  
  757.     op_size = eSymbolSize16Bit;
  758.     if (decode_adr(&ArgStr[1], &src_adr_vals, EProgCounter() + 2, MModReg)
  759.      && decode_adr(&ArgStr[2], &dest_adr_vals, EProgCounter() + 2, MModReg))
  760.       append_word((code & 0xffc0) | ((src_adr_vals.mode & 7) << 3) | (dest_adr_vals.mode & 7));
  761.   }
  762. }
  763.  
  764. /*!------------------------------------------------------------------------
  765.  * \fn     decode_one_arg(Word code)
  766.  * \brief  handle instructions with one generic arg
  767.  * \param  code machine code
  768.  * ------------------------------------------------------------------------ */
  769.  
  770. static void decode_one_arg(Word code)
  771. {
  772.   if (ChkArgCnt(1, 1))
  773.   {
  774.     adr_vals_t adr_vals;
  775.  
  776.     op_size = (code & CODE_FLAG_16BIT) ? eSymbolSize16Bit : eSymbolSize8Bit;
  777.     if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModReg | MModMem | imm_mask(code)))
  778.     {
  779.       append_word((code & 0177700) | adr_vals.mode);
  780.       append_adr_vals(&adr_vals);
  781.     }
  782.   }
  783. }
  784.  
  785. /*!------------------------------------------------------------------------
  786.  * \fn     decode_tstset(Word code)
  787.  * \brief  handle TSTSET instruction
  788.  * \param  code machine code
  789.  * ------------------------------------------------------------------------ */
  790.  
  791. static void decode_tstset(Word code)
  792. {
  793.   if (ChkArgCnt(1, 1) && check_cpu_ext(e_ext_tstset))
  794.   {
  795.     adr_vals_t adr_vals;
  796.  
  797.     op_size = (code & CODE_FLAG_16BIT) ? eSymbolSize16Bit : eSymbolSize8Bit;
  798.     if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModReg | MModMem | imm_mask(code)))
  799.     {
  800.       append_word((code & 0177700) | adr_vals.mode);
  801.       append_adr_vals(&adr_vals);
  802.     }
  803.   }
  804. }
  805.  
  806. /*!------------------------------------------------------------------------
  807.  * \fn     decode_mfp_mtp(Word code)
  808.  * \brief  handle MFP/MTP instructions
  809.  * \param  code machine code
  810.  * ------------------------------------------------------------------------ */
  811.  
  812. static void decode_mfp_mtp(Word code)
  813. {
  814.   if (ChkArgCnt(1, 1) && check_cpu_ext(e_ext_mfp_mtp))
  815.   {
  816.     adr_vals_t adr_vals;
  817.  
  818.     op_size = (code & CODE_FLAG_16BIT) ? eSymbolSize16Bit : eSymbolSize8Bit;
  819.     if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModReg | MModMem | imm_mask(code)))
  820.     {
  821.       append_word((code & 0177700) | adr_vals.mode);
  822.       append_adr_vals(&adr_vals);
  823.     }
  824.   }
  825. }
  826.  
  827. /*!------------------------------------------------------------------------
  828.  * \fn     decode_mfps_mtps(Word code)
  829.  * \brief  handle MFPS/MTPS instructions
  830.  * \param  code machine code
  831.  * ------------------------------------------------------------------------ */
  832.  
  833. static void decode_mfps_mtps(Word code)
  834. {
  835.   if (ChkArgCnt(1, 1) && check_cpu_ext(e_ext_mfps_mtps))
  836.   {
  837.     adr_vals_t adr_vals;
  838.  
  839.     op_size = (code & CODE_FLAG_16BIT) ? eSymbolSize16Bit : eSymbolSize8Bit;
  840.     if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModReg | MModMem | imm_mask(code)))
  841.     {
  842.       append_word((code & 0177700) | adr_vals.mode);
  843.       append_adr_vals(&adr_vals);
  844.     }
  845.   }
  846. }
  847.  
  848. /*!------------------------------------------------------------------------
  849.  * \fn     decode_csm(Word code)
  850.  * \brief  handle CSM instruction
  851.  * \param  code machine code
  852.  * ------------------------------------------------------------------------ */
  853.  
  854. static void decode_csm(Word code)
  855. {
  856.   /* TODO: not in kernel mode */
  857.   if (ChkArgCnt(1, 1) && check_cpu_ext(e_ext_csm))
  858.   {
  859.     adr_vals_t adr_vals;
  860.  
  861.     op_size = (code & CODE_FLAG_16BIT) ? eSymbolSize16Bit : eSymbolSize8Bit;
  862.     if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModReg | MModMem | imm_mask(code)))
  863.     {
  864.       append_word((code & 0177700) | adr_vals.mode);
  865.       append_adr_vals(&adr_vals);
  866.     }
  867.   }
  868. }
  869.  
  870. /*!------------------------------------------------------------------------
  871.  * \fn     decode_sxt(Word code)
  872.  * \brief  handle SXT instruction
  873.  * \param  code machine code
  874.  * ------------------------------------------------------------------------ */
  875.  
  876. static void decode_sxt(Word code)
  877. {
  878.   if (ChkArgCnt(1, 1) && check_cpu_ext(e_ext_sob_sxt))
  879.   {
  880.     adr_vals_t adr_vals;
  881.  
  882.     op_size = (code & CODE_FLAG_16BIT) ? eSymbolSize16Bit : eSymbolSize8Bit;
  883.     if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModReg | MModMem | imm_mask(code)))
  884.     {
  885.       append_word((code & 0177700) | adr_vals.mode);
  886.       append_adr_vals(&adr_vals);
  887.     }
  888.   }
  889. }
  890.  
  891. /*!------------------------------------------------------------------------
  892.  * \fn     decode_fp11_f1_f3(Word code)
  893.  * \brief  handle FP11 instructions with two arguments (AC is dest)
  894.  * \param  code machine code
  895.  * ------------------------------------------------------------------------ */
  896.  
  897. static void decode_fp11_f1_f3(Word code)
  898. {
  899.   if (ChkArgCnt(2, 2) && check_cpu_ext(e_ext_fp11))
  900.   {
  901.     adr_vals_t adr_vals;
  902.     Word ac_num;
  903.     int ac_arg_index = (code & CODE_FLAG_ARGSWAP) ? 1 : 2;
  904.  
  905.     if (code & CODE_FLAG_16BIT)
  906.       op_size = eSymbolSize16Bit;
  907.     else if (code & CODE_FLAG_32BIT)
  908.       op_size = eSymbolSize32Bit;
  909.     else if (code & CODE_FLAG_F64BIT)
  910.       op_size = eSymbolSizeFloat64Bit;
  911.     else
  912.       op_size = eSymbolSizeFloat32Bit;
  913.     if (decode_adr(&ArgStr[3 - ac_arg_index], &adr_vals, EProgCounter() + 2, MModReg | MModMem | imm_mask(code)))
  914.     {
  915.       op_size = (code & CODE_FLAG_F64BIT) ? eSymbolSizeFloat64Bit : eSymbolSizeFloat32Bit;
  916.       if (decode_ac_03(&ArgStr[ac_arg_index], &ac_num))
  917.       {
  918.         append_word((code & 0177400) | (ac_num << 6) | adr_vals.mode);
  919.         append_adr_vals(&adr_vals);
  920.       }
  921.     }
  922.   }
  923. }
  924.  
  925. /*!------------------------------------------------------------------------
  926.  * \fn     decode_fp11_f2(Word code)
  927.  * \brief  handle FP11 instructions with one (float) arg
  928.  * \param  code machine code
  929.  * ------------------------------------------------------------------------ */
  930.  
  931. static void decode_fp11_f2(Word code)
  932. {
  933.   if (ChkArgCnt(1, 1) && check_cpu_ext(e_ext_fp11))
  934.   {
  935.     adr_vals_t adr_vals;
  936.  
  937.     op_size = (code & CODE_FLAG_F64BIT) ? eSymbolSizeFloat64Bit : eSymbolSizeFloat32Bit;
  938.     if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModReg | MModMem | imm_mask(code)))
  939.     {
  940.       append_word((code & 0177700) | adr_vals.mode);
  941.       append_adr_vals(&adr_vals);
  942.     }
  943.   }
  944. }
  945.  
  946. /*!------------------------------------------------------------------------
  947.  * \fn     void decode_fp11_f4(Word code)
  948.  * \brief  handle FP11 instructions with one (int) arg
  949.  * \param  code machine code
  950.  * ------------------------------------------------------------------------ */
  951.  
  952. static void decode_fp11_f4(Word code)
  953. {
  954.   if (ChkArgCnt(1, 1) && check_cpu_ext(e_ext_fp11))
  955.   {
  956.     adr_vals_t adr_vals;
  957.  
  958.     if (code & CODE_FLAG_16BIT)
  959.       op_size = eSymbolSize16Bit;
  960.     else if (code & CODE_FLAG_32BIT)
  961.       op_size = eSymbolSize32Bit;
  962.     else
  963.       op_size = eSymbolSize8Bit;
  964.     if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModReg | MModMem | imm_mask(code)))
  965.     {
  966.       append_word((code & 0177700) | adr_vals.mode);
  967.       append_adr_vals(&adr_vals);
  968.     }
  969.   }
  970. }
  971.  
  972. /*!------------------------------------------------------------------------
  973.  * \fn     decode_fp11_f5(Word code)
  974.  * \brief  handle FP11 instructions with no arg
  975.  * \param  code machine code
  976.  * ------------------------------------------------------------------------ */
  977.  
  978. static void decode_fp11_f5(Word code)
  979. {
  980.   if (ChkArgCnt(0, 0) && check_cpu_ext(e_ext_fp11))
  981.     append_word(code);
  982. }
  983.  
  984. /*!------------------------------------------------------------------------
  985.  * \fn     decode_cis_0(Word code)
  986.  * \brief  handle CIS instructions with no arguments
  987.  * \param  code machine code
  988.  * ------------------------------------------------------------------------ */
  989.  
  990. static void decode_cis_0(Word code)
  991. {
  992.   if (ChkArgCnt(0, 0) && check_cpu_ext(e_ext_cis))
  993.     append_word(code);
  994. }
  995.  
  996. /* TODO: CIS instructions take address of descriptors.  Should
  997.    this be written as absolute addressing? */
  998.  
  999. /*!------------------------------------------------------------------------
  1000.  * \fn     decode_cis_1i(Word code)
  1001.  * \brief  handle CIS instructions with one address and one immediate argument
  1002.  * \param  code machine code
  1003.  * ------------------------------------------------------------------------ */
  1004.  
  1005. static void decode_cis_1i(Word code)
  1006. {
  1007.   Word src, imm;
  1008.  
  1009.   if (ChkArgCnt(2, 2)
  1010.    && check_cpu_ext(e_ext_cis)
  1011.    && decode_abs(&ArgStr[1], &src)
  1012.    && decode_imm8(&ArgStr[2], &imm))
  1013.   {
  1014.     append_word(code);
  1015.     append_word(src);
  1016.     append_word(imm);
  1017.   }
  1018. }
  1019.  
  1020. /*!------------------------------------------------------------------------
  1021.  * \fn     decode_cis_2(Word code)
  1022.  * \brief  handle CIS instructions with two address arguments
  1023.  * \param  code machine code
  1024.  * ------------------------------------------------------------------------ */
  1025.  
  1026. static void decode_cis_2(Word code)
  1027. {
  1028.   Word src, dest;
  1029.  
  1030.   if (ChkArgCnt(2, 2)
  1031.    && check_cpu_ext(e_ext_cis)
  1032.    && decode_abs(&ArgStr[1], &src)
  1033.    && decode_abs(&ArgStr[2], &dest))
  1034.   {
  1035.     append_word(code);
  1036.     append_word(src);
  1037.     append_word(dest);
  1038.   }
  1039. }
  1040.  
  1041. /*!------------------------------------------------------------------------
  1042.  * \fn     decode_cis_2i(Word code)
  1043.  * \brief  handle CIS instructions with two address and one immediate argument
  1044.  * \param  code machine code
  1045.  * ------------------------------------------------------------------------ */
  1046.  
  1047. static void decode_cis_2i(Word code)
  1048. {
  1049.   Word src, dest, imm;
  1050.  
  1051.   if (ChkArgCnt(3, 3)
  1052.    && check_cpu_ext(e_ext_cis)
  1053.    && decode_abs(&ArgStr[1], &src)
  1054.    && decode_abs(&ArgStr[2], &dest)
  1055.    && decode_imm8(&ArgStr[3], &imm))
  1056.   {
  1057.     append_word(code);
  1058.     append_word(src);
  1059.     append_word(dest);
  1060.     append_word(imm);
  1061.   }
  1062. }
  1063.  
  1064. /*!------------------------------------------------------------------------
  1065.  * \fn     decode_cis_2i1(Word code)
  1066.  * \brief  handle CIS instructions with two src address, one immediate,
  1067.            and one dest address argument
  1068.  * \param  code machine code
  1069.  * ------------------------------------------------------------------------ */
  1070.  
  1071. static void decode_cis_2i1(Word code)
  1072. {
  1073.   Word src1, src2, dest, imm;
  1074.  
  1075.   if (ChkArgCnt(4, 4)
  1076.    && check_cpu_ext(e_ext_cis)
  1077.    && decode_abs(&ArgStr[1], &src1)
  1078.    && decode_abs(&ArgStr[2], &src2)
  1079.    && decode_imm8(&ArgStr[3], &imm)
  1080.    && decode_abs(&ArgStr[4], &dest))
  1081.   {
  1082.     append_word(code);
  1083.     append_word(src1);
  1084.     append_word(src2);
  1085.     append_word(imm);
  1086.     append_word(dest);
  1087.   }
  1088. }
  1089.  
  1090. /*!------------------------------------------------------------------------
  1091.  * \fn     decode_cis_3(Word code)
  1092.  * \brief  handle CIS instructions with three address arguments
  1093.  * \param  code machine code
  1094.  * ------------------------------------------------------------------------ */
  1095.  
  1096. static void decode_cis_3(Word code)
  1097. {
  1098.   Word src1, src2, dest;
  1099.  
  1100.   if (ChkArgCnt(3, 3)
  1101.    && check_cpu_ext(e_ext_cis)
  1102.    && decode_abs(&ArgStr[1], &src1)
  1103.    && decode_abs(&ArgStr[2], &src2)
  1104.    && decode_abs(&ArgStr[3], &dest))
  1105.   {
  1106.     append_word(code);
  1107.     append_word(src1);
  1108.     append_word(src2);
  1109.     append_word(dest);
  1110.   }
  1111. }
  1112.  
  1113. /*!------------------------------------------------------------------------
  1114.  * \fn     decode_cis_ld(Word code)
  1115.  * \brief  handle CIS instructions with one post-inc argument
  1116.  * \param  code machine code
  1117.  * ------------------------------------------------------------------------ */
  1118.  
  1119. static void decode_cis_ld(Word code)
  1120. {
  1121.   adr_vals_t adr_vals;
  1122.  
  1123.   if (ChkArgCnt(1, 1)
  1124.    && check_cpu_ext(e_ext_cis)
  1125.    && decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModMem))
  1126.   {
  1127.     if ((adr_vals.mode & 070) != 020) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  1128.     else
  1129.       append_word(code | (adr_vals.mode & 07));
  1130.   }
  1131. }
  1132.  
  1133. /*!------------------------------------------------------------------------
  1134.  * \fn     decode_wrtlck(Word code)
  1135.  * \brief  handle WRTLCK instruction
  1136.  * \param  code machine code
  1137.  * ------------------------------------------------------------------------ */
  1138.  
  1139. static void decode_wrtlck(Word code)
  1140. {
  1141.   if (ChkArgCnt(1, 1) && check_cpu_ext(e_ext_wrtlck))
  1142.   {
  1143.     adr_vals_t adr_vals;
  1144.  
  1145.     op_size = (code & CODE_FLAG_16BIT) ? eSymbolSize16Bit : eSymbolSize8Bit;
  1146.     if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModMem | imm_mask(code)))
  1147.     {
  1148.       append_word((code & 0177700) | adr_vals.mode);
  1149.       append_adr_vals(&adr_vals);
  1150.     }
  1151.   }
  1152. }
  1153.  
  1154. /*!------------------------------------------------------------------------
  1155.  * \fn     decode_two_arg(Word code)
  1156.  * \brief  handle instructions with two generic args
  1157.  * \param  code machine code
  1158.  * ------------------------------------------------------------------------ */
  1159.  
  1160. static void decode_two_arg(Word code)
  1161. {
  1162.   if (ChkArgCnt(2, 2))
  1163.   {
  1164.     adr_vals_t src_adr_vals, dest_adr_vals;
  1165.  
  1166.     op_size = (code & CODE_FLAG_16BIT) ? eSymbolSize16Bit : eSymbolSize8Bit;
  1167.     if (decode_adr(&ArgStr[1], &src_adr_vals, EProgCounter() + 2, MModReg | MModMem | MModImm)
  1168.      && decode_adr(&ArgStr[2], &dest_adr_vals, EProgCounter() + 2 + src_adr_vals.count, MModReg | MModMem | imm_mask(code)))
  1169.     {
  1170.       append_word((code & 0170000) | (src_adr_vals.mode << 6) | dest_adr_vals.mode);
  1171.       append_adr_vals(&src_adr_vals);
  1172.       append_adr_vals(&dest_adr_vals);
  1173.     }
  1174.   }
  1175. }
  1176.  
  1177. /*!------------------------------------------------------------------------
  1178.  * \fn     decode_eis(Word code)
  1179.  * \brief  handle EIS instructions
  1180.  * \param  code machine code
  1181.  * ------------------------------------------------------------------------ */
  1182.  
  1183. static void decode_eis(Word code)
  1184. {
  1185.   if (ChkArgCnt(2, 2) && check_cpu_ext(e_ext_eis))
  1186.   {
  1187.     adr_vals_t src_adr_vals, dest_adr_vals;
  1188.  
  1189.     op_size = eSymbolSize16Bit;
  1190.     if (decode_adr(&ArgStr[1], &src_adr_vals, EProgCounter() + 2, MModReg | MModMem | MModImm)
  1191.      && decode_adr(&ArgStr[2], &dest_adr_vals, EProgCounter() + 2 + src_adr_vals.count, MModReg))
  1192.     {
  1193.       append_word((code & 0177000) | ((dest_adr_vals.mode & 7) << 6) | src_adr_vals.mode);
  1194.       append_adr_vals(&src_adr_vals);
  1195.     }
  1196.   }
  1197. }
  1198.  
  1199. /*!------------------------------------------------------------------------
  1200.  * \fn     decode_reg_gen(Word code)
  1201.  * \brief  handle instructions with one register and one general argument
  1202.  * \param  code machine code
  1203.  * ------------------------------------------------------------------------ */
  1204.  
  1205. static void decode_reg_gen(Word code)
  1206. {
  1207.   if (ChkArgCnt(2, 2))
  1208.   {
  1209.     adr_vals_t reg_adr_vals, dest_adr_vals;
  1210.  
  1211.     op_size = eSymbolSize16Bit;
  1212.     if (decode_adr(&ArgStr[1], &reg_adr_vals, EProgCounter() + 2, MModReg)
  1213.      && decode_adr(&ArgStr[2], &dest_adr_vals, EProgCounter() + 2 + reg_adr_vals.count, MModReg | MModMem | MModImm))
  1214.     {
  1215.       append_word((code & 0177000) | ((reg_adr_vals.mode & 7) << 6) | dest_adr_vals.mode);
  1216.       append_adr_vals(&dest_adr_vals);
  1217.     }
  1218.   }
  1219. }
  1220.  
  1221. /*!------------------------------------------------------------------------
  1222.  * \fn     decode_xor(Word code)
  1223.  * \brief  handle XOR instruction
  1224.  * \param  code machine code
  1225.  * ------------------------------------------------------------------------ */
  1226.  
  1227. static void decode_xor(Word code)
  1228. {
  1229.   if (ChkArgCnt(2, 2) && check_cpu_ext(e_ext_xor))
  1230.   {
  1231.     adr_vals_t src_adr_vals, dest_adr_vals;
  1232.  
  1233.     op_size = eSymbolSize16Bit;
  1234.     if (decode_adr(&ArgStr[1], &src_adr_vals, EProgCounter() + 2, MModReg)
  1235.      && decode_adr(&ArgStr[2], &dest_adr_vals, EProgCounter() + 2 + src_adr_vals.count, MModReg | MModMem | imm_mask(code)))
  1236.     {
  1237.       append_word((code & 0177000) | ((src_adr_vals.mode & 7) << 6) | dest_adr_vals.mode);
  1238.       append_adr_vals(&dest_adr_vals);
  1239.     }
  1240.   }
  1241. }
  1242.  
  1243. /*!------------------------------------------------------------------------
  1244.  * \fn     decode_fis(Word code)
  1245.  * \brief  handle FIS instructions
  1246.  * \param  code machine code
  1247.  * ------------------------------------------------------------------------ */
  1248.  
  1249. static void decode_fis(Word code)
  1250. {
  1251.   adr_vals_t reg_adr_vals;
  1252.  
  1253.   if (ChkArgCnt(1, 1)
  1254.    && check_cpu_ext(e_ext_fis)
  1255.    && decode_adr(&ArgStr[1], &reg_adr_vals, EProgCounter() + 2, MModReg))
  1256.     append_word((code & 0177770) | (reg_adr_vals.mode & 7));
  1257. }
  1258.  
  1259. /*!------------------------------------------------------------------------
  1260.  * \fn     decode_branch(Word code)
  1261.  * \brief  handle branch instructions
  1262.  * \param  code machine code
  1263.  * ------------------------------------------------------------------------ */
  1264.  
  1265. static void decode_branch(Word code)
  1266. {
  1267.   if (ChkArgCnt(1, 1))
  1268.   {
  1269.     tEvalResult eval_result;
  1270.     LongInt dist = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &eval_result) - (EProgCounter() + 2);
  1271.  
  1272.     if (eval_result.OK)
  1273.     {
  1274.       if ((dist & 1) && !mFirstPassUnknownOrQuestionable(eval_result.Flags)) WrStrErrorPos(ErrNum_DistIsOdd, &ArgStr[1]);
  1275.       else
  1276.       {
  1277.         dist /= 2;
  1278.         if (!RangeCheck(dist, SInt8) && !mFirstPassUnknownOrQuestionable(eval_result.Flags)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
  1279.         else
  1280.           append_word((code & 0xff00) | (dist & 0x00ff));
  1281.       }
  1282.     }
  1283.   }
  1284. }
  1285.  
  1286. /*!------------------------------------------------------------------------
  1287.  * \fn     decode_sob(Word code)
  1288.  * \brief  handle SOB instruction
  1289.  * \param  code machine code
  1290.  * ------------------------------------------------------------------------ */
  1291.  
  1292. static void decode_sob(Word code)
  1293. {
  1294.   adr_vals_t reg_adr_vals;
  1295.  
  1296.   if (ChkArgCnt(2, 2)
  1297.    && check_cpu_ext(e_ext_sob_sxt)
  1298.    && decode_adr(&ArgStr[1], &reg_adr_vals, EProgCounter() + 2, MModReg))
  1299.   {
  1300.     tEvalResult eval_result;
  1301.     LongInt dist = EvalStrIntExpressionWithResult(&ArgStr[2], UInt16, &eval_result) - (EProgCounter() + 2);
  1302.  
  1303.     if ((dist & 1) && !mFirstPassUnknownOrQuestionable(eval_result.Flags)) WrStrErrorPos(ErrNum_DistIsOdd, &ArgStr[1]);
  1304.     else
  1305.     {
  1306.       dist /= 2;
  1307.       if (((dist > 0) || (dist < -63)) && !mFirstPassUnknownOrQuestionable(eval_result.Flags)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
  1308.       else
  1309.         append_word((code & 0177000) | ((reg_adr_vals.mode & 7) << 6) | ((-dist) & 077));
  1310.     }
  1311.   }
  1312. }
  1313.  
  1314. /*!------------------------------------------------------------------------
  1315.  * \fn     decode_jmp(Word code)
  1316.  * \brief  handle JMP instruction
  1317.  * \param  code machine code
  1318.  * ------------------------------------------------------------------------ */
  1319.  
  1320. static void decode_jmp(Word code)
  1321. {
  1322.   if (ChkArgCnt(1, 1))
  1323.   {
  1324.     adr_vals_t adr_vals;
  1325.  
  1326.     op_size = eSymbolSize16Bit;
  1327.     if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModMem | MModImm))
  1328.     {
  1329.       append_word((code & 0177700) | adr_vals.mode);
  1330.       append_adr_vals(&adr_vals);
  1331.     }
  1332.   }
  1333. }
  1334.  
  1335. /*!------------------------------------------------------------------------
  1336.  * \fn     decode_jsr_core(Word code, Word reg)
  1337.  * \brief  JSR instruction common core
  1338.  * \param  code machine code
  1339.  * \param  reg register operand
  1340.  * ------------------------------------------------------------------------ */
  1341.  
  1342. static void decode_jsr_core(Word code, Word reg)
  1343. {
  1344.   adr_vals_t addr_adr_vals;
  1345.  
  1346.   op_size = eSymbolSize16Bit;
  1347.   if (decode_adr(&ArgStr[ArgCnt], &addr_adr_vals, EProgCounter() + 2, (is_wd16() ? 0 : MModReg) | MModMem | MModImm))
  1348.   {
  1349.     append_word((code & 0177000) | ((reg & 7) << 6) | addr_adr_vals.mode);
  1350.     append_adr_vals(&addr_adr_vals);
  1351.   }
  1352. }
  1353.  
  1354. /*!------------------------------------------------------------------------
  1355.  * \fn     decode_jsr(Word code)
  1356.  * \brief  handle JSR instruction
  1357.  * \param  code machine code
  1358.  * ------------------------------------------------------------------------ */
  1359.  
  1360. static void decode_jsr(Word code)
  1361. {
  1362.   if (ChkArgCnt(2, 2))
  1363.   {
  1364.     adr_vals_t reg_adr_vals;
  1365.  
  1366.     op_size = eSymbolSize16Bit;
  1367.     if (decode_adr(&ArgStr[1], &reg_adr_vals, EProgCounter() + 2, MModReg))
  1368.       decode_jsr_core(code, reg_adr_vals.mode & 7);
  1369.   }
  1370. }
  1371.  
  1372. /*!------------------------------------------------------------------------
  1373.  * \fn     decode_call(Word code)
  1374.  * \brief  handle CALL instruction
  1375.  * \param  code machine code
  1376.  * ------------------------------------------------------------------------ */
  1377.  
  1378. static void decode_call(Word code)
  1379. {
  1380.   if (ChkArgCnt(1, 1))
  1381.     decode_jsr_core(code, REG_PC);
  1382. }
  1383.  
  1384. /*!------------------------------------------------------------------------
  1385.  * \fn     decode_rts(Word code)
  1386.  * \brief  handle RTS instruction
  1387.  * \param  code machine code
  1388.  * ------------------------------------------------------------------------ */
  1389.  
  1390. static void decode_rts(Word code)
  1391. {
  1392.   if (ChkArgCnt(1, 1))
  1393.   {
  1394.     adr_vals_t reg_adr_vals;
  1395.  
  1396.     op_size = eSymbolSize16Bit;
  1397.     if (decode_adr(&ArgStr[1], &reg_adr_vals, EProgCounter() + 2, MModReg))
  1398.       append_word((code & 0177770) | (reg_adr_vals.mode & 7));
  1399.   }
  1400. }
  1401.  
  1402. /*!------------------------------------------------------------------------
  1403.  * \fn     decode_imm6(Word code)
  1404.  * \brief  handle instructions with 6 bit numeric argument
  1405.  * \param  code machine code
  1406.  * ------------------------------------------------------------------------ */
  1407.  
  1408. static void decode_imm6(Word code)
  1409. {
  1410.   if (ChkArgCnt(1, 1))
  1411.   {
  1412.     Boolean ok;
  1413.     Word num = EvalStrIntExpression(&ArgStr[1], UInt6, &ok);
  1414.  
  1415.     if (ok)
  1416.       append_word(code | (num & 63));
  1417.   }
  1418. }
  1419.  
  1420. /*!------------------------------------------------------------------------
  1421.  * \fn     decode_mark(Word code)
  1422.  * \brief  handle MARK instruction
  1423.  * \param  code machine code
  1424.  * ------------------------------------------------------------------------ */
  1425.  
  1426. static void decode_mark(Word code)
  1427. {
  1428.   if (check_cpu_ext(e_ext_mark))
  1429.     decode_imm6(code);
  1430. }
  1431.  
  1432. /*!------------------------------------------------------------------------
  1433.  * \fn     decode_imm4p1_reg(Word code)
  1434.  * \brief  handle instructions with 4 bit immediate and register argument
  1435.  * \param  code machine code
  1436.  * ------------------------------------------------------------------------ */
  1437.  
  1438. static void decode_imm4p1_reg(Word code)
  1439. {
  1440.   adr_vals_t reg_adr_vals;
  1441.  
  1442.   if (ChkArgCnt(2, 2)
  1443.    && decode_adr(&ArgStr[2], &reg_adr_vals, EProgCounter() + 2, MModReg))
  1444.   {
  1445.     tEvalResult eval_result;
  1446.     Word imm_val = EvalStrIntExpressionWithResult(&ArgStr[1], UInt5, &eval_result);
  1447.  
  1448.     if (eval_result.OK)
  1449.     {
  1450.       if (mFirstPassUnknownOrQuestionable(eval_result.Flags))
  1451.         imm_val = 1;
  1452.       if (ChkRange(imm_val, 1, 16))
  1453.         append_word(code | ((reg_adr_vals.mode & 7) << 6) | ((imm_val - 1) & 15));
  1454.     }
  1455.   }
  1456. }
  1457.  
  1458. /*!------------------------------------------------------------------------
  1459.  * \fn     decode_spl(Word code)
  1460.  * \brief  handle SPL instruction
  1461.  * \param  code machine code
  1462.  * ------------------------------------------------------------------------ */
  1463.  
  1464. static void decode_spl(Word code)
  1465. {
  1466.   if (ChkArgCnt(1, 1) && check_cpu_ext(e_ext_spl))
  1467.   {
  1468.     Boolean ok;
  1469.     Word num = EvalStrIntExpression(&ArgStr[1], UInt3, &ok);
  1470.  
  1471.     if (ok)
  1472.       append_word(code | (num & 7));
  1473.   }
  1474. }
  1475.  
  1476. /*!------------------------------------------------------------------------
  1477.  * \fn     decode_trap(Word code)
  1478.  * \brief  handle trap instructions
  1479.  * \param  code machine code
  1480.  * ------------------------------------------------------------------------ */
  1481.  
  1482. static void decode_trap(Word code)
  1483. {
  1484.   if (ChkArgCnt(0, 1))
  1485.   {
  1486.     Boolean ok = True;
  1487.     Word num = (ArgCnt >= 1) ? EvalStrIntExpression(&ArgStr[1], UInt8, &ok) : 0;
  1488.  
  1489.     if (ok)
  1490.       append_word(code | (num & 255));
  1491.   }
  1492. }
  1493.  
  1494. /*!------------------------------------------------------------------------
  1495.  * \fn     decode_flags(Word code)
  1496.  * \brief  handle generic flag set/clear instructions
  1497.  * \param  code machine code
  1498.  * ------------------------------------------------------------------------ */
  1499.  
  1500. static void decode_flags(Word code)
  1501. {
  1502.   if (ChkArgCnt(1, 1))
  1503.   {
  1504.     Boolean ok = True;
  1505.     Word num = EvalStrIntExpression(&ArgStr[1], UInt4, &ok);
  1506.  
  1507.     if (ok)
  1508.       append_word(code | (num & 15));
  1509.   }
  1510. }
  1511.  
  1512. /*!------------------------------------------------------------------------
  1513.  * \fn     decode_lcc(Word code)
  1514.  * \brief  handle LCC instruction (WD16)
  1515.  * \param  code machine code
  1516.  * ------------------------------------------------------------------------ */
  1517.  
  1518. static void decode_lcc(Word code)
  1519. {
  1520.   if (ChkArgCnt(1, 1))
  1521.   {
  1522.     Boolean ok;
  1523.     Word num = EvalStrIntExpression(&ArgStr[1], UInt4, &ok);
  1524.  
  1525.     if (ok)
  1526.       append_word(code | (num & 15));
  1527.   }
  1528. }
  1529.  
  1530. /*!------------------------------------------------------------------------
  1531.  * \fn     decode_format11(Word code)
  1532.  * \brief  handle format 11 instructions
  1533.  * \param  code machine code
  1534.  * ------------------------------------------------------------------------ */
  1535.  
  1536. static Boolean decode_adr_01(tStrComp *p_arg, adr_vals_t *p_vals)
  1537. {
  1538.   if (!decode_adr(p_arg, p_vals, EProgCounter() + 2, MModReg | MModMem))
  1539.     return False;
  1540.  
  1541.   switch (p_vals->mode & 070)
  1542.   {
  1543.     case 010:
  1544.       p_vals->mode = (p_vals->mode & 007) | 000;
  1545.       break;
  1546.     case 070:
  1547.       if (p_vals->vals[0] == 0)
  1548.       {
  1549.         p_vals->count = 0;
  1550.         p_vals->mode = (p_vals->mode & 007) | 010;
  1551.         break;
  1552.       }
  1553.       /* else fall-through */
  1554.     default:
  1555.       WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  1556.       reset_adr_vals(p_vals);
  1557.       return False;
  1558.   }
  1559.   return True;
  1560. }
  1561.  
  1562. static void decode_format11(Word code)
  1563. {
  1564.   adr_vals_t src_adr_vals, dest_adr_vals;
  1565.  
  1566.   if (ChkArgCnt(2, 2)
  1567.    && decode_adr_01(&ArgStr[1], &src_adr_vals)
  1568.    && decode_adr_01(&ArgStr[2], &dest_adr_vals))
  1569.     append_word(code | ((src_adr_vals.mode & 15) << 4) | (dest_adr_vals.mode& 15));
  1570. }
  1571.  
  1572.  
  1573. /*!------------------------------------------------------------------------
  1574.  * \fn     decode_pseudo(void)
  1575.  * \brief  handle pseudo instructions
  1576.  * \return True if handled
  1577.  * ------------------------------------------------------------------------ */
  1578.  
  1579. static Boolean decode_pseudo(void)
  1580. {
  1581.   if (Memo("REG"))
  1582.   {
  1583.     if (LabPart.str.p_str[0])
  1584.       CodeREG(0);
  1585.     else if (ChkArgCnt(1, 1))
  1586.     {
  1587.       Boolean IsON;
  1588.  
  1589.       if (CheckONOFFArg(&ArgStr[1], &IsON))
  1590.         SetFlag(&default_regsyms, default_regsyms_name, IsON);
  1591.     }
  1592.     return True;
  1593.   }
  1594.  
  1595.   if (Memo("BYTE"))
  1596.   {
  1597.     DecodeIntelDB(eIntPseudoFlag_DECFormat | eIntPseudoFlag_AllowString);
  1598.     return True;
  1599.   }
  1600.  
  1601.   if (Memo("WORD"))
  1602.   {
  1603.     DecodeIntelDW(eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString | eIntPseudoFlag_DECFormat);
  1604.     return True;
  1605.   }
  1606.  
  1607.   if (is_wd16())
  1608.   {
  1609.     if (Memo("FLT3"))
  1610.     {
  1611.       DecodeIntelDM(eIntPseudoFlag_AllowFloat | eIntPseudoFlag_DECFormat);
  1612.       return True;
  1613.     }
  1614.   }
  1615.   {
  1616.     if (Memo("FLT2"))
  1617.     {
  1618.       DecodeIntelDD(eIntPseudoFlag_AllowFloat | eIntPseudoFlag_DECFormat);
  1619.       return True;
  1620.     }
  1621.  
  1622.     if (Memo("FLT4"))
  1623.     {
  1624.       DecodeIntelDQ(eIntPseudoFlag_AllowFloat | eIntPseudoFlag_DECFormat);
  1625.       return True;
  1626.     }
  1627.   }
  1628.  
  1629.   if (Memo("PRWINS"))
  1630.   {
  1631.     cpu_2_phys_area_dump(SegCode, stdout);
  1632.     return True;
  1633.   }
  1634.  
  1635.   return False;
  1636. }
  1637.  
  1638. /*--------------------------------------------------------------------------*/
  1639. /* Memory Management */
  1640.  
  1641. /*!------------------------------------------------------------------------
  1642.  * \fn     update_apr(void)
  1643.  * \brief  compute the CPU -> physical mapping from the current APR values
  1644.  * ------------------------------------------------------------------------ */
  1645.  
  1646. static void update_apr(void)
  1647. {
  1648.   int z;
  1649.   LargeWord base, size;
  1650.   Word acf;
  1651.  
  1652.   cpu_2_phys_area_clear(SegCode);
  1653.   for (z = 0, base = 0; z < APR_COUNT; z++, base += 0x2000)
  1654.   {
  1655.     /* page at least read only? */
  1656.  
  1657.     acf = reg_pdr[z] & 7;
  1658.     if ((acf == 00) || (acf == 03) || (acf == 07))
  1659.       continue;
  1660.  
  1661.     /* extract size field */
  1662.  
  1663.     size = (reg_pdr[z] >> 8) & 0xff;
  1664.  
  1665.     /* expand downward -> size field is 2s complement of number of blocks */
  1666.  
  1667.     if (reg_pdr[z] & 0x08)
  1668.     {
  1669.       size = ((size ^ 0xff) + 1) << 6;
  1670.       cpu_2_phys_area_add(SegCode, base + 0x2000 - size, (reg_par[z] << 6) + 0x2000 - size, size);
  1671.     }
  1672.  
  1673.     /* expand upward -> size field is highest block number */
  1674.  
  1675.     else
  1676.     {
  1677.       size = ((size & 0x7f) + 1) << 6;
  1678.       cpu_2_phys_area_add(SegCode, base, reg_par[z] << 6, size);
  1679.     }
  1680.   }
  1681.   cpu_2_phys_area_set_cpu_end(SegCode, 0xffff);
  1682. }
  1683.  
  1684. /*--------------------------------------------------------------------------*/
  1685. /* Instruction Lookup Table */
  1686.  
  1687. /*!------------------------------------------------------------------------
  1688.  * \fn     init_branches(void)
  1689.  * \brief  add branch instructions to lookup table (same on PDP-11 and WD16)
  1690.  * ------------------------------------------------------------------------ */
  1691.  
  1692. static void init_branches(void)
  1693. {
  1694.   AddInstTable(InstTable, "BCC" , 0103000, decode_branch);
  1695.   AddInstTable(InstTable, "BCS" , 0103400, decode_branch);
  1696.   AddInstTable(InstTable, "BEQ" , 0001400, decode_branch);
  1697.   AddInstTable(InstTable, "BGE" , 0002000, decode_branch);
  1698.   AddInstTable(InstTable, "BGT" , 0003000, decode_branch);
  1699.   AddInstTable(InstTable, "BHI" , 0101000, decode_branch);
  1700.   AddInstTable(InstTable, "BHIS", 0103000, decode_branch);
  1701.   AddInstTable(InstTable, "BLE" , 0003400, decode_branch);
  1702.   AddInstTable(InstTable, "BLO" , 0103400, decode_branch);
  1703.   AddInstTable(InstTable, "BLOS", 0101400, decode_branch);
  1704.   AddInstTable(InstTable, "BLT" , 0002400, decode_branch);
  1705.   AddInstTable(InstTable, "BMI" , 0100400, decode_branch);
  1706.   AddInstTable(InstTable, "BNE" , 0001000, decode_branch);
  1707.   AddInstTable(InstTable, "BPL" , 0100000, decode_branch);
  1708.   AddInstTable(InstTable, "BR"  , 0000400, decode_branch);
  1709.   AddInstTable(InstTable, "BVC" , 0102000, decode_branch);
  1710.   AddInstTable(InstTable, "BVS" , 0102400, decode_branch);
  1711. }
  1712.  
  1713. /*!------------------------------------------------------------------------
  1714.  * \fn     init_fields_pdp11(void)
  1715.  * \brief  create lookup table - PDP-11 encoding
  1716.  * ------------------------------------------------------------------------ */
  1717.  
  1718. static void add_one_arg(const char *p_name, Word code)
  1719. {
  1720.   char name[10];
  1721.  
  1722.   AddInstTable(InstTable, p_name, code | CODE_FLAG_16BIT, decode_one_arg);
  1723.   as_snprintf(name, sizeof(name), "%sB", p_name);
  1724.   AddInstTable(InstTable, name, 0100000 | code, decode_one_arg);
  1725. }
  1726.  
  1727. static void add_two_arg(const char *p_name, Word code)
  1728. {
  1729.   char name[10];
  1730.  
  1731.   AddInstTable(InstTable, p_name, code | CODE_FLAG_16BIT, decode_two_arg);
  1732.   as_snprintf(name, sizeof(name), "%sB", p_name);
  1733.   AddInstTable(InstTable, name, 0100000 | code, decode_two_arg);
  1734. }
  1735.  
  1736. static void add_fp11(const char *p_name, Word code, InstProc proc)
  1737. {
  1738.   char name[10];
  1739.  
  1740.   as_snprintf(name, sizeof(name), "%sF", p_name);
  1741.   AddInstTable(InstTable, name, code, proc);
  1742.   as_snprintf(name, sizeof(name), "%sD", p_name);
  1743.   AddInstTable(InstTable, name, code | CODE_FLAG_F64BIT, proc);
  1744. }
  1745.  
  1746. static void add_cis(const char *p_name, Word code, InstProc inline_proc)
  1747. {
  1748.   char name[10];
  1749.  
  1750.   AddInstTable(InstTable, p_name, code, decode_cis_0);
  1751.   as_snprintf(name, sizeof(name), "%sI", p_name);
  1752.   AddInstTable(InstTable, name, code | 0000100, inline_proc);
  1753. }
  1754.  
  1755. static void init_fields_pdp11(void)
  1756. {
  1757.   InstTable = CreateInstTable(201);
  1758.   SetDynamicInstTable(InstTable);
  1759.  
  1760.   AddInstTable(InstTable, "BPT",   000003, decode_fixed);
  1761.   AddInstTable(InstTable, "CCC",   000257, decode_fixed);
  1762.   AddInstTable(InstTable, "CLC",   000241, decode_fixed);
  1763.   AddInstTable(InstTable, "CLN",   000250, decode_fixed);
  1764.   AddInstTable(InstTable, "CLV",   000242, decode_fixed);
  1765.   AddInstTable(InstTable, "CLZ",   000244, decode_fixed);
  1766.   AddInstTable(InstTable, "HALT",  000000, decode_fixed_sup);
  1767.   AddInstTable(InstTable, "IOT",   000004, decode_fixed);
  1768.   AddInstTable(InstTable, "MFPT",  000007, decode_mfpt);
  1769.   AddInstTable(InstTable, "NOP",   NOPCode, decode_fixed);
  1770.   AddInstTable(InstTable, "RESET", 000005, decode_fixed_sup);
  1771.   AddInstTable(InstTable, "RTI",   000002, decode_fixed);
  1772.   AddInstTable(InstTable, "RTT",   000006, decode_rtt);
  1773.   AddInstTable(InstTable, "SCC",   000277, decode_fixed);
  1774.   AddInstTable(InstTable, "SEC",   000261, decode_fixed);
  1775.   AddInstTable(InstTable, "SEN",   000270, decode_fixed);
  1776.   AddInstTable(InstTable, "SEV",   000262, decode_fixed);
  1777.   AddInstTable(InstTable, "SEZ",   000264, decode_fixed);
  1778.   AddInstTable(InstTable, "WAIT",  000001, decode_fixed);
  1779.  
  1780.   add_one_arg("ADC", 005500);
  1781.   add_one_arg("ASL", 006300);
  1782.   add_one_arg("ASR", 006200);
  1783.   add_one_arg("CLR", 005000);
  1784.   add_one_arg("COM", 005100);
  1785.   add_one_arg("NEG", 005400);
  1786.   add_one_arg("DEC", 005300);
  1787.   add_one_arg("INC", 005200);
  1788.   add_one_arg("ROL", 006100);
  1789.   add_one_arg("ROR", 006000);
  1790.   add_one_arg("SBC", 005600);
  1791.   AddInstTable(InstTable, "SWAB", 000300, decode_one_arg);
  1792.   AddInstTable(InstTable, "SXT", 006700, decode_sxt);
  1793.   add_one_arg("TST", 005700);
  1794.   AddInstTable(InstTable, "TSTSET", 0007200, decode_tstset);
  1795.   AddInstTable(InstTable, "WRTLCK", 0007300, decode_wrtlck);
  1796.   AddInstTable(InstTable, "CSM"   , 0007000 | CODE_FLAG_16BIT | CODE_FLAG_GEN_IMM, decode_csm);
  1797.   AddInstTable(InstTable, "MFPD"  , 0006500 | CODE_FLAG_16BIT | CODE_FLAG_GEN_IMM, decode_mfp_mtp);
  1798.   AddInstTable(InstTable, "MFPI"  , 0106500 | CODE_FLAG_16BIT | CODE_FLAG_GEN_IMM, decode_mfp_mtp);
  1799.   AddInstTable(InstTable, "MFPS"  , 0106700 , decode_mfps_mtps);
  1800.   AddInstTable(InstTable, "MTPD"  , 0006600 | CODE_FLAG_16BIT, decode_mfp_mtp);
  1801.   AddInstTable(InstTable, "MTPI"  , 0106600 | CODE_FLAG_16BIT, decode_mfp_mtp);
  1802.   AddInstTable(InstTable, "MTPS"  , 0106400 | CODE_FLAG_GEN_IMM, decode_mfps_mtps);
  1803.  
  1804.   AddInstTable(InstTable, "FADD"  , 0075000, decode_fis);
  1805.   AddInstTable(InstTable, "FSUB"  , 0075010, decode_fis);
  1806.   AddInstTable(InstTable, "FMUL"  , 0075020, decode_fis);
  1807.   AddInstTable(InstTable, "FDIV"  , 0075030, decode_fis);
  1808.  
  1809.   add_fp11("ADD" , 0172000 | CODE_FLAG_GEN_IMM, decode_fp11_f1_f3);
  1810.   add_fp11("CMP" , 0173400 | CODE_FLAG_GEN_IMM, decode_fp11_f1_f3);
  1811.   add_fp11("DIV" , 0174400 | CODE_FLAG_GEN_IMM, decode_fp11_f1_f3);
  1812.   AddInstTable(InstTable, "LDCDF", 0177400 | CODE_FLAG_GEN_IMM | CODE_FLAG_F64BIT, decode_fp11_f1_f3);
  1813.   AddInstTable(InstTable, "LDCFD", 0177400 | CODE_FLAG_GEN_IMM, decode_fp11_f1_f3);
  1814.   AddInstTable(InstTable, "LDCIF", 0177000 | CODE_FLAG_GEN_IMM | CODE_FLAG_16BIT, decode_fp11_f1_f3);
  1815.   AddInstTable(InstTable, "LDCID", 0177000 | CODE_FLAG_GEN_IMM | CODE_FLAG_16BIT | CODE_FLAG_F64BIT, decode_fp11_f1_f3);
  1816.   AddInstTable(InstTable, "LDCLF", 0177000 | CODE_FLAG_GEN_IMM | CODE_FLAG_32BIT, decode_fp11_f1_f3);
  1817.   AddInstTable(InstTable, "LDCLD", 0177000 | CODE_FLAG_GEN_IMM | CODE_FLAG_32BIT | CODE_FLAG_F64BIT, decode_fp11_f1_f3);
  1818.   AddInstTable(InstTable, "STCFI", 0175400 | CODE_FLAG_ARGSWAP | CODE_FLAG_16BIT, decode_fp11_f1_f3);
  1819.   AddInstTable(InstTable, "STCDI", 0175400 | CODE_FLAG_ARGSWAP | CODE_FLAG_16BIT | CODE_FLAG_F64BIT, decode_fp11_f1_f3);
  1820.   AddInstTable(InstTable, "STCFL", 0175400 | CODE_FLAG_ARGSWAP | CODE_FLAG_32BIT, decode_fp11_f1_f3);
  1821.   AddInstTable(InstTable, "STCDL", 0175400 | CODE_FLAG_ARGSWAP | CODE_FLAG_32BIT | CODE_FLAG_F64BIT, decode_fp11_f1_f3);
  1822.   AddInstTable(InstTable, "LDEXP", 0176400 | CODE_FLAG_GEN_IMM | CODE_FLAG_16BIT, decode_fp11_f1_f3);
  1823.   AddInstTable(InstTable, "STEXP", 0175000 | CODE_FLAG_ARGSWAP | CODE_FLAG_16BIT, decode_fp11_f1_f3);
  1824.   add_fp11("LD"  , 0172400 | CODE_FLAG_GEN_IMM, decode_fp11_f1_f3);
  1825.   add_fp11("ST"  , 0174000 | CODE_FLAG_ARGSWAP, decode_fp11_f1_f3);
  1826.   add_fp11("MOD" , 0171400 | CODE_FLAG_GEN_IMM, decode_fp11_f1_f3);
  1827.   add_fp11("MUL" , 0171000 | CODE_FLAG_GEN_IMM, decode_fp11_f1_f3);
  1828.   add_fp11("SUB" , 0173000 | CODE_FLAG_GEN_IMM, decode_fp11_f1_f3);
  1829.  
  1830.   add_fp11("ABS" , 0170600, decode_fp11_f2);
  1831.   add_fp11("CLR" , 0170400, decode_fp11_f2);
  1832.   add_fp11("NEG" , 0170700, decode_fp11_f2);
  1833.   add_fp11("TST" , 0170500 | CODE_FLAG_GEN_IMM, decode_fp11_f2);
  1834.  
  1835.   AddInstTable(InstTable, "LDFPS", 0170100 | CODE_FLAG_16BIT | CODE_FLAG_GEN_IMM, decode_fp11_f4);
  1836.   AddInstTable(InstTable, "STFPS", 0170200 | CODE_FLAG_16BIT, decode_fp11_f4);
  1837.   AddInstTable(InstTable, "STST" , 0170300 | CODE_FLAG_32BIT, decode_fp11_f4);
  1838.  
  1839.   AddInstTable(InstTable, "CFCC", 0170000, decode_fp11_f5);
  1840.   AddInstTable(InstTable, "SETF", 0170001, decode_fp11_f5);
  1841.   AddInstTable(InstTable, "SETD", 0170011, decode_fp11_f5);
  1842.   AddInstTable(InstTable, "SETI", 0170002, decode_fp11_f5);
  1843.   AddInstTable(InstTable, "SETL", 0170012, decode_fp11_f5);
  1844.  
  1845.   add_two_arg("CMP", 0020000 | CODE_FLAG_GEN_IMM);
  1846.   add_two_arg("BIC", 0040000);
  1847.   add_two_arg("BIS", 0050000);
  1848.   add_two_arg("BIT", 0030000 | CODE_FLAG_GEN_IMM);
  1849.   add_two_arg("MOV", 0010000);
  1850.   AddInstTable(InstTable, "ADD", 0060000 | CODE_FLAG_16BIT, decode_two_arg);
  1851.   AddInstTable(InstTable, "SUB", 0160000 | CODE_FLAG_16BIT, decode_two_arg);
  1852.  
  1853.   AddInstTable(InstTable, "ASH" , 0072000, decode_eis);
  1854.   AddInstTable(InstTable, "ASHC", 0073000, decode_eis);
  1855.   AddInstTable(InstTable, "DIV" , 0071000, decode_eis);
  1856.   AddInstTable(InstTable, "MUL" , 0070000, decode_eis);
  1857.   AddInstTable(InstTable, "XOR" , 0074000, decode_xor);
  1858.  
  1859.   init_branches();
  1860.   AddInstTable(InstTable, "SOB" , 0077000, decode_sob);
  1861.  
  1862.   AddInstTable(InstTable, "JMP" , 000100, decode_jmp);
  1863.   AddInstTable(InstTable, "JSR" , 004000, decode_jsr);
  1864.   AddInstTable(InstTable, "CALL", 004000, decode_call);
  1865.   AddInstTable(InstTable, "RTS" , 000200, decode_rts);
  1866.   AddInstTable(InstTable, "MARK", 006400, decode_mark);
  1867.  
  1868.   AddInstTable(InstTable, "EMT"  , 0104000, decode_trap);
  1869.   AddInstTable(InstTable, "TRAP" , 0104400, decode_trap);
  1870.   AddInstTable(InstTable, "SPL"  , 0000230, decode_spl);
  1871.  
  1872.   AddInstTable(InstTable, "C" , 000240, decode_flags);
  1873.   AddInstTable(InstTable, "S" , 000260, decode_flags);
  1874.  
  1875.   add_cis("ADDN" , 0076050, decode_cis_3);
  1876.   add_cis("ADDP" , 0076070, decode_cis_3);
  1877.   add_cis("ASHN" , 0076056, decode_cis_2i);
  1878.   add_cis("ASHP" , 0076076, decode_cis_2i);
  1879.   add_cis("CMPC" , 0076044, decode_cis_2i);
  1880.   add_cis("CMPN" , 0076052, decode_cis_2);
  1881.   add_cis("CMPP" , 0076072, decode_cis_2);
  1882.   add_cis("CVTLN", 0076057, decode_cis_2);
  1883.   add_cis("CVTLP", 0076077, decode_cis_2);
  1884.   add_cis("CVTNL", 0076053, decode_cis_2);
  1885.   add_cis("CVTPL", 0076073, decode_cis_2);
  1886.   add_cis("CVTNP", 0076055, decode_cis_2);
  1887.   add_cis("CVTPN", 0076054, decode_cis_2);
  1888.   add_cis("DIVP" , 0076075, decode_cis_3);
  1889.   add_cis("LOCC" , 0076040, decode_cis_2i);
  1890.   AddInstTable(InstTable, "L2DR" , 0076020, decode_cis_ld);
  1891.   AddInstTable(InstTable, "L3DR" , 0076060, decode_cis_ld);
  1892.   add_cis("MATC" , 0076045, decode_cis_2);
  1893.   add_cis("MOVC" , 0076030, decode_cis_2i);
  1894.   add_cis("MOVRC", 0076031, decode_cis_2i);
  1895.   add_cis("MOVTC", 0076032, decode_cis_2i1);
  1896.   add_cis("MULP" , 0076074, decode_cis_3);
  1897.   add_cis("SCANC", 0076042, decode_cis_2);
  1898.   add_cis("SKPC" , 0076041, decode_cis_1i);
  1899.   add_cis("SPANC", 0076043, decode_cis_2);
  1900.   add_cis("SUBN" , 0076051, decode_cis_3);
  1901.   add_cis("SUBP" , 0076071, decode_cis_3);
  1902. }
  1903.  
  1904. /*!------------------------------------------------------------------------
  1905.  * \fn     init_fields_wd16(void)
  1906.  * \brief  create lookup table - WD16 encoding
  1907.  * ------------------------------------------------------------------------ */
  1908.  
  1909. static Boolean TrueFnc(void)
  1910. {
  1911.   return True;
  1912. }
  1913.  
  1914. static void init_fields_wd16(void)
  1915. {
  1916.   InstTable = CreateInstTable(201);
  1917.   SetDynamicInstTable(InstTable);
  1918.  
  1919.   AddInstTable(InstTable, "NOP"  , NOPCode, decode_fixed);
  1920.   AddInstTable(InstTable, "RESET", 0x0001 , decode_fixed);
  1921.   AddInstTable(InstTable, "IEN"  , 0x0002 , decode_fixed);
  1922.   AddInstTable(InstTable, "IDS"  , 0x0003 , decode_fixed);
  1923.   AddInstTable(InstTable, "HALT" , 0x0004 , decode_fixed);
  1924.   AddInstTable(InstTable, "XCT"  , 0x0005 , decode_fixed);
  1925.   AddInstTable(InstTable, "BPT"  , 0x0006 , decode_fixed);
  1926.   AddInstTable(InstTable, "WFI"  , 0x0007 , decode_fixed);
  1927.   AddInstTable(InstTable, "RSVC" , 0x0008 , decode_fixed);
  1928.   AddInstTable(InstTable, "RRTT" , 0x0009 , decode_fixed);
  1929.   AddInstTable(InstTable, "SAVE" , 0x000a , decode_fixed); SaveIsOccupiedFnc = TrueFnc;
  1930.   AddInstTable(InstTable, "SAVS" , 0x000b , decode_fixed);
  1931.   AddInstTable(InstTable, "REST" , 0x000c , decode_fixed);
  1932.   AddInstTable(InstTable, "RRTN" , 0x000d , decode_fixed);
  1933.   AddInstTable(InstTable, "RSTS" , 0x000e , decode_fixed);
  1934.   AddInstTable(InstTable, "RTT"  , 0x000f , decode_fixed);
  1935.  
  1936.   AddInstTable(InstTable, "IAK"  , 0x0010 , decode_one_reg);
  1937.   AddInstTable(InstTable, "RTN"  , 0x0018 , decode_one_reg);
  1938.   AddInstTable(InstTable, "MSKO" , 0x0020 , decode_one_reg);
  1939.   AddInstTable(InstTable, "PRTN" , 0x0028 , decode_one_reg);
  1940.  
  1941.   AddInstTable(InstTable, "LCC"  , 0x0030 , decode_lcc);
  1942.  
  1943.   AddInstTable(InstTable, "SVCA" , 0x0040 , decode_imm6);
  1944.   AddInstTable(InstTable, "SVCB" , 0x0080 , decode_imm6);
  1945.   AddInstTable(InstTable, "SVCC" , 0x00c0 , decode_imm6);
  1946.  
  1947.   AddInstTable(InstTable, "ADDI" , 0x0800 , decode_imm4p1_reg);
  1948.   AddInstTable(InstTable, "SUBI" , 0x0810 , decode_imm4p1_reg);
  1949.   AddInstTable(InstTable, "BICI" , 0x0820 , decode_imm4p1_reg);
  1950.   AddInstTable(InstTable, "MOVI" , 0x0830 , decode_imm4p1_reg);
  1951.   AddInstTable(InstTable, "SSRR" , 0x8800 , decode_imm4p1_reg);
  1952.   AddInstTable(InstTable, "SSLR" , 0x8810 , decode_imm4p1_reg);
  1953.   AddInstTable(InstTable, "SSRA" , 0x8820 , decode_imm4p1_reg);
  1954.   AddInstTable(InstTable, "SSLA" , 0x8830 , decode_imm4p1_reg);
  1955.   AddInstTable(InstTable, "SDRR" , 0x8e00 , decode_imm4p1_reg);
  1956.   AddInstTable(InstTable, "SDLR" , 0x8e10 , decode_imm4p1_reg);
  1957.   AddInstTable(InstTable, "SDRA" , 0x8e20 , decode_imm4p1_reg);
  1958.   AddInstTable(InstTable, "SDLA" , 0x8e30 , decode_imm4p1_reg);
  1959.  
  1960.   add_one_arg("ROR", 0x0a00);
  1961.   add_one_arg("ROL", 0x0a40);
  1962.   add_one_arg("TST", 0x0a80);
  1963.   add_one_arg("ASL", 0x0ac0);
  1964.   add_one_arg("SET", 0x0b00); SetIsOccupiedFnc = TrueFnc;
  1965.   add_one_arg("CLR", 0x0b40);
  1966.   add_one_arg("ASR", 0x0b80);
  1967.   add_one_arg("COM", 0x0c00);
  1968.   add_one_arg("NEG", 0x0c40);
  1969.   add_one_arg("INC", 0x0c80);
  1970.   add_one_arg("DEC", 0x0cc0);
  1971.   AddInstTable(InstTable, "SWAB" , 0x0bc0, decode_one_arg);
  1972.   AddInstTable(InstTable, "SWAD" , 0x8bc0, decode_one_arg);
  1973.   AddInstTable(InstTable, "IW2"  , 0x0d00, decode_one_arg);
  1974.   AddInstTable(InstTable, "SXT"  , 0x0d40, decode_one_arg);
  1975.   AddInstTable(InstTable, "TCALL", 0x0d80 | CODE_FLAG_GEN_IMM | CODE_FLAG_16BIT, decode_one_arg);
  1976.   AddInstTable(InstTable, "TJMP" , 0x0dc0 | CODE_FLAG_GEN_IMM | CODE_FLAG_16BIT, decode_one_arg);
  1977.   AddInstTable(InstTable, "LSTS" , 0x8d00 | CODE_FLAG_GEN_IMM | CODE_FLAG_16BIT, decode_one_arg);
  1978.   AddInstTable(InstTable, "SSTS" , 0x8d40, decode_one_arg);
  1979.   AddInstTable(InstTable, "ADC"  , 0x8d80, decode_one_arg);
  1980.   AddInstTable(InstTable, "SBC"  , 0x8dc0, decode_one_arg);
  1981.  
  1982.   AddInstTable(InstTable, "MBWU" , 0x0e00, decode_two_reg);
  1983.   AddInstTable(InstTable, "MBWD" , 0x0e40, decode_two_reg);
  1984.   AddInstTable(InstTable, "MBBU" , 0x0e80, decode_two_reg);
  1985.   AddInstTable(InstTable, "MBBD" , 0x0ec0, decode_two_reg);
  1986.   AddInstTable(InstTable, "MBWA" , 0x0f00, decode_two_reg);
  1987.   AddInstTable(InstTable, "MBBA" , 0x0f40, decode_two_reg);
  1988.   AddInstTable(InstTable, "MABW" , 0x0f80, decode_two_reg);
  1989.   AddInstTable(InstTable, "MABB" , 0x0fc0, decode_two_reg);
  1990.  
  1991.   AddInstTable(InstTable, "JSR" , 0x7000, decode_jsr);
  1992.   AddInstTable(InstTable, "CALL", 0x7000, decode_call);
  1993.   AddInstTable(InstTable, "LEA" , 0x7200, decode_jsr);
  1994.   AddInstTable(InstTable, "JMP" , 0x7200, decode_call);
  1995.   AddInstTable(InstTable, "ASH" , 0x7400, decode_reg_gen);
  1996.   AddInstTable(InstTable, "SOB" , 0x7600, decode_sob);
  1997.   AddInstTable(InstTable, "XCH" , 0x7800, decode_reg_gen);
  1998.   AddInstTable(InstTable, "ASHC", 0x7a00, decode_reg_gen);
  1999.   AddInstTable(InstTable, "MUL" , 0x7c00, decode_reg_gen);
  2000.   AddInstTable(InstTable, "DIV" , 0x7e00, decode_reg_gen);
  2001.  
  2002.   AddInstTable(InstTable, "ADD" , 0x1000 | CODE_FLAG_16BIT, decode_two_arg);
  2003.   AddInstTable(InstTable, "SUB" , 0x2000 | CODE_FLAG_16BIT, decode_two_arg);
  2004.   AddInstTable(InstTable, "AND" , 0x3000 | CODE_FLAG_16BIT, decode_two_arg);
  2005.   AddInstTable(InstTable, "BIC" , 0x4000 | CODE_FLAG_16BIT, decode_two_arg);
  2006.   AddInstTable(InstTable, "BIS" , 0x5000 | CODE_FLAG_16BIT, decode_two_arg);
  2007.   AddInstTable(InstTable, "XOR" , 0x6000 | CODE_FLAG_16BIT, decode_two_arg);
  2008.   AddInstTable(InstTable, "CMP" , 0x9000 | CODE_FLAG_GEN_IMM | CODE_FLAG_16BIT, decode_two_arg);
  2009.   AddInstTable(InstTable, "BIT" , 0xa000 | CODE_FLAG_GEN_IMM | CODE_FLAG_16BIT, decode_two_arg);
  2010.   AddInstTable(InstTable, "MOV" , 0xb000 | CODE_FLAG_16BIT, decode_two_arg);
  2011.   AddInstTable(InstTable, "CMPB", 0xc000 | CODE_FLAG_GEN_IMM, decode_two_arg);
  2012.   AddInstTable(InstTable, "MOVB", 0xd000, decode_two_arg);
  2013.   AddInstTable(InstTable, "BISB", 0xe000, decode_two_arg);
  2014.  
  2015.   AddInstTable(InstTable, "FADD", 0xf000, decode_format11);
  2016.   AddInstTable(InstTable, "FSUB", 0xf100, decode_format11);
  2017.   AddInstTable(InstTable, "FMUL", 0xf200, decode_format11);
  2018.   AddInstTable(InstTable, "FDIV", 0xf300, decode_format11);
  2019.   AddInstTable(InstTable, "FCMP", 0xf400, decode_format11);
  2020.  
  2021.   init_branches();
  2022. }
  2023.  
  2024. /*!------------------------------------------------------------------------
  2025.  * \fn     deinit_fields(void)
  2026.  * \brief  destroy/cleanup lookup table
  2027.  * ------------------------------------------------------------------------ */
  2028.  
  2029. static void deinit_fields(void)
  2030. {
  2031.   DestroyInstTable(InstTable);
  2032. }
  2033.  
  2034. /*--------------------------------------------------------------------------*/
  2035. /* Interface Functions */
  2036.  
  2037. /*!------------------------------------------------------------------------
  2038.  * \fn     intern_symbol_pdp11(char *pArg, TempResult *pResult)
  2039.  * \brief  handle built-in (register) symbols for PDP-11
  2040.  * \param  p_arg source argument
  2041.  * \param  p_result result buffer
  2042.  * ------------------------------------------------------------------------ */
  2043.  
  2044. static void intern_symbol_pdp11(char *p_arg, TempResult *p_result)
  2045. {
  2046.   Word reg_num;
  2047.  
  2048.   if (decode_reg_core(p_arg, &reg_num, &p_result->DataSize))
  2049.   {
  2050.     p_result->Typ = TempReg;
  2051.     p_result->Contents.RegDescr.Reg = reg_num;
  2052.     p_result->Contents.RegDescr.Dissect = dissect_reg_pdp11;
  2053.     p_result->Contents.RegDescr.compare = NULL;
  2054.   }
  2055. }
  2056.  
  2057. /*!------------------------------------------------------------------------
  2058.  * \fn     make_code_pdp11(void)
  2059.  * \brief  encode machine instruction
  2060.  * ------------------------------------------------------------------------ */
  2061.  
  2062. static void make_code_pdp11(void)
  2063. {
  2064.   CodeLen = 0; DontPrint = False;
  2065.   op_size = eSymbolSizeUnknown;
  2066.  
  2067.   /* to be ignored */
  2068.  
  2069.   if (Memo("")) return;
  2070.  
  2071.   /* Pseudo Instructions */
  2072.  
  2073.   if (decode_pseudo())
  2074.     return;
  2075.  
  2076.   /* machine instructions may not begin on odd addresses */
  2077.  
  2078.   if (Odd(EProgCounter()))
  2079.   {
  2080.     if (DoPadding)
  2081.       InsertPadding(1, False);
  2082.     else
  2083.       WrError(ErrNum_AddrNotAligned);
  2084.   }
  2085.  
  2086.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  2087.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  2088. }
  2089.  
  2090. /*!------------------------------------------------------------------------
  2091.  * \fn     is_def_pdp11(void)
  2092.  * \brief  check whether insn makes own use of label
  2093.  * \return True if yes
  2094.  * ------------------------------------------------------------------------ */
  2095.  
  2096. static Boolean is_def_pdp11(void)
  2097. {
  2098.   return Memo("REG");
  2099. }
  2100.  
  2101. /*!------------------------------------------------------------------------
  2102.  * \fn     initpass_pdp11(void)
  2103.  * \brief  pre-initialize APRs to 1:1 mapping
  2104.  * ------------------------------------------------------------------------ */
  2105.  
  2106. static void initpass_pdp11(void)
  2107. {
  2108.   /* if the PDP-11 target is never used, the memory never gets allocated: */
  2109.  
  2110.   if (reg_par)
  2111.   {
  2112.     int z;
  2113.  
  2114.     /* initialize APRs to 1:1 mapping */
  2115.  
  2116.     for (z = 0; z < APR_COUNT; z++)
  2117.     {
  2118.       reg_par[z] = z << 7;
  2119.       reg_pdr[z] = 0x7f05;
  2120.     }
  2121.   }
  2122.   ext_registered = 0;
  2123. }
  2124.  
  2125. /*!------------------------------------------------------------------------
  2126.  * \fn     switch_from_pdp11(void)
  2127.  * \brief  deinitialize as target
  2128.  * ------------------------------------------------------------------------ */
  2129.  
  2130. static void switch_from_pdp11(void)
  2131. {
  2132.   deinit_fields();
  2133.   p_curr_cpu_props = NULL;
  2134. }
  2135.  
  2136. /*!------------------------------------------------------------------------
  2137.  * \fn     switch_to_pdp11(void *p_user)
  2138.  * \brief  prepare to assemble code for this target
  2139.  * ------------------------------------------------------------------------ */
  2140.  
  2141. static void switch_to_pdp11(void *p_user)
  2142. {
  2143.   static char *p_assume_reg_names = NULL;
  2144.   static ASSUMERec *p_assumes = NULL;
  2145.   const TFamilyDescr *p_descr;
  2146.  
  2147.   p_curr_cpu_props = (const cpu_props_t*)p_user;
  2148.   p_descr = FindFamilyByName(is_wd16() ? "WD16" : "PDP-11");
  2149.   TurnWords = False;
  2150.   SetIntConstMode(eIntConstModeC);
  2151.  
  2152.   PCSymbol = "*";
  2153.   HeaderID = p_descr->Id;
  2154.   NOPCode = is_wd16() ? 0x0000 : 000240;
  2155.   DivideChars = ",";
  2156.  
  2157.   ValidSegs = 1 << SegCode;
  2158.   Grans[SegCode] = 1;
  2159.   ListGrans[SegCode] = 2;
  2160.   SegInits[SegCode] = 0;
  2161.   SegLimits[SegCode] = IntTypeDefs[p_curr_cpu_props->addr_space].Max;
  2162.  
  2163.   MakeCode = make_code_pdp11;
  2164.   IsDef = is_def_pdp11;
  2165.   SwitchFrom = switch_from_pdp11;
  2166.   InternSymbol = intern_symbol_pdp11;
  2167.   DissectReg = dissect_reg_pdp11;
  2168.   multi_char_le = True;
  2169.  
  2170.   if (!is_wd16())
  2171.     onoff_supmode_add();
  2172.   AddONOFF(DoPaddingName, &DoPadding, DoPaddingName, False);
  2173.   if (p_curr_cpu_props->opt_flags & e_cpu_flag_eis)
  2174.     onoff_ext_add(e_ext_eis, False);
  2175.   if (p_curr_cpu_props->opt_flags & e_cpu_flag_fis)
  2176.     onoff_ext_add(e_ext_fis, False);
  2177.   if (p_curr_cpu_props->opt_flags & e_cpu_flag_fp11)
  2178.     onoff_ext_add(e_ext_fp11, False);
  2179.   if (p_curr_cpu_props->opt_flags & e_cpu_flag_cis)
  2180.     onoff_ext_add(e_ext_cis, False);
  2181.   if (!ext_test_and_set(0x80))
  2182.     SetFlag(&default_regsyms, default_regsyms_name, True);
  2183.  
  2184.   /* create list of PDP-11 paging registers upon first use */
  2185.  
  2186.   if (!is_wd16())
  2187.   {
  2188.     if (!reg_par)
  2189.     {
  2190.       reg_par = (LongInt*)calloc(APR_COUNT, sizeof(*reg_par));
  2191.       reg_pdr = (LongInt*)calloc(APR_COUNT, sizeof(*reg_pdr));
  2192.       initpass_pdp11();
  2193.     }
  2194.     if (!p_assumes)
  2195.     {
  2196.       int apr_index, assume_index, l;
  2197.       char *p_reg_name;
  2198.  
  2199.       if (!p_assume_reg_names)
  2200.         p_assume_reg_names = (char*)malloc(ASSUME_COUNT * (4 + 1));
  2201.       p_assumes = (ASSUMERec*)calloc(ASSUME_COUNT, sizeof(*p_assumes));
  2202.  
  2203.       p_reg_name = p_assume_reg_names;
  2204.       for (apr_index = 0; apr_index < APR_COUNT; apr_index++)
  2205.       {
  2206.         l = as_snprintf(p_reg_name, 6, "PAR%c", apr_index + '0');
  2207.         p_assumes[apr_index * 2].Name = p_reg_name;
  2208.         p_assumes[apr_index * 2].Dest = &reg_par[apr_index];
  2209.         p_reg_name += l + 1;
  2210.         l = as_snprintf(p_reg_name, 6, "PDR%c", apr_index + '0');
  2211.         p_assumes[apr_index * 2 + 1].Name = p_reg_name;
  2212.         p_assumes[apr_index * 2 + 1].Dest = &reg_pdr[apr_index];
  2213.         p_reg_name += l + 1;
  2214.       }
  2215.       for (assume_index = 0; assume_index < ASSUME_COUNT; assume_index++)
  2216.       {
  2217.         p_assumes[assume_index].Min = 0x0000;
  2218.         p_assumes[assume_index].Max = 0xffff;
  2219.         p_assumes[assume_index].NothingVal = 0x0000;
  2220.         p_assumes[assume_index].pPostProc = update_apr;
  2221.       }
  2222.     }
  2223.     pASSUMERecs = p_assumes;
  2224.     ASSUMERecCnt = ASSUME_COUNT;
  2225.     update_apr();
  2226.   }
  2227.  
  2228.   if (is_wd16())
  2229.     init_fields_wd16();
  2230.   else
  2231.     init_fields_pdp11();
  2232. }
  2233.  
  2234. /*!------------------------------------------------------------------------
  2235.  * \fn     codepdp11_init(void)
  2236.  * \brief  register PDP-11 target
  2237.  * ------------------------------------------------------------------------ */
  2238.  
  2239. /* NOTE: the KEV-11C implements DIS, which is actually a subset of CIS, but
  2240.    since noone knows which subset, we just treat DIS as CIS: */
  2241.  
  2242. #define opt_cpu_flags_lsi11 (e_cpu_flag_eis | e_cpu_flag_fis | e_cpu_flag_cis)
  2243. #define cpu_flags_lsi11 (e_cpu_flag_sob_sxt | e_cpu_flag_xor | e_cpu_flag_rtt | e_cpu_flag_mark | e_cpu_flag_mfps_mtps)
  2244.  
  2245. #define opt_cpu_flags_f11 (e_cpu_flag_fp11)
  2246. #define cpu_flags_f11 (e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt | e_cpu_flag_xor | e_cpu_flag_mfpt | e_cpu_flag_eis | e_cpu_flag_mfp_mtp | e_cpu_flag_mfps_mtps)
  2247.  
  2248. #define opt_cpu_flags_t11 0
  2249. #define cpu_flags_t11 (e_cpu_flag_sob_sxt | e_cpu_flag_rtt | e_cpu_flag_mfps_mtps)
  2250.  
  2251. #define opt_cpu_flags_j11 0
  2252. #define cpu_flags_j11 (e_cpu_flag_eis | e_cpu_flag_fp11 | e_cpu_flag_sob_sxt | e_cpu_flag_xor | e_cpu_flag_rtt | e_cpu_flag_mark | e_cpu_flag_mfpt | e_cpu_flag_mfp_mtp | e_cpu_flag_mfps_mtps | e_cpu_flag_spl | e_cpu_flag_csm | e_cpu_flag_wrtlck | e_cpu_flag_tstset)
  2253.  
  2254. static const cpu_props_t cpu_props[] =
  2255. {
  2256.   {      "PDP-11/03" , UInt16, opt_cpu_flags_lsi11              , cpu_flags_lsi11 },
  2257.   {      "PDP-11/04" , UInt16, 0                                , e_cpu_flag_rtt },
  2258.   {      "PDP-11/05" , UInt16, 0                                , 0 }, /* OEM version of PDP-11/10 */
  2259.   {      "PDP-11/10" , UInt16, 0                                , 0 },
  2260.   {      "PDP-11/15" , UInt16, 0                                , 0 }, /* OEM version of PDP-11/20 */
  2261.   {      "PDP-11/20" , UInt16, 0                                , 0 },
  2262.   {      "PDP-11/23" , UInt22, opt_cpu_flags_f11                , cpu_flags_f11 },
  2263.   {      "PDP-11/24" , UInt22, opt_cpu_flags_f11                , cpu_flags_f11 },
  2264.   {      "PDP-11/34" , UInt18, e_cpu_flag_fp11                  ,                   e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt | e_cpu_flag_eis | e_cpu_flag_xor                   | e_cpu_flag_mfp_mtp | e_cpu_flag_mfps_mtps },
  2265.   {      "PDP-11/35" , UInt18, e_cpu_flag_eis | e_cpu_flag_fis  ,                   e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt                  | e_cpu_flag_xor                   | e_cpu_flag_mfp_mtp }, /* OEM version of PDP-11/40 */
  2266.   {      "PDP-11/40" , UInt18, e_cpu_flag_eis | e_cpu_flag_fis  ,                   e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt                  | e_cpu_flag_xor                   | e_cpu_flag_mfp_mtp },
  2267.   {      "PDP-11/44" , UInt22, e_cpu_flag_fp11 | e_cpu_flag_cis ,                   e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt | e_cpu_flag_eis | e_cpu_flag_xor | e_cpu_flag_mfpt | e_cpu_flag_mfp_mtp | e_cpu_flag_spl | e_cpu_flag_csm },
  2268.   {      "PDP-11/45" , UInt18, e_cpu_flag_fp11                  ,                   e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt | e_cpu_flag_eis | e_cpu_flag_xor                                        | e_cpu_flag_spl },
  2269.   {      "PDP-11/50" , UInt18, e_cpu_flag_fp11                  ,                   e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt | e_cpu_flag_eis | e_cpu_flag_xor                                        | e_cpu_flag_spl },
  2270.   { "MicroPDP-11/53" , UInt22, opt_cpu_flags_j11                , cpu_flags_j11 },
  2271.   {      "PDP-11/55" , UInt18, e_cpu_flag_fp11                  ,                   e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt | e_cpu_flag_eis | e_cpu_flag_xor                                        | e_cpu_flag_spl },
  2272.   {      "PDP-11/60" , UInt18, 0                                , e_cpu_flag_fp11 | e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt | e_cpu_flag_eis | e_cpu_flag_xor                   | e_cpu_flag_mfp_mtp },
  2273.   {      "PDP-11/70" , UInt22, e_cpu_flag_fp11                  ,                   e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt | e_cpu_flag_eis | e_cpu_flag_xor                   | e_cpu_flag_mfp_mtp | e_cpu_flag_spl },
  2274.   { "MicroPDP-11/73" , UInt22, opt_cpu_flags_j11                , cpu_flags_j11 },
  2275.   { "MicroPDP-11/83" , UInt22, opt_cpu_flags_j11                , cpu_flags_j11 },
  2276.   {      "PDP-11/84" , UInt22, opt_cpu_flags_j11                , cpu_flags_j11 },
  2277.   { "MicroPDP-11/93" , UInt22, opt_cpu_flags_j11                , cpu_flags_j11 },
  2278.   {      "PDP-11/94" , UInt22, opt_cpu_flags_j11                , cpu_flags_j11 },
  2279.   {           "T-11" , UInt16, opt_cpu_flags_t11                , cpu_flags_t11 },
  2280.  
  2281.   /* The WD16 is basically an LSI-11 with
  2282.      - different microcode,
  2283.      - different opcodes,
  2284.      - different floating point format
  2285.      but same architecture: */
  2286.  
  2287.   {           "WD16" , UInt16, 0                                , e_cpu_flag_wd16 | e_cpu_flag_sob_sxt },
  2288. };
  2289.  
  2290. void codepdp11_init(void)
  2291. {
  2292.   const cpu_props_t *p_prop;
  2293.  
  2294.   for (p_prop = cpu_props; p_prop < cpu_props + as_array_size(cpu_props); p_prop++)
  2295.     (void)AddCPUUserWithArgs(p_prop->name, switch_to_pdp11, (void*)p_prop, NULL, NULL);
  2296.  
  2297.   AddInitPassProc(initpass_pdp11);
  2298. }
  2299.