]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
68030 MMU prefetch hack fix, 68030 data cache fix.
authorToni Wilen <twilen@winuae.net>
Tue, 2 Jun 2015 17:08:12 +0000 (20:08 +0300)
committerToni Wilen <twilen@winuae.net>
Tue, 2 Jun 2015 17:08:12 +0000 (20:08 +0300)
cpummu30.cpp
include/cpummu030.h
newcpu.cpp

index 9e2c60a6747507081861763edcdae2f667559bc6..eb5d1e99ae5901c8e5528f2748d0bb941b63a111 100644 (file)
@@ -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"),
index 577f5ab35f7a98f6aadd15219898f86fd0ed536a..9eaebd82b15af0fc5e729b10c89226140aae11fe 100644 (file)
@@ -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];
index 8572ce7804625681dcf4c74e81b0aea4213b25f3..8cc27f9653e5bd7187d7a913217c82a053364fa3 100644 (file)
@@ -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?