// 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 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