]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Simple prefetch emulation when 68030 MMU is switched on or off. Some programs switch...
authorToni Wilen <twilen@winuae.net>
Mon, 5 Jan 2015 11:32:41 +0000 (13:32 +0200)
committerToni Wilen <twilen@winuae.net>
Mon, 5 Jan 2015 11:32:41 +0000 (13:32 +0200)
cpummu30.cpp
include/cpummu030.h
newcpu.cpp

index 7f204164e28dc775c7950b894debc4ef88aae768..66a1594cc4458aa18864f5b3b818befa174bed4e 100644 (file)
@@ -60,6 +60,7 @@ uae_u32 mm030_stageb_address;
 bool mmu030_retry;
 int mmu030_opcode;
 int mmu030_opcode_stageb;
+int mmu030_fake_prefetch;
 uae_u16 mmu030_state[3];
 uae_u32 mmu030_data_buffer;
 uae_u32 mmu030_disp_store[2];
@@ -709,15 +710,35 @@ int mmu030_do_match_lrmw_ttr(uae_u32 tt, TT_info comp, uaecptr addr, uae_u32 fc)
 #define TC_TIC_MASK             0x000000F0
 #define TC_TID_MASK             0x0000000F
 
+static void mmu030_do_fake_prefetch(void)
+{
+       uaecptr pc = m68k_getpci();
+       // fetch next opcode before MMU state switches.
+       // There are programs that do following:
+       // - enable MMU
+       // - JMP (An)
+       // "enable MMU" unmaps memory under us.
+       TRY (prb) {
+               mmu030_fake_prefetch = x_prefetch(0);
+       } CATCH (prb) {
+               // 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) {
-        
+bool mmu030_decode_tc(uae_u32 TC)
+{
     /* Set MMU condition */    
     if (TC & TC_ENABLE_TRANSLATION) {
+               if (!mmu030.enabled)
+                       mmu030_do_fake_prefetch();
         mmu030.enabled = true;
     } else {
-               if (mmu030.enabled)
+               if (mmu030.enabled) {
+                       mmu030_do_fake_prefetch();
                        write_log(_T("MMU disabled\n"));
+               }
         mmu030.enabled = false;
         return false;
     }
@@ -1957,8 +1978,7 @@ uae_u16 mmu030_get_iword(uaecptr addr, uae_u32 fc) {
 
        if (atc_line_num >= 0) {
                return mmu030_get_iword_atc(addr, atc_line_num, fc);
-       }
-       else {
+       } else {
                mmu030_table_search(addr, fc, false, 0);
                return mmu030_get_iword_atc(addr, mmu030_logical_is_in_atc(addr, fc, false), fc);
        }
@@ -2288,6 +2308,13 @@ void mmu030_reset(int hardreset)
         mmusr_030 = 0;
         mmu030_flush_atc_all();
        }
+       mmu030_set_funcs();
+}
+
+void mmu030_set_funcs(void)
+{
+       if (currprefs.mmu_model != 68030)
+               return;
        if (currprefs.cpu_cycle_exact || currprefs.cpu_compatible) {
                x_phys_get_iword = get_word_icache030;
                x_phys_get_ilong = get_long_icache030;
index 9136bcafaf6f69541417b23509e167d3bb47c48c..577f5ab35f7a98f6aadd15219898f86fd0ed536a 100644 (file)
@@ -11,7 +11,7 @@ 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;
+extern int mmu030_opcode, mmu030_opcode_stageb, mmu030_fake_prefetch;
 extern uae_u16 mmu030_state[3];
 extern uae_u32 mmu030_data_buffer;
 extern uae_u32 mmu030_disp_store[2];
@@ -74,6 +74,7 @@ void mmu030_flush_atc_page(uaecptr logical_addr);
 void mmu030_flush_atc_page_fc(uaecptr logical_addr, uae_u32 fc_base, uae_u32 fc_mask);
 void mmu030_flush_atc_all(void);
 void mmu030_reset(int hardreset);
+void mmu030_set_funcs(void);
 uaecptr mmu030_translate(uaecptr addr, bool super, bool data, bool write);
 
 int mmu030_match_ttr(uaecptr addr, uae_u32 fc, bool write);
index 86d51022e58a706e000d4f02c7eb174385b7e957..2676898da3fa4d0326e23fe64b8e3b62afd36dcb 100644 (file)
@@ -1016,6 +1016,7 @@ static void set_x_funcs (void)
        }
 
        set_x_cp_funcs();
+       mmu030_set_funcs();
 
 }
 
@@ -2460,7 +2461,7 @@ static void Exception_mmu (int nr, uaecptr oldpc)
                        Exception_build_stack_frame(oldpc, currpc, regs.mmu_fslw, nr, 0x4);
        } else if (nr == 3) { // address error
         Exception_build_stack_frame(last_fault_for_exception_3, currpc, 0, nr, 0x2);
-               write_log (_T("Exception %d (%x) at %x -> %x!\n"), nr, last_fault_for_exception_3, currpc, get_long (regs.vbr + 4 * nr));
+               write_log (_T("Exception %d (%x) at %x -> %x!\n"), nr, last_fault_for_exception_3, currpc, get_long_debug (regs.vbr + 4 * nr));
        } else if (nr == 5 || nr == 6 || nr == 7 || nr == 9) {
         Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0x2);
        } else if (regs.m && interrupt) { /* M + Interrupt */
@@ -3587,37 +3588,6 @@ isstopped:
                }
 #endif
 
