summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author R. Belmont <rb6502@users.noreply.github.com>2016-11-23 23:04:34 -0500
committer GitHub <noreply@github.com>2016-11-23 23:04:34 -0500
commitb78109fea686979c5fe1d8d5f5d9243713e155ef (patch)
tree8f7c9ee275ced9b24bd79b009d0857731bfcb9d5 /src
parent4cb37e50fa32db1d03e68535e935c653e51c033e (diff)
parent74289af32800ace3f46c2192f0dd7c259f81125c (diff)
Merge pull request #1770 from mamehaze/mk6
allow experimental SH4 MMU test code to be turned on / off on a per-driver basis.
Diffstat (limited to 'src')
-rw-r--r--src/devices/cpu/sh4/sh4.cpp226
-rw-r--r--src/devices/cpu/sh4/sh4.h11
-rw-r--r--src/devices/cpu/sh4/sh4comn.cpp84
-rw-r--r--src/mame/drivers/aristmk6.cpp1
4 files changed, 251 insertions, 71 deletions
diff --git a/src/devices/cpu/sh4/sh4.cpp b/src/devices/cpu/sh4/sh4.cpp
index 637929121ec..0dce1e5c744 100644
--- a/src/devices/cpu/sh4/sh4.cpp
+++ b/src/devices/cpu/sh4/sh4.cpp
@@ -103,6 +103,7 @@ sh34_base_device::sh34_base_device(const machine_config &mconfig, device_type ty
, c_md7(0)
, c_md8(0)
, c_clock(0)
+ , m_mmuhack(1)
#if SH4_USE_FASTRAM_OPTIMIZATION
, m_bigendian(endianness == ENDIANNESS_BIG)
, m_byte_xor(m_bigendian ? BYTE8_XOR_BE(0) : BYTE8_XOR_LE(0))
@@ -298,21 +299,36 @@ inline uint8_t sh34_base_device::RB(offs_t A)
if (A >= 0xe0000000)
return m_program->read_byte(A);
-#if SH4_USE_FASTRAM_OPTIMIZATION
- const offs_t _A = A & AM;
- for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
+ if (A >= 0x80000000) // P1/P2/P3 region
{
- if (_A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end)
+#if SH4_USE_FASTRAM_OPTIMIZATION
+ const offs_t _A = A & AM;
+ for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
{
- continue;
+ if (_A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end)
+ {
+ continue;
+ }
+ uint8_t *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start;
+ return fastbase[_A ^ m_byte_xor];
}
- uint8_t *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start;
- return fastbase[_A ^ m_byte_xor];
- }
- return m_program->read_byte(_A);
+ return m_program->read_byte(_A);
#else
- return m_program->read_byte(A & AM);
+ return m_program->read_byte(A & AM);
#endif
+ }
+ else // P0 region
+ {
+ if (!m_sh4_mmu_enabled)
+ {
+ return m_program->read_byte(A & AM);
+ }
+ else
+ {
+ A = get_remap(A & AM);
+ return m_program->read_byte(A);
+ }
+ }
}
@@ -321,21 +337,36 @@ inline uint16_t sh34_base_device::RW(offs_t A)
if (A >= 0xe0000000)
return m_program->read_word(A);
-#if SH4_USE_FASTRAM_OPTIMIZATION
- const offs_t _A = A & AM;
- for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
+ if (A >= 0x80000000) // P1/P2/P3 region
{
- if (_A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end)
+#if SH4_USE_FASTRAM_OPTIMIZATION
+ const offs_t _A = A & AM;
+ for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
{
- continue;
+ if (_A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end)
+ {
+ continue;
+ }
+ uint8_t *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start;
+ return ((uint16_t*)fastbase)[(_A ^ m_word_xor) >> 1];
}
- uint8_t *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start;
- return ((uint16_t*)fastbase)[(_A ^ m_word_xor) >> 1];
- }
- return m_program->read_word(_A);
+ return m_program->read_word(_A);
#else
- return m_program->read_word(A & AM);
+ return m_program->read_word(A & AM);
#endif
+ }
+ else
+ {
+ if (!m_sh4_mmu_enabled)
+ {
+ return m_program->read_word(A & AM);
+ }
+ else
+ {
+ A = get_remap(A & AM);
+ return m_program->read_word(A);
+ }
+ }
}
@@ -344,21 +375,36 @@ inline uint32_t sh34_base_device::RL(offs_t A)
if (A >= 0xe0000000)
return m_program->read_dword(A);
-#if SH4_USE_FASTRAM_OPTIMIZATION
- const offs_t _A = A & AM;
- for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
+ if (A >= 0x80000000) // P1/P2/P3 region
{
- if (_A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end)
+#if SH4_USE_FASTRAM_OPTIMIZATION
+ const offs_t _A = A & AM;
+ for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
{
- continue;
+ if (_A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end)
+ {
+ continue;
+ }
+ uint8_t *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start;
+ return ((uint32_t*)fastbase)[(_A^m_dword_xor) >> 2];
}
- uint8_t *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start;
- return ((uint32_t*)fastbase)[(_A^m_dword_xor) >> 2];
- }
- return m_program->read_dword(_A);
+ return m_program->read_dword(_A);
#else
- return m_program->read_dword(A & AM);
+ return m_program->read_dword(A & AM);
#endif
+ }
+ else
+ {
+ if (!m_sh4_mmu_enabled)
+ {
+ return m_program->read_dword(A & AM);
+ }
+ else
+ {
+ A = get_remap(A & AM);
+ return m_program->read_dword(A);
+ }
+ }
}
@@ -369,22 +415,38 @@ inline void sh34_base_device::WB(offs_t A, uint8_t V)
m_program->write_byte(A,V);
return;
}
-#if SH4_USE_FASTRAM_OPTIMIZATION
- const offs_t _A = A & AM;
- for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
+
+ if (A >= 0x80000000) // P1/P2/P3 region
{
- if (m_fastram[ramnum].readonly == true || _A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end)
+#if SH4_USE_FASTRAM_OPTIMIZATION
+ const offs_t _A = A & AM;
+ for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
{
- continue;
+ if (m_fastram[ramnum].readonly == true || _A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end)
+ {
+ continue;
+ }
+ uint8_t *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start;
+ fastbase[_A ^ m_byte_xor] = V;
+ return;
}
- uint8_t *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start;
- fastbase[_A ^ m_byte_xor] = V;
- return;
- }
- m_program->write_byte(_A,V);
+ m_program->write_byte(_A, V);
#else
- m_program->write_byte(A & AM,V);
+ m_program->write_byte(A & AM, V);
#endif
+ }
+ else
+ {
+ if (!m_sh4_mmu_enabled)
+ {
+ m_program->write_byte(A & AM, V);
+ }
+ else
+ {
+ A = get_remap(A & AM);
+ m_program->write_byte(A, V);
+ }
+ }
}
@@ -395,22 +457,38 @@ inline void sh34_base_device::WW(offs_t A, uint16_t V)
m_program->write_word(A,V);
return;
}
-#if SH4_USE_FASTRAM_OPTIMIZATION
- const offs_t _A = A & AM;
- for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
+
+ if (A >= 0x80000000) // P1/P2/P3 region
{
- if (m_fastram[ramnum].readonly == true || _A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end)
+#if SH4_USE_FASTRAM_OPTIMIZATION
+ const offs_t _A = A & AM;
+ for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
{
- continue;
+ if (m_fastram[ramnum].readonly == true || _A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end)
+ {
+ continue;
+ }
+ void *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start;
+ ((uint16_t*)fastbase)[(_A ^ m_word_xor) >> 1] = V;
+ return;
}
- void *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start;
- ((uint16_t*)fastbase)[(_A ^ m_word_xor) >> 1] = V;
- return;
- }
- m_program->write_word(_A,V);
+ m_program->write_word(_A, V);
#else
- m_program->write_word(A & AM,V);
+ m_program->write_word(A & AM, V);
#endif
+ }
+ else
+ {
+ if (!m_sh4_mmu_enabled)
+ {
+ m_program->write_word(A & AM, V);
+ }
+ else
+ {
+ A = get_remap(A & AM);
+ m_program->write_word(A, V);
+ }
+ }
}
@@ -421,22 +499,39 @@ inline void sh34_base_device::WL(offs_t A, uint32_t V)
m_program->write_dword(A,V);
return;
}
-#if SH4_USE_FASTRAM_OPTIMIZATION
- const offs_t _A = A & AM;
- for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
+
+ if (A >= 0x80000000) // P1/P2/P3 region
{
- if (m_fastram[ramnum].readonly == true || _A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end)
+#if SH4_USE_FASTRAM_OPTIMIZATION
+ const offs_t _A = A & AM;
+ for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
{
- continue;
+ if (m_fastram[ramnum].readonly == true || _A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end)
+ {
+ continue;
+ }
+ void *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start;
+ ((uint32_t*)fastbase)[(_A ^ m_dword_xor) >> 2] = V;
+ return;
}
- void *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start;
- ((uint32_t*)fastbase)[(_A ^ m_dword_xor) >> 2] = V;
- return;
- }
- m_program->write_dword(_A,V);
+ m_program->write_dword(_A, V);
#else
- m_program->write_dword(A & AM,V);
+ m_program->write_dword(A & AM, V);
#endif
+ }
+ else
+ {
+ if (!m_sh4_mmu_enabled)
+ {
+ m_program->write_dword(A & AM, V);
+ }
+ else
+ {
+ A = get_remap(A & AM);
+ m_program->write_dword(A, V);
+ }
+ }
+
}
/* code cycles t-bit
@@ -3974,7 +4069,10 @@ void sh34_base_device::execute_run()
m_ppc = m_pc & AM;
debugger_instruction_hook(this, m_pc & AM);
- const uint16_t opcode = m_direct->read_word(m_pc & AM, WORD2_XOR_LE(0));
+ uint16_t opcode;
+
+ if (!m_sh4_mmu_enabled) opcode = m_direct->read_word(m_pc & AM, WORD2_XOR_LE(0));
+ else opcode = RW(m_pc); // should probably use a different function as this needs to go through the ITLB
if (m_delay)
{
diff --git a/src/devices/cpu/sh4/sh4.h b/src/devices/cpu/sh4/sh4.h
index 2b9d10bfed4..0720ec9375d 100644
--- a/src/devices/cpu/sh4/sh4.h
+++ b/src/devices/cpu/sh4/sh4.h
@@ -190,6 +190,10 @@ typedef void (*sh4_ftcsr_callback)(uint32_t);
sh34_base_device::set_sh4_clock(*device, _clock);
+#define MCFG_MMU_HACK_TYPE(_hacktype) \
+ sh34_base_device::set_mmu_hacktype(*device, _hacktype);
+
+
class sh34_base_device : public cpu_device
{
public:
@@ -211,6 +215,8 @@ public:
static void set_md8(device_t &device, int md0) { downcast<sh34_base_device &>(device).c_md8 = md0; }
static void set_sh4_clock(device_t &device, int clock) { downcast<sh34_base_device &>(device).c_clock = clock; }
+ static void set_mmu_hacktype(device_t &device, int hacktype) { downcast<sh34_base_device &>(device).m_mmuhack = hacktype; }
+
TIMER_CALLBACK_MEMBER( sh4_refresh_timer_callback );
TIMER_CALLBACK_MEMBER( sh4_rtc_timer_callback );
TIMER_CALLBACK_MEMBER( sh4_timer_callback );
@@ -262,6 +268,9 @@ protected:
int c_md8;
int c_clock;
+ // hack 1 = Naomi hack, hack 2 = Work in Progress implementation
+ int m_mmuhack;
+
uint32_t m_ppc;
uint32_t m_pc;
uint32_t m_spc;
@@ -646,6 +655,7 @@ protected:
void increment_rtc_time(int mode);
void sh4_dmac_nmi();
void sh4_handler_ipra_w(uint32_t data, uint32_t mem_mask);
+ virtual uint32_t get_remap(uint32_t address);
virtual uint32_t sh4_getsqremap(uint32_t address);
void sh4_parse_configuration();
void sh4_timer_recompute(int which);
@@ -764,6 +774,7 @@ public:
virtual void LDTLB(const uint16_t opcode) override;
+ virtual uint32_t get_remap(uint32_t address) override;
virtual uint32_t sh4_getsqremap(uint32_t address) override;
sh4_utlb m_utlb[64];
diff --git a/src/devices/cpu/sh4/sh4comn.cpp b/src/devices/cpu/sh4/sh4comn.cpp
index f02c9f50242..dbb794e0c82 100644
--- a/src/devices/cpu/sh4/sh4comn.cpp
+++ b/src/devices/cpu/sh4/sh4comn.cpp
@@ -710,8 +710,19 @@ WRITE32_MEMBER( sh4_base_device::sh4_internal_w )
*/
break;
+ case TTB:
+ m_m[TTB] &= 0xffffffff;
+ logerror("TTB set to %08x\n", data);
+ break;
+
+ case TEA:
+ m_m[TEA] &= 0xffffffff;
+ logerror("TEA set to %08x\n", data);
+ break;
+
+
case MMUCR: // MMU Control
- logerror("MMUCR %08x\n", data);
+ logerror("%s: MMUCR %08x\n", machine().describe_context(), data);
m_m[MMUCR] &= 0xffffffff;
/*
LLLL LL-- BBBB BB-- CCCC CCQV ---- -T-A
@@ -729,12 +740,42 @@ WRITE32_MEMBER( sh4_base_device::sh4_internal_w )
if (data & MMUCR_AT)
{
- printf("SH4 MMU Enabled\n");
- printf("If you're seeing this, but running something other than a Naomi GD-ROM game then chances are it won't work\n");
- printf("The MMU emulation is a hack specific to that system\n");
m_sh4_mmu_enabled = 1;
+ if (m_mmuhack == 1)
+ {
+ printf("SH4 MMU Enabled\n");
+ printf("If you're seeing this, but running something other than a Naomi GD-ROM game then chances are it won't work\n");
+ printf("The MMU emulation is a hack specific to that system\n");
+ }
+
+
+ if (m_mmuhack == 2)
+ {
+ for (int i = 0;i < 64;i++)
+ {
+ if (m_utlb[i].V)
+ {
+ printf("(entry %02x | ASID: %02x VPN: %08x V: %02x PPN: %08x SZ: %02x SH: %02x C: %02x PPR: %02x D: %02x WT %02x: SA: %02x TC: %02x)\n",
+ i,
+ m_utlb[i].ASID,
+ m_utlb[i].VPN << 10,
+ m_utlb[i].V,
+ m_utlb[i].PPN << 10,
+ m_utlb[i].PSZ,
+ m_utlb[i].SH,
+ m_utlb[i].C,
+ m_utlb[i].PPR,
+ m_utlb[i].D,
+ m_utlb[i].WT,
+ m_utlb[i].SA,
+ m_utlb[i].TC);
+ }
+ }
+ }
+
+
}
else
{
@@ -1223,6 +1264,36 @@ void sh34_base_device::sh4_parse_configuration()
}
}
+uint32_t sh34_base_device::get_remap(uint32_t address)
+{
+ return address;
+}
+
+uint32_t sh4_base_device::get_remap(uint32_t address)
+{
+ if (m_mmuhack != 2)
+ return address;
+
+ // is this the correct way around?
+ int i;
+ uint32_t topaddr = address&0xfff00000;
+
+ for (i=0;i<64;i++)
+ {
+ if (m_utlb[i].V)
+ {
+ uint32_t topcmp = (m_utlb[i].PPN << 10) & 0xfff00000;
+ if (topcmp == topaddr)
+ return (address & 0x000fffff) | ((m_utlb[i].VPN << 10) & 0xfff00000);
+ }
+ }
+
+ //printf("address not in UTLB? %08x\n", address);
+
+
+ return address;
+}
+
uint32_t sh34_base_device::sh4_getsqremap(uint32_t address)
{
return address;
@@ -1230,7 +1301,7 @@ uint32_t sh34_base_device::sh4_getsqremap(uint32_t address)
uint32_t sh4_base_device::sh4_getsqremap(uint32_t address)
{
- if (!m_sh4_mmu_enabled)
+ if (!m_sh4_mmu_enabled || (m_mmuhack != 1))
return address;
else
{
@@ -1243,7 +1314,6 @@ uint32_t sh4_base_device::sh4_getsqremap(uint32_t address)
if (topcmp==topaddr)
return (address&0x000fffff) | ((m_utlb[i].PPN<<10)&0xfff00000);
}
-
}
return address;
@@ -1258,7 +1328,7 @@ WRITE64_MEMBER( sh4_base_device::sh4_utlb_address_array_w )
NNNN NNNN NNNN NNNN NNNN NNDV AAAA AAAA
- N = VPM = Virtual Page Number
+ N = VPN = Virtual Page Number
D = Dirty Bit
V = Validity Bit
A = ASID = Address Space Identifier
diff --git a/src/mame/drivers/aristmk6.cpp b/src/mame/drivers/aristmk6.cpp
index e732b7b7318..75e9eade880 100644
--- a/src/mame/drivers/aristmk6.cpp
+++ b/src/mame/drivers/aristmk6.cpp
@@ -246,6 +246,7 @@ static MACHINE_CONFIG_START( aristmk6, aristmk6_state )
MCFG_SH4_CLOCK(ARISTMK6_CPU_CLOCK)
MCFG_CPU_PROGRAM_MAP(aristmk6_map)
MCFG_CPU_IO_MAP(aristmk6_port)
+ MCFG_MMU_HACK_TYPE(2)
// MCFG_DEVICE_DISABLE()
MCFG_DEVICE_ADD( "uart0", NS16550, XTAL_8MHz )