From 3ccf4cba7536a7b1ff10546611785153bef2a857 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Tue, 2 Jun 2015 20:08:12 +0300 Subject: [PATCH] 68030 MMU prefetch hack fix, 68030 data cache fix. --- cpummu30.cpp | 11 ++++++++--- include/cpummu030.h | 4 +++- newcpu.cpp | 34 ++++++++++++++++++++++++---------- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/cpummu30.cpp b/cpummu30.cpp index 9e2c60a6..eb5d1e99 100644 --- a/cpummu30.cpp +++ b/cpummu30.cpp @@ -60,7 +60,10 @@ uae_u32 mm030_stageb_address; bool mmu030_retry; int mmu030_opcode; int mmu030_opcode_stageb; + int mmu030_fake_prefetch; +uaecptr mmu030_fake_prefetch_addr; + uae_u16 mmu030_state[3]; uae_u32 mmu030_data_buffer; uae_u32 mmu030_disp_store[2]; @@ -718,6 +721,9 @@ static void mmu030_do_fake_prefetch(void) // - JMP (An) // "enable MMU" unmaps memory under us. TRY (prb) { + uaecptr pc = m68k_getpci(); + mmu030_fake_prefetch = -1; + mmu030_fake_prefetch_addr = mmu030_translate(pc, regs.s != 0, false, false); mmu030_fake_prefetch = x_prefetch(0); // A26x0 ROM code switches off rom // NOP @@ -728,7 +734,6 @@ static void mmu030_do_fake_prefetch(void) // didn't work, oh well.. mmu030_fake_prefetch = -1; } ENDTRY - write_log(_T("MMU030 fake prefetched %04X\n"), mmu030_fake_prefetch); } bool mmu030_decode_tc(uae_u32 TC) @@ -741,7 +746,7 @@ bool mmu030_decode_tc(uae_u32 TC) } else { if (mmu030.enabled) { mmu030_do_fake_prefetch(); - write_log(_T("MMU disabled\n")); + write_log(_T("MMU disabled PC=%08x\n"), M68K_GETPC); } mmu030.enabled = false; return false; @@ -764,7 +769,7 @@ bool mmu030_decode_tc(uae_u32 TC) regs.mmu_page_size = 1 << mmu030.translation.page.size; - write_log(_T("68030 MMU enabled. Page size = %d\n"), regs.mmu_page_size); + write_log(_T("68030 MMU enabled. Page size = %d PC=%08x\n"), regs.mmu_page_size, M68K_GETPC); if (mmu030.translation.page.size<8) { write_log(_T("MMU Configuration Exception: Bad value in TC register! (bad page size: %i byte)\n"), diff --git a/include/cpummu030.h b/include/cpummu030.h index 577f5ab3..9eaebd82 100644 --- a/include/cpummu030.h +++ b/include/cpummu030.h @@ -11,7 +11,9 @@ extern uae_u16 mmusr_030; extern uae_u32 mm030_stageb_address; extern int mmu030_idx; extern bool mmu030_retry; -extern int mmu030_opcode, mmu030_opcode_stageb, mmu030_fake_prefetch; +extern int mmu030_opcode, mmu030_opcode_stageb; +extern int mmu030_fake_prefetch; +extern uaecptr mmu030_fake_prefetch_addr; extern uae_u16 mmu030_state[3]; extern uae_u32 mmu030_data_buffer; extern uae_u32 mmu030_disp_store[2]; diff --git a/newcpu.cpp b/newcpu.cpp index 8572ce78..8cc27f96 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -4267,7 +4267,19 @@ insretry: mmu030_state[0] = mmu030_state[1] = mmu030_state[2] = 0; mmu030_opcode = -1; if (mmu030_fake_prefetch >= 0) { - regs.opcode = mmu030_fake_prefetch; + // use fake prefetch opcode only if mapping changed + uaecptr new_addr = mmu030_translate(regs.instruction_pc, regs.s != 0, false, false); + if (mmu030_fake_prefetch_addr != new_addr) { + regs.opcode = mmu030_fake_prefetch; + write_log(_T("MMU030 fake prefetch remap: %04x, %08x -> %08x\n"), mmu030_fake_prefetch, mmu030_fake_prefetch_addr, new_addr); + } else { + if (mmu030_opcode_stageb < 0) { + regs.opcode = x_prefetch (0); + } else { + regs.opcode = mmu030_opcode_stageb; + mmu030_opcode_stageb = -1; + } + } mmu030_fake_prefetch = -1; } else if (mmu030_opcode_stageb < 0) { regs.opcode = x_prefetch (0); @@ -6759,16 +6771,18 @@ uae_u32 read_dcache030 (uaecptr addr, int size) if (!c1->valid[lws1] || c1->tag != tag1) { v1 = currprefs.cpu_cycle_exact ? mem_access_delay_long_read_ce020 (addr) : get_long (addr); update_cache030 (c1, v1, tag1, lws1); - } else if (uae_boot_rom_type > 0) { - // this check and fix is needed for UAE filesystem handler because it runs in host side and in - // separate thread. No way to access via cache without locking that would cause major slowdown - // and unneeded complexity - uae_u32 tv = get_long (addr); + } else { + uae_u32 tv = get_long(addr); v1 = c1->data[lws1]; - if (tv != v1) { - write_log (_T("data cache mismatch %d %d %08x %08x != %08x %08x %d PC=%08x\n"), - size, aligned, addr, tv, v1, tag1, lws1, M68K_GETPC); - v1 = get_long (addr); + if (uae_boot_rom_type > 0) { + // this check and fix is needed for UAE filesystem handler because it runs in host side and in + // separate thread. No way to access via cache without locking that would cause major slowdown + // and unneeded complexity + if (tv != v1) { + write_log(_T("data cache mismatch %d %d %08x %08x != %08x %08x %d PC=%08x\n"), + size, aligned, addr, tv, v1, tag1, lws1, M68K_GETPC); + v1 = get_long(addr); + } } } // only one long fetch needed? -- 2.47.3