diff options
| author | 2016-11-23 23:04:34 -0500 | |
|---|---|---|
| committer | 2016-11-23 23:04:34 -0500 | |
| commit | b78109fea686979c5fe1d8d5f5d9243713e155ef (patch) | |
| tree | 8f7c9ee275ced9b24bd79b009d0857731bfcb9d5 /src | |
| parent | 4cb37e50fa32db1d03e68535e935c653e51c033e (diff) | |
| parent | 74289af32800ace3f46c2192f0dd7c259f81125c (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.cpp | 226 | ||||
| -rw-r--r-- | src/devices/cpu/sh4/sh4.h | 11 | ||||
| -rw-r--r-- | src/devices/cpu/sh4/sh4comn.cpp | 84 | ||||
| -rw-r--r-- | src/mame/drivers/aristmk6.cpp | 1 |
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 ) |
