summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/m68000/m68kcpu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/m68000/m68kcpu.cpp')
-rw-r--r--src/devices/cpu/m68000/m68kcpu.cpp257
1 files changed, 244 insertions, 13 deletions
diff --git a/src/devices/cpu/m68000/m68kcpu.cpp b/src/devices/cpu/m68000/m68kcpu.cpp
index 2ab2cb9fd43..19d1063e026 100644
--- a/src/devices/cpu/m68000/m68kcpu.cpp
+++ b/src/devices/cpu/m68000/m68kcpu.cpp
@@ -9,7 +9,7 @@ static const char copyright_notice[] =
"MUSASHI\n"
"Version 4.95 (2012-02-19)\n"
"A portable Motorola M68xxx/CPU32/ColdFire processor emulation engine.\n"
-"Copyright Karl Stenerud. All rights reserved.\n"
+"Copyright Karl Stenerud.\n"
;
#endif
@@ -880,6 +880,7 @@ void m68000_musashi_device::execute_run()
}
if(m_stopped)
{
+ debugger_wait_hook();
if (m_icount > 0)
m_icount = 0;
return;
@@ -901,7 +902,7 @@ void m68000_musashi_device::execute_run()
try
{
- if (!m_instruction_restart)
+ if (!m_can_instruction_restart)
{
m_run_mode = RUN_MODE_NORMAL;
/* Read an instruction and call its handler */
@@ -1038,7 +1039,7 @@ void m68000_musashi_device::init_cpu_common(void)
m_pmmu_enabled = false;
m_hmmu_enabled = 0;
m_emmu_enabled = false;
- m_instruction_restart = false;
+ m_can_instruction_restart = false;
/* The first call to this function initializes the opcode handler jump table */
if(!emulation_initialized)
@@ -1073,7 +1074,7 @@ void m68000_musashi_device::init_cpu_common(void)
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_can_instruction_restart));
save_item(NAME(m_restart_instruction));
save_item(NAME(m_mmu_crp_aptr));
@@ -1112,7 +1113,7 @@ void m68000_musashi_device::device_reset()
m_pmmu_enabled = false;
m_hmmu_enabled = 0;
m_emmu_enabled = false;
- m_instruction_restart = false;
+ m_can_instruction_restart = false;
m_mmu_tc = 0;
m_mmu_tt0 = 0;
@@ -1316,7 +1317,7 @@ void m68000_musashi_device::set_hmmu_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;
+ m_can_instruction_restart = m_pmmu_enabled || m_emmu_enabled;
}
void m68000_musashi_device::set_fpu_enable(bool enable)
@@ -1602,6 +1603,238 @@ void m68000_musashi_device::init32mmu(address_space &space, address_space &ospac
};
}
+/* interface for 32-bit data bus without byte smearing 68040) */
+void m68000_musashi_device::init32_no_smear(address_space &space, address_space &ospace)
+{
+ m_space = &space;
+ m_ospace = &ospace;
+ ospace.cache(m_oprogram32);
+ space.specific(m_program32);
+
+ m_readimm16 = [this](offs_t address) -> u16
+ { return m_oprogram32.read_word(address); };
+ m_read8 = [this](offs_t address) -> u8
+ { return m_program32.read_byte(address); };
+ m_read16 = [this](offs_t address) -> u16
+ { return m_program32.read_word_unaligned(address); };
+ m_read32 = [this](offs_t address) -> u32
+ { return m_program32.read_dword_unaligned(address); };
+ m_write8 = [this](offs_t address, u8 data)
+ { return m_program32.write_byte(address, data); };
+ m_write16 = [this](offs_t address, u16 data)
+ {
+ if (address & 1)
+ {
+ m_program32.write_byte(address, data >> 8);
+ m_program32.write_byte(address + 1, data & 0xff);
+ }
+ else
+ {
+ m_program32.write_word(address, data);
+ }
+ return;
+ };
+ m_write32 = [this](offs_t address, u32 data)
+ {
+ switch (address & 3)
+ {
+ case 0:
+ m_program32.write_dword(address, data, 0xffffffffU);
+ break;
+
+ case 1:
+ m_program32.write_dword(address - 1, (data & 0xff000000U) | (data & 0xffffff00U) >> 8, 0x00ffffff);
+ m_program32.write_dword(address + 3, dword_from_byte(data & 0x000000ff), 0xff000000U);
+ break;
+
+ case 2:
+ m_program32.write_dword(address - 2, dword_from_word((data & 0xffff0000U) >> 16), 0x0000ffff);
+ m_program32.write_dword(address + 2, dword_from_word(data & 0x0000ffff), 0xffff0000U);
+ break;
+
+ case 3:
+ m_program32.write_dword(address - 3, dword_from_unaligned_word((data & 0xffff0000U) >> 16), 0x000000ff);
+ m_program32.write_dword(address + 1, rotl_32(data, 8), 0xffffff00U);
+ break;
+ }
+ };
+}
+
+/* interface for 32-bit data bus with PMMU without byte smearing (68040)*/
+void m68000_musashi_device::init32mmu_no_smear(address_space &space, address_space &ospace)
+{
+ m_space = &space;
+ m_ospace = &ospace;
+ ospace.cache(m_oprogram32);
+ space.specific(m_program32);
+
+ m_readimm16 = [this](offs_t address) -> u16
+ {
+ if (m_pmmu_enabled)
+ {
+ address = pmmu_translate_addr(address, 1);
+ if (m_mmu_tmp_buserror_occurred)
+ return ~0;
+ }
+
+ return m_oprogram32.read_word(address);
+ };
+
+ m_read8 = [this](offs_t address) -> u8
+ {
+ if (m_pmmu_enabled)
+ {
+ address = pmmu_translate_addr(address, 1);
+ if (m_mmu_tmp_buserror_occurred)
+ return ~0;
+ }
+ return m_program32.read_byte(address);
+ };
+
+ m_read16 = [this](offs_t address) -> u16
+ {
+ if (m_pmmu_enabled)
+ {
+ u32 address0 = pmmu_translate_addr(address, 1);
+ if (m_mmu_tmp_buserror_occurred)
+ return ~0;
+ if (WORD_ALIGNED(address))
+ return m_program32.read_word(address0);
+ u32 address1 = pmmu_translate_addr(address + 1, 1);
+ if (m_mmu_tmp_buserror_occurred)
+ return ~0;
+ u16 result = m_program32.read_byte(address0) << 8;
+ return result | m_program32.read_byte(address1);
+ }
+ return m_program32.read_word_unaligned(address);
+ };
+
+ m_read32 = [this](offs_t address) -> u32
+ {
+ if (m_pmmu_enabled)
+ {
+ u32 address0 = pmmu_translate_addr(address, 1);
+ if (m_mmu_tmp_buserror_occurred)
+ return ~0;
+ if ((address + 3) & 0xfc)
+ // not at page boundary; use default code
+ address = address0;
+ else if (DWORD_ALIGNED(address)) // 0
+ return m_program32.read_dword(address0);
+ else
+ {
+ u32 address2 = pmmu_translate_addr(address + 2, 1);
+ if (m_mmu_tmp_buserror_occurred)
+ return ~0;
+ if (WORD_ALIGNED(address))
+ { // 2
+ u32 result = m_program32.read_word(address0) << 16;
+ return result | m_program32.read_word(address2);
+ }
+ u32 address1 = pmmu_translate_addr(address + 1, 1);
+ u32 address3 = pmmu_translate_addr(address + 3, 1);
+ if (m_mmu_tmp_buserror_occurred)
+ return ~0;
+ u32 result = m_program32.read_byte(address0) << 24;
+ result |= m_program32.read_word(address1) << 8;
+ return result | m_program32.read_byte(address3);
+ }
+ }
+ return m_program32.read_dword_unaligned(address);
+ };
+
+ m_write8 = [this](offs_t address, u8 data)
+ {
+ u32 address0 = address;
+ if (m_pmmu_enabled)
+ {
+ address0 = pmmu_translate_addr(address, 0);
+ if (m_mmu_tmp_buserror_occurred)
+ return;
+ }
+ m_program32.write_byte(address0, data);
+ };
+
+ m_write16 = [this](offs_t address, u16 data)
+ {
+ u32 address0 = address;
+ if (m_pmmu_enabled)
+ {
+ address0 = pmmu_translate_addr(address0, 0);
+ if (m_mmu_tmp_buserror_occurred)
+ return;
+ }
+ if (address0 & 1)
+ {
+ m_program32.write_byte(address0, data >> 8);
+ m_program32.write_byte(address0 + 1, data & 0xff);
+ }
+ else
+ {
+ m_program32.write_word(address0, data);
+ }
+ };
+
+ m_write32 = [this](offs_t address, u32 data)
+ {
+ u32 address0 = address;
+ if (m_pmmu_enabled)
+ {
+ address0 = pmmu_translate_addr(address0, 0);
+ if (m_mmu_tmp_buserror_occurred)
+ return;
+ }
+ switch (address & 3)
+ {
+ case 0:
+ m_program32.write_dword(address0, data, 0xffffffffU);
+ break;
+
+ case 1:
+ {
+ u32 address3 = address + 3;
+ if (m_pmmu_enabled)
+ {
+ address3 = pmmu_translate_addr(address3, 0);
+ if (m_mmu_tmp_buserror_occurred)
+ return;
+ }
+ m_program32.write_dword(address0 - 1, (data & 0xff000000U) | (data & 0xffffff00U) >> 8, 0x00ffffff);
+ m_program32.write_dword(address3, dword_from_byte(data & 0x000000ff), 0xff000000U);
+ break;
+ }
+
+ case 2:
+ {
+ u32 address2 = address + 2;
+ if (m_pmmu_enabled)
+ {
+ address2 = pmmu_translate_addr(address2, 0);
+ if (m_mmu_tmp_buserror_occurred)
+ return;
+ }
+ m_program32.write_dword(address0 - 2, dword_from_word((data & 0xffff0000U) >> 16), 0x0000ffff);
+ m_program32.write_dword(address2, dword_from_word(data & 0x0000ffff), 0xffff0000U);
+ break;
+ }
+
+ case 3:
+ {
+ u32 address1 = address + 1;
+ if (m_pmmu_enabled)
+ {
+ address1 = pmmu_translate_addr(address1, 0);
+ if (m_mmu_tmp_buserror_occurred)
+ return;
+ }
+ m_program32.write_dword(address0 - 3, dword_from_unaligned_word((data & 0xffff0000U) >> 16), 0x000000ff);
+ m_program32.write_dword(address1, rotl_32(data, 8), 0xffffff00U);
+ break;
+ }
+ }
+ };
+}
+
void m68000_musashi_device::init32hmmu(address_space &space, address_space &ospace)
{
m_space = &space;
@@ -1688,7 +1921,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 = true; // hack for external MMU
+ if (m_can_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;
@@ -1997,7 +2230,6 @@ void m68000_musashi_device::init_cpu_m68030(void)
m_cyc_shift = 1;
m_cyc_reset = 518;
m_has_pmmu = 1;
- m_has_fpu = 1;
define_state();
}
@@ -2040,7 +2272,7 @@ void m68000_musashi_device::init_cpu_m68040(void)
m_cpu_type = CPU_TYPE_040;
- init32mmu(*m_program, *m_oprogram);
+ init32mmu_no_smear(*m_program, *m_oprogram);
m_sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
m_state_table = m68ki_instruction_state_table[5];
m_cyc_instruction = m68ki_cycles[5];
@@ -2055,7 +2287,6 @@ void m68000_musashi_device::init_cpu_m68040(void)
m_cyc_shift = 1;
m_cyc_reset = 518;
m_has_pmmu = 1;
- m_has_fpu = 1;
define_state();
}
@@ -2068,7 +2299,7 @@ void m68000_musashi_device::init_cpu_m68ec040(void)
m_cpu_type = CPU_TYPE_EC040;
- init32(*m_program, *m_oprogram);
+ init32_no_smear(*m_program, *m_oprogram);
m_sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
m_state_table = m68ki_instruction_state_table[5];
m_cyc_instruction = m68ki_cycles[5];
@@ -2096,7 +2327,7 @@ void m68000_musashi_device::init_cpu_m68lc040(void)
m_cpu_type = CPU_TYPE_LC040;
- init32mmu(*m_program, *m_oprogram);
+ init32mmu_no_smear(*m_program, *m_oprogram);
m_sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
m_state_table = m68ki_instruction_state_table[5];
m_cyc_instruction = m68ki_cycles[5];
@@ -2337,7 +2568,7 @@ void m68000_musashi_device::clear_all()
m_pmmu_enabled= false;
m_hmmu_enabled= 0;
m_emmu_enabled= false;
- m_instruction_restart= false;
+ m_can_instruction_restart= false;
m_has_fpu= 0;
m_fpu_just_reset= 0;