diff options
Diffstat (limited to 'src/devices/cpu/m68000/m68kdasm.h')
-rw-r--r-- | src/devices/cpu/m68000/m68kdasm.h | 454 |
1 files changed, 454 insertions, 0 deletions
diff --git a/src/devices/cpu/m68000/m68kdasm.h b/src/devices/cpu/m68000/m68kdasm.h new file mode 100644 index 00000000000..43dfd144980 --- /dev/null +++ b/src/devices/cpu/m68000/m68kdasm.h @@ -0,0 +1,454 @@ +// license:BSD-3-Clause +// copyright-holders:Karl Stenerud +/* ======================================================================== */ +/* ========================= LICENSING & COPYRIGHT ======================== */ +/* ======================================================================== */ +/* + * MUSASHI + * Version 3.32 + * + * A portable Motorola M680x0 processor emulation engine. + * Copyright Karl Stenerud. All rights reserved. + * + */ + +#ifndef MAME_CPU_M68000_M68KDASM_H +#define MAME_CPU_M68000_M68KDASM_H + +#pragma once + +class m68k_disassembler : public util::disasm_interface +{ +public: + enum { + TYPE_68000 = 1, + TYPE_68008 = 2, + TYPE_68010 = 4, + TYPE_68020 = 8, + TYPE_68030 = 16, + TYPE_68040 = 32, + TYPE_68340 = 64, // (CPU32) + TYPE_COLDFIRE = 128, + }; + + m68k_disassembler(u32 type); + virtual ~m68k_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + enum { + M68000_ONLY = (TYPE_68000 | TYPE_68008), + M68010_ONLY = TYPE_68010, + M68010_LESS = (TYPE_68000 | TYPE_68008 | TYPE_68010), + M68010_PLUS = (TYPE_68010 | TYPE_68020 | TYPE_68030 | TYPE_68040 | TYPE_68340 | TYPE_COLDFIRE), + M68020_ONLY = (TYPE_68020 | TYPE_68340), + M68020_LESS = (TYPE_68010 | TYPE_68020 | TYPE_68340), + M68020_PLUS = (TYPE_68020 | TYPE_68030 | TYPE_68040 | TYPE_68340 | TYPE_COLDFIRE), + + M68030_ONLY = TYPE_68030, + M68030_LESS = (TYPE_68010 | TYPE_68020 | TYPE_68030 | TYPE_68340 ), + M68030_PLUS = (TYPE_68030 | TYPE_68040), + M68040_PLUS = TYPE_68040, + + COLDFIRE = TYPE_COLDFIRE + }; + + typedef std::string (m68k_disassembler::*opcode_handler)(); + + struct opcode_struct { + opcode_handler handler; /* handler function */ + u32 mask; /* mask on opcode */ + u32 match; /* what to match after masking */ + u32 ea_mask; /* what ea modes are allowed */ + }; + + /* Extension word formats */ + static inline u32 ext_8bit_displacement(u32 A) { return ((A)&0xff); } + static inline u32 ext_full(u32 A) { return BIT(A, 8); } + static inline u32 ext_effective_zero(u32 A) { return (((A)&0xe4) == 0xc4 || ((A)&0xe2) == 0xc0); } + static inline u32 ext_base_register_present(u32 A) { return (!BIT(A, 7)); } + static inline u32 ext_index_register_present(u32 A) { return (!BIT(A, 6)); } + static inline u32 ext_index_register(u32 A) { return (((A)>>12)&7); } + static inline u32 ext_index_scale(u32 A) { return (((A)>>9)&3); } + static inline u32 ext_index_long(u32 A) { return BIT(A, 11); } + static inline u32 ext_index_ar(u32 A) { return BIT(A, 15); } + static inline u32 ext_base_displacement_present(u32 A) { return (((A)&0x30) > 0x10); } + static inline u32 ext_base_displacement_word(u32 A) { return (((A)&0x30) == 0x20); } + static inline u32 ext_base_displacement_long(u32 A) { return (((A)&0x30) == 0x30); } + static inline u32 ext_outer_displacement_present(u32 A) { return (((A)&3) > 1 && ((A)&0x47) < 0x44); } + static inline u32 ext_outer_displacement_word(u32 A) { return (((A)&3) == 2 && ((A)&0x47) < 0x44); } + static inline u32 ext_outer_displacement_long(u32 A) { return (((A)&3) == 3 && ((A)&0x47) < 0x44); } + + static inline s32 sext_7bit_int(u32 value) { return (value & 0x40) ? (value | 0xffffff80) : (value & 0x7f); } + static inline s32 make_int_8(u8 value) { return s8(value); } + static inline s32 make_int_16(u16 value) { return s16(value); } + static inline s32 make_int_32(u32 value) { return s32(value); } + + static std::string make_signed_hex_str_8(u8 val); + static std::string make_signed_hex_str_16(u16 val); + static std::string make_signed_hex_str_32(u32 val); + + inline u32 read_imm_8 (u32 advance) { u32 result = m_buffer->r8 (m_cpu_pc + 1); m_cpu_pc += advance; return result; } + inline u32 read_imm_16(u32 advance) { u32 result = m_buffer->r16(m_cpu_pc); m_cpu_pc += advance; return result; } + inline u32 read_imm_32(u32 advance) { u32 result = m_buffer->r32(m_cpu_pc); m_cpu_pc += advance; return result; } + + inline u32 read_imm_8 () { return read_imm_8 (2); } // 2 to keep alignement + inline u32 read_imm_16() { return read_imm_16(2); } + inline u32 read_imm_32() { return read_imm_32(4); } + + inline u32 peek_imm_8 () { return read_imm_8 (0); } + inline u32 peek_imm_16() { return read_imm_16(0); } + inline u32 peek_imm_32() { return read_imm_32(0); } + + std::string get_imm_str_s(u32 size); + inline std::string get_imm_str_s8 () { return get_imm_str_s(0); } + inline std::string get_imm_str_s16() { return get_imm_str_s(1); } + inline std::string get_imm_str_s32() { return get_imm_str_s(2); } + + std::string get_imm_str_u(u32 size); + inline std::string get_imm_str_u8 () { return get_imm_str_u(0); } + inline std::string get_imm_str_u16() { return get_imm_str_u(1); } + inline std::string get_imm_str_u32() { return get_imm_str_u(2); } + + std::string get_ea_mode_str(u16 instruction, u32 size); + inline std::string get_ea_mode_str_8 (u16 instruction) { return get_ea_mode_str(instruction, 0); } + inline std::string get_ea_mode_str_16(u16 instruction) { return get_ea_mode_str(instruction, 1); } + inline std::string get_ea_mode_str_32(u16 instruction) { return get_ea_mode_str(instruction, 2); } + + inline std::pair<bool, std::string> limit_cpu_types(u32 allowed); + + std::string d68000_illegal(); + std::string d68000_1010(); + std::string d68000_1111(); + std::string d68000_abcd_rr(); + std::string d68000_abcd_mm(); + std::string d68000_add_er_8(); + std::string d68000_add_er_16(); + std::string d68000_add_er_32(); + std::string d68000_add_re_8(); + std::string d68000_add_re_16(); + std::string d68000_add_re_32(); + std::string d68000_adda_16(); + std::string d68000_adda_32(); + std::string d68000_addi_8(); + std::string d68000_addi_16(); + std::string d68000_addi_32(); + std::string d68000_addq_8(); + std::string d68000_addq_16(); + std::string d68000_addq_32(); + std::string d68000_addx_rr_8(); + std::string d68000_addx_rr_16(); + std::string d68000_addx_rr_32(); + std::string d68000_addx_mm_8(); + std::string d68000_addx_mm_16(); + std::string d68000_addx_mm_32(); + std::string d68000_and_er_8(); + std::string d68000_and_er_16(); + std::string d68000_and_er_32(); + std::string d68000_and_re_8(); + std::string d68000_and_re_16(); + std::string d68000_and_re_32(); + std::string d68000_andi_8(); + std::string d68000_andi_16(); + std::string d68000_andi_32(); + std::string d68000_andi_to_ccr(); + std::string d68000_andi_to_sr(); + std::string d68000_asr_s_8(); + std::string d68000_asr_s_16(); + std::string d68000_asr_s_32(); + std::string d68000_asr_r_8(); + std::string d68000_asr_r_16(); + std::string d68000_asr_r_32(); + std::string d68000_asr_ea(); + std::string d68000_asl_s_8(); + std::string d68000_asl_s_16(); + std::string d68000_asl_s_32(); + std::string d68000_asl_r_8(); + std::string d68000_asl_r_16(); + std::string d68000_asl_r_32(); + std::string d68000_asl_ea(); + std::string d68000_bcc_8(); + std::string d68000_bcc_16(); + std::string d68020_bcc_32(); + std::string d68000_bchg_r(); + std::string d68000_bchg_s(); + std::string d68000_bclr_r(); + std::string d68000_bclr_s(); + std::string d68010_bkpt(); + std::string d68020_bfchg(); + std::string d68020_bfclr(); + std::string d68020_bfexts(); + std::string d68020_bfextu(); + std::string d68020_bfffo(); + std::string d68020_bfins(); + std::string d68020_bfset(); + std::string d68020_bftst(); + std::string d68000_bra_8(); + std::string d68000_bra_16(); + std::string d68020_bra_32(); + std::string d68000_bset_r(); + std::string d68000_bset_s(); + std::string d68000_bsr_8(); + std::string d68000_bsr_16(); + std::string d68020_bsr_32(); + std::string d68000_btst_r(); + std::string d68000_btst_s(); + std::string d68020_callm(); + std::string d68020_cas_8(); + std::string d68020_cas_16(); + std::string d68020_cas_32(); + std::string d68020_cas2_16(); + std::string d68020_cas2_32(); + std::string d68000_chk_16(); + std::string d68020_chk_32(); + std::string d68020_chk2_cmp2_8(); + std::string d68020_chk2_cmp2_16(); + std::string d68020_chk2_cmp2_32(); + std::string d68040_cinv(); + std::string d68000_clr_8(); + std::string d68000_clr_16(); + std::string d68000_clr_32(); + std::string d68000_cmp_8(); + std::string d68000_cmp_16(); + std::string d68000_cmp_32(); + std::string d68000_cmpa_16(); + std::string d68000_cmpa_32(); + std::string d68000_cmpi_8(); + std::string d68020_cmpi_pcdi_8(); + std::string d68020_cmpi_pcix_8(); + std::string d68000_cmpi_16(); + std::string d68020_cmpi_pcdi_16(); + std::string d68020_cmpi_pcix_16(); + std::string d68000_cmpi_32(); + std::string d68020_cmpi_pcdi_32(); + std::string d68020_cmpi_pcix_32(); + std::string d68000_cmpm_8(); + std::string d68000_cmpm_16(); + std::string d68000_cmpm_32(); + std::string d68020_cpbcc_16(); + std::string d68020_cpbcc_32(); + std::string d68020_cpdbcc(); + std::string d68020_cpgen(); + std::string d68020_cprestore(); + std::string d68020_cpsave(); + std::string d68020_cpscc(); + std::string d68020_cptrapcc_0(); + std::string d68020_cptrapcc_16(); + std::string d68020_cptrapcc_32(); + std::string d68040_cpush(); + std::string d68000_dbra(); + std::string d68000_dbcc(); + std::string d68000_divs(); + std::string d68000_divu(); + std::string d68020_divl(); + std::string d68000_eor_8(); + std::string d68000_eor_16(); + std::string d68000_eor_32(); + std::string d68000_eori_8(); + std::string d68000_eori_16(); + std::string d68000_eori_32(); + std::string d68000_eori_to_ccr(); + std::string d68000_eori_to_sr(); + std::string d68000_exg_dd(); + std::string d68000_exg_aa(); + std::string d68000_exg_da(); + std::string d68000_ext_16(); + std::string d68000_ext_32(); + std::string d68020_extb_32(); + std::string d68881_ftrap(); + std::string d68040_fpu(); + std::string d68000_jmp(); + std::string d68000_jsr(); + std::string d68000_lea(); + std::string d68000_link_16(); + std::string d68020_link_32(); + std::string d68000_lsr_s_8(); + std::string d68000_lsr_s_16(); + std::string d68000_lsr_s_32(); + std::string d68000_lsr_r_8(); + std::string d68000_lsr_r_16(); + std::string d68000_lsr_r_32(); + std::string d68000_lsr_ea(); + std::string d68000_lsl_s_8(); + std::string d68000_lsl_s_16(); + std::string d68000_lsl_s_32(); + std::string d68000_lsl_r_8(); + std::string d68000_lsl_r_16(); + std::string d68000_lsl_r_32(); + std::string d68000_lsl_ea(); + std::string d68000_move_8(); + std::string d68000_move_16(); + std::string d68000_move_32(); + std::string d68000_movea_16(); + std::string d68000_movea_32(); + std::string d68000_move_to_ccr(); + std::string d68010_move_fr_ccr(); + std::string d68000_move_fr_sr(); + std::string d68000_move_to_sr(); + std::string d68000_move_fr_usp(); + std::string d68000_move_to_usp(); + std::string d68010_movec(); + std::string d68000_movem_pd_16(); + std::string d68000_movem_pd_32(); + std::string d68000_movem_er_16(); + std::string d68000_movem_er_32(); + std::string d68000_movem_re_16(); + std::string d68000_movem_re_32(); + std::string d68000_movep_re_16(); + std::string d68000_movep_re_32(); + std::string d68000_movep_er_16(); + std::string d68000_movep_er_32(); + std::string d68010_moves_8(); + std::string d68010_moves_16(); + std::string d68010_moves_32(); + std::string d68000_moveq(); + std::string d68040_move16_pi_pi(); + std::string d68040_move16_pi_al(); + std::string d68040_move16_al_pi(); + std::string d68040_move16_ai_al(); + std::string d68040_move16_al_ai(); + std::string d68000_muls(); + std::string d68000_mulu(); + std::string d68020_mull(); + std::string d68000_nbcd(); + std::string d68000_neg_8(); + std::string d68000_neg_16(); + std::string d68000_neg_32(); + std::string d68000_negx_8(); + std::string d68000_negx_16(); + std::string d68000_negx_32(); + std::string d68000_nop(); + std::string d68000_not_8(); + std::string d68000_not_16(); + std::string d68000_not_32(); + std::string d68000_or_er_8(); + std::string d68000_or_er_16(); + std::string d68000_or_er_32(); + std::string d68000_or_re_8(); + std::string d68000_or_re_16(); + std::string d68000_or_re_32(); + std::string d68000_ori_8(); + std::string d68000_ori_16(); + std::string d68000_ori_32(); + std::string d68000_ori_to_ccr(); + std::string d68000_ori_to_sr(); + std::string d68020_pack_rr(); + std::string d68020_pack_mm(); + std::string d68000_pea(); + std::string d68040_pflush(); + std::string d68000_reset(); + std::string d68000_ror_s_8(); + std::string d68000_ror_s_16(); + std::string d68000_ror_s_32(); + std::string d68000_ror_r_8(); + std::string d68000_ror_r_16(); + std::string d68000_ror_r_32(); + std::string d68000_ror_ea(); + std::string d68000_rol_s_8(); + std::string d68000_rol_s_16(); + std::string d68000_rol_s_32(); + std::string d68000_rol_r_8(); + std::string d68000_rol_r_16(); + std::string d68000_rol_r_32(); + std::string d68000_rol_ea(); + std::string d68000_roxr_s_8(); + std::string d68000_roxr_s_16(); + std::string d68000_roxr_s_32(); + std::string d68000_roxr_r_8(); + std::string d68000_roxr_r_16(); + std::string d68000_roxr_r_32(); + std::string d68000_roxr_ea(); + std::string d68000_roxl_s_8(); + std::string d68000_roxl_s_16(); + std::string d68000_roxl_s_32(); + std::string d68000_roxl_r_8(); + std::string d68000_roxl_r_16(); + std::string d68000_roxl_r_32(); + std::string d68000_roxl_ea(); + std::string d68010_rtd(); + std::string d68000_rte(); + std::string d68020_rtm(); + std::string d68000_rtr(); + std::string d68000_rts(); + std::string d68000_sbcd_rr(); + std::string d68000_sbcd_mm(); + std::string d68000_scc(); + std::string d68000_stop(); + std::string d68000_sub_er_8(); + std::string d68000_sub_er_16(); + std::string d68000_sub_er_32(); + std::string d68000_sub_re_8(); + std::string d68000_sub_re_16(); + std::string d68000_sub_re_32(); + std::string d68000_suba_16(); + std::string d68000_suba_32(); + std::string d68000_subi_8(); + std::string d68000_subi_16(); + std::string d68000_subi_32(); + std::string d68000_subq_8(); + std::string d68000_subq_16(); + std::string d68000_subq_32(); + std::string d68000_subx_rr_8(); + std::string d68000_subx_rr_16(); + std::string d68000_subx_rr_32(); + std::string d68000_subx_mm_8(); + std::string d68000_subx_mm_16(); + std::string d68000_subx_mm_32(); + std::string d68000_swap(); + std::string d68000_tas(); + std::string d68000_trap(); + std::string d68020_trapcc_0(); + std::string d68020_trapcc_16(); + std::string d68020_trapcc_32(); + std::string d68000_trapv(); + std::string d68000_tst_8(); + std::string d68020_tst_pcdi_8(); + std::string d68020_tst_pcix_8(); + std::string d68020_tst_i_8(); + std::string d68000_tst_16(); + std::string d68020_tst_a_16(); + std::string d68020_tst_pcdi_16(); + std::string d68020_tst_pcix_16(); + std::string d68020_tst_i_16(); + std::string d68000_tst_32(); + std::string d68020_tst_a_32(); + std::string d68020_tst_pcdi_32(); + std::string d68020_tst_pcix_32(); + std::string d68020_tst_i_32(); + std::string d68000_unlk(); + std::string d68020_unpk_rr(); + std::string d68020_unpk_mm(); + std::string d68851_p000(); + std::string d68851_pbcc16(); + std::string d68851_pbcc32(); + std::string d68851_pdbcc(); + std::string d68851_p001(); + std::string d68040_fbcc_16(); + std::string d68040_fbcc_32(); + + static bool valid_ea(u32 opcode, u32 mask); + static bool compare_nof_true_bits(const opcode_struct *aptr, const opcode_struct *bptr); + void build_opcode_table(); + + + /* used by ops like asr, ror, addq, etc */ + static const u32 m_3bit_qdata_table[8]; + static const u32 m_5bit_data_table[32]; + + static const char *const m_cc[16]; + static const char *const m_cpcc[64]; + static const char *const m_mmuregs[8]; + static const char *const m_mmucond[16]; + + static const opcode_struct m_opcode_info[]; + opcode_handler m_instruction_table[0x10000]; + + const data_buffer *m_buffer; + u32 m_cpu_type, m_cpu_pc, m_flags; + u16 m_cpu_ir; +}; + + +#endif |