From fc37ac35b01ad06ce55f830574eb4dde4764d756 Mon Sep 17 00:00:00 2001 From: mooglyguy Date: Sat, 29 Sep 2018 10:56:29 +0200 Subject: sun4c: More MMU fixes, makes SPARCstation SLC, IPX and 1+ happier, though not yet completely. [Ryan Holtz] --- src/devices/machine/sun4c_mmu.cpp | 50 ++++++++++++++++++++++++--------------- src/devices/machine/sun4c_mmu.h | 1 + src/mame/drivers/sun4.cpp | 4 ++++ 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/devices/machine/sun4c_mmu.cpp b/src/devices/machine/sun4c_mmu.cpp index ec226ebb9d5..64ec8c954c6 100644 --- a/src/devices/machine/sun4c_mmu.cpp +++ b/src/devices/machine/sun4c_mmu.cpp @@ -230,15 +230,15 @@ uint32_t sun4c_mmu_device::system_r(const uint32_t offset, const uint32_t mem_ma case 6: // bus error register { - //printf("sun4c_mmu: read buserror %08x, PC=%x (mask %08x)\n", 0x60000000 | (offset << 2), m_cpu->pc(), mem_mask); const uint32_t retval = m_buserr[offset & 0xf]; + //logerror("sun4c_mmu: read buserror %08x & %08x = %08x, PC=%x\n", 0x60000000 | (offset << 2), mem_mask, retval, m_cpu->pc()); m_buserr[offset & 0xf] = 0; // clear on reading return retval; } case 8: // (d-)cache tags //logerror("sun4_mmu: read dcache tags @ %x, PC = %x\n", offset, m_cpu->pc()); - return m_cachetags[(offset >> 3) & 0x3fff]; + return m_cachetags[offset & 0x3fff]; case 9: // (d-)cache data //logerror("sun4c_mmu: read dcache data @ %x, PC = %x\n", offset, m_cpu->pc()); @@ -255,7 +255,7 @@ uint32_t sun4c_mmu_device::system_r(const uint32_t offset, const uint32_t mem_ma case 0: // IDPROM - SPARCstation-1 does not have an ID prom and a timeout should occur. default: - logerror("%s: sun4c_mmu: ASI 2 space unhandled read @ %x\n", machine().describe_context(), offset<<2); + //logerror("%s: sun4c_mmu: ASI 2 space unhandled read @ %x\n", machine().describe_context(), offset<<2); return 0; } } @@ -269,6 +269,7 @@ void sun4c_mmu_device::system_w(const uint32_t offset, const uint32_t data, cons //printf("%08x to context, mask %08x, offset %x\n", data, mem_mask, offset); m_context = data >> 24; m_context_masked = m_context & m_ctx_mask; + m_cache_context = m_context & m_ctx_mask; m_curr_segmap = m_segmap[m_context_masked]; m_curr_segmap_masked = m_segmap_masked[m_context_masked]; return; @@ -295,22 +296,32 @@ void sun4c_mmu_device::system_w(const uint32_t offset, const uint32_t data, cons } case 6: // bus error - //logerror("%08x to bus error @ %x, mask %08x\n", data, offset, mem_mask); - m_buserr[offset & 0xf] = data; + { + const uint32_t masked_offset = offset & 0xf; + //logerror("%08x to bus error @ %x, mask %08x\n", data, offset << 2, mem_mask); + if (masked_offset == 0) + m_buserr[0] = (data & 0x000000ff) | 0x00008000; + else if (masked_offset == 1) + m_buserr[1] = data; + else if (masked_offset == 2) + m_buserr[2] = data & 0x000000b0; + else if (masked_offset == 3) + m_buserr[3] = (data & 0x3fffffff) | ((data & 0x20000000) << 1) | ((data & 0x20000000) << 2); return; + } case 8: // cache tags //logerror("sun4: %08x to cache tags @ %x, PC = %x\n", data, offset, m_cpu->pc()); - m_cachetags[(offset>>3)&0x3fff] = data & 0x03f8fffc; + m_cachetags[offset&0x3fff] = data & 0x03f8fffc; return; case 9: // cache data //logerror("sun4c: %08x to cache data @ %x, PC = %x\n", data, offset, m_cpu->pc()); - m_cachedata[offset&0x3fff] = data; + m_cachedata[offset&0x3fff] = data | (1 << 19); return; case 0xf: // UART bypass - //printf("%08x to UART bypass @ %x, mask %08x\n", data, offset<<2, mem_mask); + logerror("%08x to UART bypass @ %x, mask %08x\n", data, offset<<2, mem_mask); switch (offset & 3) { case 0: if (mem_mask == 0xff000000) m_scc->cb_w(0, data>>24); else m_scc->db_w(0, data>>8); break; @@ -320,7 +331,7 @@ void sun4c_mmu_device::system_w(const uint32_t offset, const uint32_t data, cons case 0: // IDPROM default: - logerror("sun4c: ASI 2 space unhandled write %x @ %x (mask %08x, PC=%x, shift %x)\n", data, offset<<2, mem_mask, m_cpu->pc(), offset>>26); + //logerror("sun4c: ASI 2 space unhandled write %x @ %x (mask %08x, PC=%x, shift %x)\n", data, offset<<2, mem_mask, m_cpu->pc(), offset>>26); return; } } @@ -353,15 +364,16 @@ void sun4c_mmu_device::segment_map_w(const uint32_t offset, const uint32_t data, uint32_t sun4c_mmu_device::page_map_r(const uint32_t offset, const uint32_t mem_mask) { - //logerror("%s: page_map_r: %08x & %08x\n", machine().describe_context(), offset << 2, mem_mask); const uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> 10) & 0x3f); - return m_pagemap[page].to_uint(); + const uint32_t retval = m_pagemap[page].to_uint(); + logerror("%s: page_map_r: %08x (%x, %x) & %08x = %08x\n", machine().describe_context(), offset << 2, page, (m_curr_segmap[(offset >> 16) & 0xfff] << 6) | ((offset >> 10) & 0x3f), mem_mask, retval); + return retval; } void sun4c_mmu_device::page_map_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask) { - //logerror("%s: page_map_w: %08x = %08x & %08x\n", machine().describe_context(), offset << 2, data, mem_mask); - const uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> 10) & 0x3f); + uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> 10) & 0x3f); + logerror("%s: page_map_w: %08x (%x, %x) = %08x & %08x\n", machine().describe_context(), offset << 2, page, (m_curr_segmap[(offset >> 16) & 0xfff] << 6) | ((offset >> 10) & 0x3f), data, mem_mask); m_pagemap[page].merge_uint(data, mem_mask); m_page_valid[page] = m_pagemap[page].valid; } @@ -413,7 +425,7 @@ uint32_t sun4c_mmu_device::insn_data_r(const uint32_t offset, const uint32_t mem } // it's translation time - const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff]; + const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];// & m_pmeg_mask; const uint32_t entry_index = pmeg | ((offset >> 10) & 0x3f); if (m_page_valid[entry_index]) @@ -447,7 +459,7 @@ uint32_t sun4c_mmu_device::insn_data_r(const uint32_t offset, const uint32_t mem return m_type1_r(tmp, mem_mask); default: - //logerror("sun4c_mmu: access to memory type not defined in sun4c\n"); + //logerror("sun4c_mmu: read from to memory type not defined in sun4c, %d, %08x & %08x\n", entry.type, tmp << 2, mem_mask); m_host->set_mae(); m_buserr[0] = 0x20; m_buserr[1] = offset << 2; @@ -458,7 +470,7 @@ uint32_t sun4c_mmu_device::insn_data_r(const uint32_t offset, const uint32_t mem { if (!machine().side_effects_disabled()) { - //logerror("sun4c: INVALID PTE entry %d %08x accessed! vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint(), offset <<2, m_cpu->pc()); + //logerror("sun4c: INVALID PTE entry %d %08x read! vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint(), offset << 2, m_cpu->pc()); m_host->set_mae(); m_buserr[0] |= 0x80; // invalid PTE m_buserr[0] &= ~0x8000; // read @@ -492,7 +504,7 @@ template void sun4c_mmu_device::insn_data_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask) { // it's translation time - const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff]; + const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];// & m_pmeg_mask; const uint32_t entry_index = pmeg | ((offset >> 10) & 0x3f); if (m_page_valid[entry_index]) @@ -537,7 +549,7 @@ void sun4c_mmu_device::insn_data_w(const uint32_t offset, const uint32_t data, c return; default: - //logerror("sun4c_mmu: access to memory type not defined\n"); + //logerror("sun4c_mmu: access to memory type not defined, %d %08x = %08x & %08x\n", entry.type, tmp, data, mem_mask); m_host->set_mae(); m_buserr[0] = 0x8020; m_buserr[1] = offset << 2; @@ -546,7 +558,7 @@ void sun4c_mmu_device::insn_data_w(const uint32_t offset, const uint32_t data, c } else { - //logerror("sun4c: INVALID PTE entry %d %08x accessed! data=%08x vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint(), data, offset <<2, m_cpu->pc()); + //logerror("sun4c: INVALID PTE entry %d %08x written! data=%08x vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint(), data, offset << 2, m_cpu->pc()); m_host->set_mae(); m_buserr[0] |= 0x8080; // write cycle, invalid PTE m_buserr[1] = offset << 2; diff --git a/src/devices/machine/sun4c_mmu.h b/src/devices/machine/sun4c_mmu.h index 5e81c3e0ce7..9852013504d 100644 --- a/src/devices/machine/sun4c_mmu.h +++ b/src/devices/machine/sun4c_mmu.h @@ -131,6 +131,7 @@ protected: uint32_t m_ram_size_words; uint32_t m_context; uint32_t m_context_masked; + uint32_t m_cache_context; uint8_t m_system_enable; bool m_fetch_bootrom; uint32_t m_buserr[4]; diff --git a/src/mame/drivers/sun4.cpp b/src/mame/drivers/sun4.cpp index a1978277b0f..c083c5b5ac9 100644 --- a/src/mame/drivers/sun4.cpp +++ b/src/mame/drivers/sun4.cpp @@ -2048,6 +2048,9 @@ void sun4_state::sun4_50(machine_config &config) { sun4c(config); + m_mmu->set_ctx_mask(0xf); + m_mmu->set_pmeg_mask(0xff); + m_mmu->set_clock(40'000'000); m_maincpu->set_clock(40'000'000); @@ -2075,6 +2078,7 @@ void sun4_state::sun4_65(machine_config &config) m_sbus_slot[0]->set_clock(25'000'000); m_sbus_slot[1]->set_clock(25'000'000); m_sbus_slot[2]->set_clock(25'000'000); + m_sbus_slot[2]->set_default_option("bwtwo"); } void sun4_state::sun4_75(machine_config &config) -- cgit v1.2.3