diff options
-rw-r--r-- | src/devices/cpu/m68000/m68000.h | 5 | ||||
-rw-r--r-- | src/devices/cpu/m68000/m68k_in.lst | 1 | ||||
-rw-r--r-- | src/devices/cpu/m68000/m68kcpu.cpp | 37 | ||||
-rw-r--r-- | src/devices/cpu/m68000/m68kcpu.h | 17 | ||||
-rw-r--r-- | src/devices/cpu/m68000/m68kmmu.h | 1 | ||||
-rw-r--r-- | src/devices/cpu/m68000/m68kops.cpp | 1 |
6 files changed, 48 insertions, 14 deletions
diff --git a/src/devices/cpu/m68000/m68000.h b/src/devices/cpu/m68000/m68000.h index b2647526ba6..3d6a3800c94 100644 --- a/src/devices/cpu/m68000/m68000.h +++ b/src/devices/cpu/m68000/m68000.h @@ -165,9 +165,10 @@ public: template <typename... T> void set_tas_write_callback(T &&... args) { m_tas_write_callback.set(std::forward<T>(args)...); } u16 get_fc(); 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_buserror_details(u32 fault_addr, u8 rw, u8 fc); + void set_buserror_details(u32 fault_addr, u8 rw, u8 fc, bool rerun = false); void disable_interrupt_mixer() { m_interrupt_mixer = false; } void set_cpu_space(int space_id) { m_cpu_space_id = space_id; } @@ -220,6 +221,8 @@ protected: 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 */ /* Clocks required for instructions / exceptions */ diff --git a/src/devices/cpu/m68000/m68k_in.lst b/src/devices/cpu/m68000/m68k_in.lst index 86f5eef9ae6..5206d3de1b4 100644 --- a/src/devices/cpu/m68000/m68k_in.lst +++ b/src/devices/cpu/m68000/m68k_in.lst @@ -5063,6 +5063,7 @@ e3c0 ffc0 lsl w A+-DXWL 01:8 7:14 234fc:5 { m_pmmu_enabled = 0; } + m_instruction_restart = m_pmmu_enabled || m_emmu_enabled; break; case 0x004: /* ITT0 */ m_mmu_itt0 = REG_DA()[(word2 >> 12) & 15]; diff --git a/src/devices/cpu/m68000/m68kcpu.cpp b/src/devices/cpu/m68000/m68kcpu.cpp index f7a61d6f77a..5ccc2f43424 100644 --- a/src/devices/cpu/m68000/m68kcpu.cpp +++ b/src/devices/cpu/m68000/m68kcpu.cpp @@ -775,12 +775,12 @@ void m68000_base_device::m68k_cause_bus_error() else if (CPU_TYPE_IS_010()) { /* only the 68010 throws this unique type-1000 frame */ - m68ki_stack_frame_1000(m_ppc, sr, EXCEPTION_BUS_ERROR); + m68ki_stack_frame_1000(m_ppc, sr, EXCEPTION_BUS_ERROR, m_mmu_tmp_buserror_address); } else if (CPU_TYPE_IS_070()) { /* only the 68070 throws this unique type-1111 frame */ - m68ki_stack_frame_1111(m_ppc, sr, EXCEPTION_BUS_ERROR); + m68ki_stack_frame_1111(m_ppc, sr, EXCEPTION_BUS_ERROR, m_mmu_tmp_buserror_address); } else if (m_mmu_tmp_buserror_address == m_ppc) { @@ -901,7 +901,7 @@ void m68000_base_device::execute_run() try { - if (!m_pmmu_enabled) + if (!m_instruction_restart) { m_run_mode = RUN_MODE_NORMAL; /* Read an instruction and call its handler */ @@ -959,7 +959,7 @@ void m68000_base_device::execute_run() { if (CPU_TYPE_IS_010()) { - m68ki_stack_frame_1000(m_ppc, sr, EXCEPTION_BUS_ERROR); + m68ki_stack_frame_1000(m_ppc, sr, EXCEPTION_BUS_ERROR, m_mmu_tmp_buserror_address); } else { @@ -1029,6 +1029,8 @@ void m68000_base_device::init_cpu_common(void) m_has_hmmu = 0; m_pmmu_enabled = 0; m_hmmu_enabled = 0; + m_emmu_enabled = 0; + m_instruction_restart = 0; /* The first call to this function initializes the opcode handler jump table */ if(!emulation_initialized) @@ -1062,6 +1064,8 @@ void m68000_base_device::init_cpu_common(void) save_item(NAME(m_has_hmmu)); save_item(NAME(m_pmmu_enabled)); save_item(NAME(m_hmmu_enabled)); + save_item(NAME(m_emmu_enabled)); + save_item(NAME(m_instruction_restart)); save_item(NAME(m_mmu_crp_aptr)); save_item(NAME(m_mmu_crp_limit)); @@ -1098,6 +1102,8 @@ void m68000_base_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_mmu_tc = 0; m_mmu_tt0 = 0; @@ -1297,6 +1303,13 @@ void m68000_base_device::set_hmmu_enable(int enable) m_hmmu_enabled = enable; } +/* set for external MMU and instruction restart */ +void m68000_base_device::set_emmu_enable(int enable) +{ + m_emmu_enabled = enable; + m_instruction_restart = m_pmmu_enabled || m_emmu_enabled; +} + void m68000_base_device::set_fpu_enable(int enable) { m_has_fpu = enable; @@ -1662,12 +1675,22 @@ void m68000_base_device::init32hmmu(address_space &space, address_space &ospace) // fault_addr = address to indicate fault at // rw = 1 for read, 0 for write // fc = 3-bit function code of access (usually you'd just put what m68k_get_fc() returns here) -void m68000_base_device::set_buserror_details(u32 fault_addr, u8 rw, u8 fc) +// rerun = trigger bus error and rerun instruction after RTE, intended for external MMU use +// do not call set_input_line(M68K_LINE_BUSERROR) when using rerun flag +void m68000_base_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 + + // save values for 68000 specific bus error m_aerr_address = fault_addr; m_aerr_write_mode = (rw << 4); m_aerr_fc = fc; - m_mmu_tmp_buserror_address = fault_addr; // Hack for x68030 + + // Hack for x68030 and external MMU + m_mmu_tmp_buserror_address = fault_addr; + m_mmu_tmp_buserror_rw = m_mmu_tmp_rw; + m_mmu_tmp_buserror_fc = m_mmu_tmp_fc; + m_mmu_tmp_buserror_sz = m_mmu_tmp_sz; } u16 m68000_base_device::get_fc() @@ -2395,6 +2418,8 @@ void m68000_base_device::clear_all() m_has_hmmu= 0; m_pmmu_enabled= 0; m_hmmu_enabled= 0; + m_emmu_enabled= 0; + m_instruction_restart= 0; m_has_fpu= 0; m_fpu_just_reset= 0; diff --git a/src/devices/cpu/m68000/m68kcpu.h b/src/devices/cpu/m68000/m68kcpu.h index 1502b09d775..aebe498f899 100644 --- a/src/devices/cpu/m68000/m68kcpu.h +++ b/src/devices/cpu/m68000/m68kcpu.h @@ -1188,8 +1188,11 @@ inline void m68ki_stack_frame_buserr(u32 sr) /* Format 8 stack frame (68010). * 68010 only. This is the 29 word bus/address error frame. */ -inline void m68ki_stack_frame_1000(u32 pc, u32 sr, u32 vector) +inline void m68ki_stack_frame_1000(u32 pc, u32 sr, u32 vector, u32 fault_address) { + int orig_rw = m_mmu_tmp_buserror_rw; // this gets splatted by the following pushes, so save it now + int orig_fc = m_mmu_tmp_buserror_fc; + /* VERSION * NUMBER * INTERNAL INFORMATION, 16 WORDS @@ -1222,10 +1225,10 @@ inline void m68ki_stack_frame_1000(u32 pc, u32 sr, u32 vector) m68ki_fake_push_16(); /* FAULT ADDRESS */ - m68ki_push_32(0); + m68ki_push_32(fault_address); /* SPECIAL STATUS WORD */ - m68ki_push_16(0); + m68ki_push_16(orig_fc | (orig_rw<<8)); /* 1000, VECTOR OFFSET */ m68ki_push_16(0x8000 | (vector<<2)); @@ -1240,7 +1243,7 @@ inline void m68ki_stack_frame_1000(u32 pc, u32 sr, u32 vector) /* Format 15 stack frame (68070). * 68070 only. This is the 17 word bus/address error frame. */ -inline void m68ki_stack_frame_1111(uint32_t pc, uint32_t sr, uint32_t vector) +inline void m68ki_stack_frame_1111(u32 pc, u32 sr, u32 vector, u32 fault_address) { /* INTERNAL INFORMATION */ m68ki_fake_push_16(); @@ -1255,7 +1258,7 @@ inline void m68ki_stack_frame_1111(uint32_t pc, uint32_t sr, uint32_t vector) m68ki_push_32(0); /* FAULT ADDRESS */ - m68ki_push_32(0); + m68ki_push_32(fault_address); /* DATA OUTPUT BUFFER */ m68ki_push_32(0); @@ -1598,12 +1601,12 @@ inline void m68ki_exception_address_error() else if (CPU_TYPE_IS_010()) { /* only the 68010 throws this unique type-1000 frame */ - m68ki_stack_frame_1000(m_ppc, sr, EXCEPTION_BUS_ERROR); + m68ki_stack_frame_1000(m_ppc, sr, EXCEPTION_BUS_ERROR, m_mmu_tmp_buserror_address); } else if (CPU_TYPE_IS_070()) { /* only the 68070 throws this unique type-1111 frame */ - m68ki_stack_frame_1111(m_ppc, sr, EXCEPTION_BUS_ERROR); + m68ki_stack_frame_1111(m_ppc, sr, EXCEPTION_BUS_ERROR, m_mmu_tmp_buserror_address); } else if (m_mmu_tmp_buserror_address == m_ppc) { diff --git a/src/devices/cpu/m68000/m68kmmu.h b/src/devices/cpu/m68000/m68kmmu.h index 2c23f73a623..28a4272f6b1 100644 --- a/src/devices/cpu/m68000/m68kmmu.h +++ b/src/devices/cpu/m68000/m68kmmu.h @@ -1086,6 +1086,7 @@ void m68851_pmove_put(u32 ea, u16 modes) m_pmmu_enabled = 0; MMULOG("PMMU disabled\n"); } + m_instruction_restart = m_pmmu_enabled || m_emmu_enabled; if (!(modes & 0x100)) // flush ATC on moves to TC, SRP, CRP with FD bit clear { diff --git a/src/devices/cpu/m68000/m68kops.cpp b/src/devices/cpu/m68000/m68kops.cpp index 3535926fbf9..06b30a61553 100644 --- a/src/devices/cpu/m68000/m68kops.cpp +++ b/src/devices/cpu/m68000/m68kops.cpp @@ -20216,6 +20216,7 @@ void m68000_base_device::x4e7b_movec_l_4() { m_pmmu_enabled = 0; } + m_instruction_restart = m_pmmu_enabled || m_emmu_enabled; break; case 0x004: /* ITT0 */ m_mmu_itt0 = REG_DA()[(word2 >> 12) & 15]; |