-#if 0
-               if (!uae_int_requested && !uaenet_int_requested && currprefs.cpu_idle && currprefs.m68k_speed != 0 && (regs.spcflags & SPCFLAG_STOP)
-#ifdef WITH_PPC
-                       && ppc_state != PPC_STATE_ACTIVE
-#endif                 
-               ) {
-                       /* sleep 1ms if STOP-instruction is executed
-                        * but only if we have free frametime left to prevent slowdown
-                        */
-                       {
-                               static int sleepcnt, lvpos, zerocnt;
-                               if (vpos != lvpos) {
-                                       lvpos = vpos;
-                                       frame_time_t rpt = read_processor_time ();
-                                       if ((int)rpt - (int)vsyncmaxtime < 0) {
-                                               sleepcnt--;
-#if 0
-                                               if (pissoff == 0 && currprefs.cachesize && --zerocnt < 0) {
-                                                       sleepcnt = -1;
-                                                       zerocnt = IDLETIME / 4;
-                                               }
-#endif
-                                               if (sleepcnt < 0) {
-                                                       sleepcnt = IDLETIME / 2;
-                                                       cpu_sleep_millis(1);
-                                               }
-                                       }
-                               }
-                       }
-               }
-#endif
        }
 
        if (regs.spcflags & SPCFLAG_TRACE)
@@ -4229,6 +4199,7 @@ static void m68k_run_mmu030 (void)
        struct flag_struct f;
 
        mmu030_opcode_stageb = -1;
+       mmu030_fake_prefetch = -1;
 retry:
        TRY (prb) {
                for (;;) {
@@ -4240,8 +4211,11 @@ insretry:
 
                        mmu030_state[0] = mmu030_state[1] = mmu030_state[2] = 0;
                        mmu030_opcode = -1;
-                       if (mmu030_opcode_stageb < 0) {
-                               regs.opcode = get_iword_mmu030 (0);
+                       if (mmu030_fake_prefetch >= 0) {
+                               regs.opcode = mmu030_fake_prefetch;
+                               mmu030_fake_prefetch = -1;
+                       } else if (mmu030_opcode_stageb < 0) {
+                               regs.opcode = x_prefetch (0);
                        } else {
                                regs.opcode = mmu030_opcode_stageb;
                                mmu030_opcode_stageb = -1;
@@ -4257,6 +4231,7 @@ insretry:
                                count_instr (regs.opcode);
                                do_cycles (cpu_cycles);
                                mmu030_retry = false;
+
                                cpu_cycles = (*cpufunctbl[regs.opcode])(regs.opcode);
                                cnt--; // so that we don't get in infinite loop if things go horribly wrong
                                if (!mmu030_retry)
@@ -4375,8 +4350,8 @@ retry:
                goto retry;
        } ENDTRY
 }
-/* "cycle exact" 68020/030  */
 
+/* "cycle exact" 68020/030  */
 
 static void m68k_run_2ce (void)
 {