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:
David Haywood 2016-11-24 00:57:57 +00:00
parent c4e5cfff15
commit 74289af328
4 changed files with 251 additions and 71 deletions

View File

@ -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)
{

View File

@ -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];

View File

@ -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

View File

@ -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 )