summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/devices/cpu/m68000/m68000.h5
-rw-r--r--src/devices/cpu/m68000/m68k_in.lst1
-rw-r--r--src/devices/cpu/m68000/m68kcpu.cpp37
-rw-r--r--src/devices/cpu/m68000/m68kcpu.h17
-rw-r--r--src/devices/cpu/m68000/m68kmmu.h1
-rw-r--r--src/devices/cpu/m68000/m68kops.cpp1
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];