mirror of
https://github.com/holub/mame
synced 2025-04-24 09:20:02 +03:00
allow experimental SH4 MMU test code to be turned on / off on a per-driver basis.
what it uploads looks ok (basic remaps, 1meg page sizes etc.) but then the code doesn't seem to play nice.
This commit is contained in:
parent
c4e5cfff15
commit
74289af328
@ -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)
|
||||
{
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 )
|
||||
|
Loading…
Reference in New Issue
Block a user