summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/m68000/m68kdasm.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/m68000/m68kdasm.h')
-rw-r--r--src/devices/cpu/m68000/m68kdasm.h454
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 &params) 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