From 445bf3e6f40be6709927b05f6f6941ca2ffd3bf8 Mon Sep 17 00:00:00 2001 From: arbee Date: Wed, 5 Jul 2023 11:02:40 -0400 Subject: cpu/m68000: Allow drivers and devices to use the instruction restart capability on the 020/030/040. [R. Belmont] --- src/devices/cpu/m68000/m68kcpu.cpp | 110 ++++++++++++++++++++--------------- src/devices/cpu/m68000/m68kmusashi.h | 26 +++++---- 2 files changed, 77 insertions(+), 59 deletions(-) diff --git a/src/devices/cpu/m68000/m68kcpu.cpp b/src/devices/cpu/m68000/m68kcpu.cpp index 3aa2d74b771..83f50246b02 100644 --- a/src/devices/cpu/m68000/m68kcpu.cpp +++ b/src/devices/cpu/m68000/m68kcpu.cpp @@ -922,7 +922,7 @@ void m68000_musashi_device::execute_run() tmp_dar[i] = REG_DA()[i]; } - m_mmu_tmp_buserror_occurred = 0; + m_mmu_tmp_buserror_occurred = false; /* Read an instruction and call its handler */ m_ir = m68ki_read_imm_16(); @@ -938,7 +938,7 @@ void m68000_musashi_device::execute_run() { u32 sr; - m_mmu_tmp_buserror_occurred = 0; + m_mmu_tmp_buserror_occurred = false; // restore cpu address registers to value at start of instruction for (i = 15; i >= 0; i--) @@ -951,39 +951,47 @@ void m68000_musashi_device::execute_run() } } - sr = m68ki_init_exception(EXCEPTION_BUS_ERROR); + // for a simple restart request, simply back up the program counter + if (m_restart_instruction) + { + m_restart_instruction = false; + m_pc = m_ppc; + } + else + { + sr = m68ki_init_exception(EXCEPTION_BUS_ERROR); - m_run_mode = RUN_MODE_BERR_AERR_RESET; + m_run_mode = RUN_MODE_BERR_AERR_RESET; - if (!CPU_TYPE_IS_020_PLUS()) - { - if (CPU_TYPE_IS_010()) + if (!CPU_TYPE_IS_020_PLUS()) { - m68ki_stack_frame_1000(m_ppc, sr, EXCEPTION_BUS_ERROR, m_mmu_tmp_buserror_address); + if (CPU_TYPE_IS_010()) + { + m68ki_stack_frame_1000(m_ppc, sr, EXCEPTION_BUS_ERROR, m_mmu_tmp_buserror_address); + } + else + { + /* Note: This is implemented for 68000 only! */ + m68ki_stack_frame_buserr(sr); + } } - else - { - /* Note: This is implemented for 68000 only! */ - m68ki_stack_frame_buserr(sr); - } - } - else if(!CPU_TYPE_IS_040_PLUS()) { - if (m_mmu_tmp_buserror_address == m_ppc) - { - m68ki_stack_frame_1010(sr, EXCEPTION_BUS_ERROR, m_ppc, m_mmu_tmp_buserror_address); + else if(!CPU_TYPE_IS_040_PLUS()) { + if (m_mmu_tmp_buserror_address == m_ppc) + { + m68ki_stack_frame_1010(sr, EXCEPTION_BUS_ERROR, m_ppc, m_mmu_tmp_buserror_address); + } + else + { + m68ki_stack_frame_1011(sr, EXCEPTION_BUS_ERROR, m_ppc, m_mmu_tmp_buserror_address); + } } else { - m68ki_stack_frame_1011(sr, EXCEPTION_BUS_ERROR, m_ppc, m_mmu_tmp_buserror_address); + m68ki_stack_frame_0111(sr, EXCEPTION_BUS_ERROR, m_ppc, m_mmu_tmp_buserror_address, true); } - } - else - { - m68ki_stack_frame_0111(sr, EXCEPTION_BUS_ERROR, m_ppc, m_mmu_tmp_buserror_address, true); - } - - m68ki_jump_vector(EXCEPTION_BUS_ERROR); + m68ki_jump_vector(EXCEPTION_BUS_ERROR); + } // TODO: /* Use up some clock cycles and undo the instruction's cycles */ // m_icount -= m_cyc_exception[EXCEPTION_BUS_ERROR] - m_cyc_instruction[m_ir]; @@ -1025,12 +1033,12 @@ void m68000_musashi_device::init_cpu_common(void) m_cpu_space = &space(m_cpu_space_id); /* disable all MMUs */ - m_has_pmmu = 0; - m_has_hmmu = 0; - m_pmmu_enabled = 0; - m_hmmu_enabled = 0; - m_emmu_enabled = 0; - m_instruction_restart = 0; + m_has_pmmu = false; + m_has_hmmu = false; + m_pmmu_enabled = false; + m_hmmu_enabled = false; + m_emmu_enabled = false; + m_instruction_restart = false; /* The first call to this function initializes the opcode handler jump table */ if(!emulation_initialized) @@ -1066,6 +1074,7 @@ void m68000_musashi_device::init_cpu_common(void) save_item(NAME(m_hmmu_enabled)); save_item(NAME(m_emmu_enabled)); save_item(NAME(m_instruction_restart)); + save_item(NAME(m_restart_instruction)); save_item(NAME(m_mmu_crp_aptr)); save_item(NAME(m_mmu_crp_limit)); @@ -1100,10 +1109,10 @@ void m68000_musashi_device::init_cpu_common(void) void m68000_musashi_device::device_reset() { /* Disable the PMMU/HMMU on reset, if any */ - m_pmmu_enabled = 0; - m_hmmu_enabled = 0; - m_emmu_enabled = 0; - m_instruction_restart = 0; + m_pmmu_enabled = false; + m_hmmu_enabled = false; + m_emmu_enabled = false; + m_instruction_restart = false; m_mmu_tc = 0; m_mmu_tt0 = 0; @@ -1298,19 +1307,19 @@ void m68000_musashi_device::state_string_export(const device_state_entry &entry, /* global access */ -void m68000_musashi_device::set_hmmu_enable(int enable) +void m68000_musashi_device::set_hmmu_enable(bool enable) { m_hmmu_enabled = enable; } /* set for external MMU and instruction restart */ -void m68000_musashi_device::set_emmu_enable(int enable) +void m68000_musashi_device::set_emmu_enable(bool enable) { m_emmu_enabled = enable; m_instruction_restart = m_pmmu_enabled || m_emmu_enabled; } -void m68000_musashi_device::set_fpu_enable(int enable) +void m68000_musashi_device::set_fpu_enable(bool enable) { m_has_fpu = enable; } @@ -1679,7 +1688,7 @@ void m68000_musashi_device::init32hmmu(address_space &space, address_space &ospa // do not call set_input_line(M68K_LINE_BUSERROR) when using rerun flag void m68000_musashi_device::set_buserror_details(u32 fault_addr, u8 rw, u8 fc, bool rerun) { - if (m_instruction_restart && rerun) m_mmu_tmp_buserror_occurred = 1; // hack for external MMU + if (m_instruction_restart && rerun) m_mmu_tmp_buserror_occurred = true; // hack for external MMU // save values for 68000 specific bus error m_aerr_address = fault_addr; @@ -1693,6 +1702,12 @@ void m68000_musashi_device::set_buserror_details(u32 fault_addr, u8 rw, u8 fc, b m_mmu_tmp_buserror_sz = m_mmu_tmp_sz; } +void m68000_musashi_device::restart_this_instruction() +{ + m_mmu_tmp_buserror_occurred = true; + m_restart_instruction = true; +} + u16 m68000_musashi_device::get_fc() const noexcept { return m_mmu_tmp_fc; @@ -2317,12 +2332,12 @@ void m68000_musashi_device::clear_all() m_sr_mask= 0; m_instr_mode= 0; m_run_mode= 0; - m_has_pmmu= 0; - m_has_hmmu= 0; - m_pmmu_enabled= 0; - m_hmmu_enabled= 0; - m_emmu_enabled= 0; - m_instruction_restart= 0; + m_has_pmmu= false; + m_has_hmmu= false; + m_pmmu_enabled= false; + m_hmmu_enabled= false; + m_emmu_enabled= false; + m_instruction_restart= false; m_has_fpu= 0; m_fpu_just_reset= 0; @@ -2383,7 +2398,8 @@ void m68000_musashi_device::clear_all() m_mmu_tmp_fc = 0; m_mmu_tmp_rw = 0; m_mmu_tmp_buserror_address = 0; - m_mmu_tmp_buserror_occurred = 0; + m_mmu_tmp_buserror_occurred = false; + m_restart_instruction = false; m_mmu_tmp_buserror_fc = 0; m_mmu_tmp_buserror_rw = 0; diff --git a/src/devices/cpu/m68000/m68kmusashi.h b/src/devices/cpu/m68000/m68kmusashi.h index 25460d24c01..5a530ee77b4 100644 --- a/src/devices/cpu/m68000/m68kmusashi.h +++ b/src/devices/cpu/m68000/m68kmusashi.h @@ -124,11 +124,12 @@ protected: public: virtual u16 get_fc() const noexcept override; - void set_hmmu_enable(int enable); - void set_emmu_enable(int enable); - int get_pmmu_enable() const {return m_pmmu_enabled;} - void set_fpu_enable(int enable); + void set_hmmu_enable(bool enable); + void set_emmu_enable(bool enable); + bool get_pmmu_enable() const {return m_pmmu_enabled;} + void set_fpu_enable(bool enable); void set_buserror_details(u32 fault_addr, u8 rw, u8 fc, bool rerun = false); + void restart_this_instruction(); protected: m68000_musashi_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, @@ -137,7 +138,7 @@ protected: m68000_musashi_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, const device_type type, u32 prg_data_width, u32 prg_address_bits, address_map_constructor internal_map); - int m_has_fpu; /* Indicates if a FPU is available (yes on 030, 040, may be on 020) */ + bool m_has_fpu; /* Indicates if a FPU is available (yes on 030, 040, may be on 020) */ u32 m_cpu_type; /* CPU Type: 68000, 68008, 68010, 68EC020, 68020, 68EC030, 68030, 68EC040, or 68040 */ // @@ -172,13 +173,14 @@ protected: u32 m_sr_mask; /* Implemented status register bits */ u32 m_instr_mode; /* Stores whether we are in instruction mode or group 0/1 exception mode */ u32 m_run_mode; /* Stores whether we are processing a reset, bus error, address error, or something else */ - int m_has_pmmu; /* Indicates if a PMMU available (yes on 030, 040, no on EC030) */ - int m_has_hmmu; /* Indicates if an Apple HMMU is available in place of the 68851 (020 only) */ - int m_pmmu_enabled; /* Indicates if the PMMU is enabled */ - int m_hmmu_enabled; /* Indicates if the HMMU is enabled */ - int m_emmu_enabled; /* Indicates if external MMU is enabled */ - int m_instruction_restart; /* Save DA regs for potential instruction restart */ - int m_fpu_just_reset; /* Indicates the FPU was just reset */ + bool m_has_pmmu; /* Indicates if a PMMU available (yes on 030, 040, no on EC030) */ + bool m_has_hmmu; /* Indicates if an Apple HMMU is available in place of the 68851 (020 only) */ + bool m_pmmu_enabled; /* Indicates if the PMMU is enabled */ + bool m_hmmu_enabled; /* Indicates if the HMMU is enabled */ + bool m_emmu_enabled; /* Indicates if external MMU is enabled */ + bool m_instruction_restart; /* Save DA regs for potential instruction restart */ + bool m_fpu_just_reset; /* Indicates the FPU was just reset */ + bool m_restart_instruction; /* Indicates the instruction should be restarted */ /* Clocks required for instructions / exceptions */ u32 m_cyc_bcc_notake_b; -- cgit v1.2.3