1 // license:BSD-3-Clause 2 // copyright-holders:Olivier Galibert 3 4 // NEC disassembler interface 5 6 #ifndef MAME_CPU_NEC_NECDASM_H 7 #define MAME_CPU_NEC_NECDASM_H 8 9 #pragma once 10 11 class nec_disassembler : public util::disasm_interface 12 { 13 public: 14 struct config { 15 public: 16 virtual ~config() = default; 17 virtual int get_mode() const = 0; 18 }; 19 20 nec_disassembler(config *conf, const u8 *decryption_table = nullptr); 21 virtual ~nec_disassembler() = default; 22 23 virtual u32 opcode_alignment() const override; 24 virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; 25 26 private: 27 enum 28 { 29 PARAM_REG8 = 1, /* 8-bit register */ 30 PARAM_REG16, /* 16-bit register */ 31 PARAM_REG2_8, /* 8-bit register */ 32 PARAM_REG2_16, /* 16-bit register */ 33 PARAM_RM8, /* 8-bit memory or register */ 34 PARAM_RM16, /* 16-bit memory or register */ 35 PARAM_RMPTR8, /* 8-bit memory or register */ 36 PARAM_RMPTR16, /* 16-bit memory or register */ 37 PARAM_I3, /* 3-bit immediate */ 38 PARAM_I4, /* 4-bit immediate */ 39 PARAM_I8, /* 8-bit signed immediate */ 40 PARAM_I16, /* 16-bit signed immediate */ 41 PARAM_UI8, /* 8-bit unsigned immediate */ 42 PARAM_IMM, /* 16-bit immediate */ 43 PARAM_ADDR, /* 16:16 address */ 44 PARAM_REL8, /* 8-bit PC-relative displacement */ 45 PARAM_REL16, /* 16-bit PC-relative displacement */ 46 PARAM_MEM_OFFS, /* 16-bit mem offset */ 47 PARAM_SREG, /* segment register */ 48 PARAM_SFREG, /* V25/V35 special function register */ 49 PARAM_1, /* used by shift/rotate instructions */ 50 PARAM_AL, 51 PARAM_CL, 52 PARAM_DL, 53 PARAM_BL, 54 PARAM_AH, 55 PARAM_CH, 56 PARAM_DH, 57 PARAM_BH, 58 PARAM_AW, 59 PARAM_CW, 60 PARAM_DW, 61 PARAM_BW, 62 PARAM_SP, 63 PARAM_BP, 64 PARAM_IX, 65 PARAM_IY 66 }; 67 68 enum 69 { 70 MODRM = 1, 71 GROUP, 72 FPU, 73 TWO_BYTE, 74 PREFIX, 75 SEG_PS, 76 SEG_DS0, 77 SEG_DS1, 78 SEG_SS 79 }; 80 81 struct NEC_I386_OPCODE { 82 char mnemonic[32]; 83 uint32_t flags; 84 uint32_t param1; 85 uint32_t param2; 86 uint32_t param3; 87 offs_t dasm_flags; 88 }; 89 90 struct NEC_GROUP_OP { 91 char mnemonic[32]; 92 const NEC_I386_OPCODE *opcode; 93 }; 94 95 static const NEC_I386_OPCODE necv_opcode_table1[256]; 96 static const NEC_I386_OPCODE necv_opcode_table2[256]; 97 static const NEC_I386_OPCODE immb_table[8]; 98 static const NEC_I386_OPCODE immw_table[8]; 99 static const NEC_I386_OPCODE immws_table[8]; 100 static const NEC_I386_OPCODE shiftbi_table[8]; 101 static const NEC_I386_OPCODE shiftwi_table[8]; 102 static const NEC_I386_OPCODE shiftb_table[8]; 103 static const NEC_I386_OPCODE shiftw_table[8]; 104 static const NEC_I386_OPCODE shiftbv_table[8]; 105 static const NEC_I386_OPCODE shiftwv_table[8]; 106 static const NEC_I386_OPCODE group1b_table[8]; 107 static const NEC_I386_OPCODE group1w_table[8]; 108 static const NEC_I386_OPCODE group2b_table[8]; 109 static const NEC_I386_OPCODE group2w_table[8]; 110 static const NEC_GROUP_OP group_op_table[]; 111 static const char *const nec_reg[8]; 112 static const char *const nec_reg8[8]; 113 static const char *const nec_sreg[8]; 114 static const char *const nec_sfreg[256]; 115 116 config *m_config; 117 const u8 *m_decryption_table; 118 119 u8 m_modrm; 120 u32 m_segment; 121 offs_t m_dasm_flags; 122 std::string m_modrm_string; 123 124 inline u8 FETCH(offs_t pc_base, offs_t &pc, const data_buffer &opcodes); 125 inline u16 FETCH16(offs_t pc_base, offs_t &pc, const data_buffer &opcodes); 126 std::string hexstring(uint32_t value, int digits); 127 std::string shexstring(uint32_t value, int digits, bool always); 128 void handle_modrm(offs_t pc_base, offs_t &pc, const data_buffer ¶ms); 129 void handle_param(std::ostream &stream, uint32_t param, offs_t pc_base, offs_t &pc, const data_buffer ¶ms); 130 void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2, offs_t pc_base, offs_t &pc, const data_buffer ¶ms); 131 132 void decode_opcode(std::ostream &stream, const NEC_I386_OPCODE *op, uint8_t op1, offs_t pc_base, offs_t &pc, const data_buffer &opcodes, const data_buffer ¶ms); 133 offs_t dis80(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms); 134 }; 135 136 137 #endif 138