]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
68020/030 prefetch and MMU tweaks.
authorToni Wilen <twilen@winuae.net>
Mon, 8 Jun 2020 17:54:03 +0000 (20:54 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 8 Jun 2020 17:54:03 +0000 (20:54 +0300)
cpummu30.cpp
gencpu.cpp
include/cpummu030.h
include/newcpu.h
newcpu.cpp
newcpu_common.cpp

index 96d14ae53a8a9e4038b385109e780de8fd5d2754..e4019a8ef7c833c812d74100f0f63035a534eaea 100644 (file)
 #include "cpummu030.h"
 #include "cputbl.h"
 
+// Prefetch mode and prefetch bus error: always flush and refill prefetch pipeline
+#define MMU030_ALWAYS_FULL_PREFETCH 1
+ // if CPU is 68030 and faulted access' addressing mode was -(an) or (an)+
+// register content is not restored when exception starts.
+#define MMU030_REG_FIXUP 1
+
 #define MMU030_OP_DBG_MSG 0
 #define MMU030_ATC_DBG_MSG 0
 #define MMU030_REG_DBG_MSG 0
@@ -91,7 +97,7 @@ static struct mmufastcache030 atc_data_cache_write[MMUFASTCACHE_ENTRIES030];
 #endif
 
 /* for debugging messages */
-char table_letter[4] = {'A','B','C','D'};
+static char table_letter[4] = {'A','B','C','D'};
 
 static const uae_u32 mmu030_size[3] = { MMU030_SSW_SIZE_B, MMU030_SSW_SIZE_W, MMU030_SSW_SIZE_L };
 
@@ -514,7 +520,7 @@ static bool mmu_op30_pload (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr ex
        if (!mmu_op30_helper_get_fc(next, &fc))
                return true;
 
-#if 0
+#if MMU030_OP_DBG_MSG
     write_log (_T("PLOAD%c: Create ATC entry for %08X, FC = %i\n"), write?'W':'R', extra, fc);
 #endif
 
@@ -530,7 +536,7 @@ bool mmu_op30_pflush (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra)
        uae_u32 fc_base;
        uae_u32 fc_bits = next & 0x7f;
     
-#if 0
+#if MMU030_OP_DBG_MSG
     switch (mode) {
         case 0x1:
             write_log(_T("PFLUSH: Flush all entries\n"));
@@ -623,8 +629,8 @@ TT_info mmu030_decode_tt(uae_u32 TT) {
     ret.fc_base = (TT&TT_FC_BASE)>>4;
     ret.addr_base = TT & TT_ADDR_BASE;
     ret.addr_mask = ~(((TT&TT_ADDR_MASK)<<8)|0x00FFFFFF);
-    
-#if 0
+   
+#if MMU030_OP_DBG_MSG
     if ((TT&TT_ENABLE) && !(TT&TT_RWM)) {
         write_log(_T("MMU Warning: Transparent translation of read-modify-write cycle is not correctly handled!\n"));
     }
@@ -1035,7 +1041,7 @@ static void mmu030_atc_handle_history_bit(int entry_num) {
             mmu030.atc[j].mru = 0;
         }
         mmu030.atc[entry_num].mru = 1;
-#if MMU030_ATC_DBG_MSG
+#if MMU030_ATC_DBG_MSG > 1
         write_log(_T("ATC: No more history zero-bits. Reset all.\n"));
 #endif
        }
@@ -1256,13 +1262,13 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
         if ((tc_030&TC_ENABLE_SUPERVISOR) && super) {
             descr[0] = (srp_030>>32)&0xFFFFFFFF;
             descr[1] = srp_030&0xFFFFFFFF;
-#if MMU030_REG_DBG_MSG
+#if MMU030_REG_DBG_MSG > 2
             write_log(_T("Supervisor Root Pointer: %08X%08X\n"),descr[0],descr[1]);
 #endif // MMU030_REG_DBG_MSG
         } else {
             descr[0] = (crp_030>>32)&0xFFFFFFFF;
             descr[1] = crp_030&0xFFFFFFFF;
-#if MMU030_REG_DBG_MSG
+#if MMU030_REG_DBG_MSG > 2
             write_log(_T("CPU Root Pointer: %08X%08X\n"),descr[0],descr[1]);
 #endif
                }
@@ -1310,12 +1316,12 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
             
             if (next_size==4) {
                 descr[0] = desc_get_long(descr_addr[descr_num]);
-#if MMU030_REG_DBG_MSG
+#if MMU030_REG_DBG_MSG > 2
                 write_log(_T("Next descriptor: %08X\n"),descr[0]);
 #endif
             } else {
                                desc_get_quad(descr_addr[descr_num], descr);
-#if MMU030_REG_DBG_MSG
+#if MMU030_REG_DBG_MSG > 2
                 write_log(_T("Next descriptor: %08X%08X\n"),descr[0],descr[1]);
 #endif
             }
@@ -1331,7 +1337,7 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
                     mmu030.status |= MMUSR_INVALID;
                     goto stop_search;
                 case DESCR_TYPE_EARLY_TERM:
-#if MMU030_REG_DBG_MSG
+#if MMU030_REG_DBG_MSG > 2
                     write_log(_T("Early termination page descriptor!\n"));
 #endif
                                        early_termination = true;
@@ -1376,7 +1382,7 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
             addr_position = (descr_size==4) ? 0 : 1;
             table_addr = descr[addr_position]&DESCR_TD_ADDR_MASK;
             table_index = (addr&mmu030.translation.table[t].mask)>>mmu030.translation.table[t].shift;
-#if MMU030_REG_DBG_MSG
+#if MMU030_REG_DBG_MSG > 2
             write_log(_T("Table %c at %08X: index = %i, "),table_letter[t],table_addr,table_index);
 #endif // MMU030_REG_DBG_MSG
             t++; /* Proceed to the next table */
@@ -1406,12 +1412,12 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
             
             if (next_size==4) {
                 descr[0] = desc_get_long(descr_addr[descr_num]);
-#if MMU030_REG_DBG_MSG
+#if MMU030_REG_DBG_MSG > 2
                 write_log(_T("Next descriptor: %08X\n"),descr[0]);
 #endif
             } else {
                                desc_get_quad(descr_addr[descr_num], descr);
-#if MMU030_REG_DBG_MSG
+#if MMU030_REG_DBG_MSG > 2
                 write_log(_T("Next descriptor: %08X%08X\n"),descr[0],descr[1]);
 #endif
             }
@@ -1431,7 +1437,7 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
                 case DESCR_TYPE_EARLY_TERM:
                     /* go to last level table handling code */
                     if (t<=mmu030.translation.last_table) {
-#if MMU030_REG_DBG_MSG
+#if MMU030_REG_DBG_MSG > 2
                         write_log(_T("Early termination page descriptor!\n"));
 #endif
                                                early_termination = true;
@@ -1456,7 +1462,7 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
         
         addr_position = (descr_size==4) ? 0 : 1;
         indirect_addr = descr[addr_position]&DESCR_ID_ADDR_MASK;
-#if MMU030_REG_DBG_MSG
+#if MMU030_REG_DBG_MSG > 2
         write_log(_T("Page indirect descriptor at %08X: "),indirect_addr);
 #endif
 
@@ -1466,12 +1472,12 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
         
         if (next_size==4) {
             descr[0] = desc_get_long(descr_addr[descr_num]);
-#if MMU030_REG_DBG_MSG
+#if MMU030_REG_DBG_MSG > 2
             write_log(_T("descr = %08X\n"),descr[0]);
 #endif
                } else {
                        desc_get_quad(descr_addr[descr_num], descr);
-#if MMU030_REG_DBG_MSG
+#if MMU030_REG_DBG_MSG > 2
             write_log(_T("descr = %08X%08X"),descr[0],descr[1]);
 #endif
                }
@@ -1557,7 +1563,7 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
                 t++;
             } while (t<=mmu030.translation.last_table);
             page_addr = addr&unused_fields_mask;
-#if MMU030_REG_DBG_MSG
+#if MMU030_REG_DBG_MSG > 1
             write_log(_T("Logical address unused bits: %08X (mask = %08X)\n"),
                       page_addr,unused_fields_mask);
 #endif
@@ -1566,7 +1572,7 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
         /* Get page address */
         addr_position = (descr_size==4) ? 0 : 1;
         page_addr += (descr[addr_position]&DESCR_PD_ADDR_MASK);
-#if MMU030_REG_DBG_MSG
+#if MMU030_REG_DBG_MSG > 2
         write_log(_T("Page at %08X\n"),page_addr);
 #endif // MMU030_REG_DBG_MSG
         
@@ -1610,7 +1616,7 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
                 break;
             }
         }
-#if MMU030_REG_DBG_MSG
+#if MMU030_REG_DBG_MSG > 2
         write_log(_T("ATC is full. Replacing entry %i\n"), i);
 #endif
        }
@@ -1637,7 +1643,7 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
 
        mmu030_flush_cache(mmu030.atc[i].logical.addr);
 
-#if MMU030_ATC_DBG_MSG    
+#if MMU030_ATC_DBG_MSG > 1
     write_log(_T("ATC create entry(%i): logical = %08X, physical = %08X, FC = %i\n"), i,
               mmu030.atc[i].logical.addr, mmu030.atc[i].physical.addr,
               mmu030.atc[i].logical.fc);
@@ -1758,16 +1764,15 @@ static void dump_opcode(uae_u16 opcode)
                break;
                }
        }
-       write_log(_T("%04x %s.%c"), opcode, lookup->name, size);
+       write_log(_T(" %04x %s.%c"), opcode, lookup->name, size);
 }
 #endif
 
-// if CPU is 68030 and faulted access' addressing mode was -(an) or (an)+
-// register content is not restored when exception starts.
 static uae_u8 mmu030fixupreg(int i)
 {
-       struct mmufixup *m = &mmufixup[i];
        uae_u8 v = 0;
+#if MMU030_REG_FIXUP
+       struct mmufixup *m = &mmufixup[i];
        if (m->reg < 0)
                return v;
        if (!(m->reg & 0x300))
@@ -1777,11 +1782,13 @@ static uae_u8 mmu030fixupreg(int i)
        if (m->reg & 0x200) // -(an)?
                v |= 1 << 5;
        v |= 1 << 6;
+#endif
        return v;
 }
 
 static void mmu030fixupmod(uae_u8 data, int dir, int idx)
 {
+#if MMU030_REG_FIXUP
        if (!data)
                return;
        int reg = data & 7;
@@ -1794,6 +1801,8 @@ static void mmu030fixupmod(uae_u8 data, int dir, int idx)
                struct mmufixup *m = &mmufixup[idx];
                m->value += adj;
        }
+       write_log("fixup %04x %d %d\n", mmu030_opcode & 0xffff, reg, adj);
+#endif
 }
 
 void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc)
@@ -1805,7 +1814,6 @@ void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc)
        }
        regs.wb3_status = 0;
        regs.wb2_status = 0;
-       regs.mmu_fault_addr = addr;
        if (fc & 1) {
                regs.mmu_ssw = MMU030_SSW_DF | (MMU030_SSW_DF << 1);
                if (!(mmu030_state[1] & MMU030_STATEFLAG1_LASTWRITE)) {
@@ -1815,20 +1823,14 @@ void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc)
                        mmu030fixupmod(regs.wb3_status, 0, 1);
                }
        } else {
+               // only used by data fault but word sounds nice
+               flags = MMU030_SSW_SIZE_W;
                if (currprefs.cpu_compatible) {
                        regs.wb2_status = mmu030fixupreg(0);
                        mmu030fixupmod(regs.wb2_status, 0, 0);
                        regs.wb3_status = mmu030fixupreg(1);
                        mmu030fixupmod(regs.wb3_status, 0, 1);
-                       if (regs.prefetch020_valid[1] != 1 && regs.prefetch020_valid[2] == 1) {
-                               regs.mmu_ssw = MMU030_SSW_FC | MMU030_SSW_RC;
-                       } else if (regs.prefetch020_valid[2] != 1) {
-                               regs.mmu_ssw = MMU030_SSW_FB | MMU030_SSW_RB;
-                       } else {
-                               // This happens when CPU prefetches from page
-                               // end - 4 and both pages are originally invalid.
-                               regs.mmu_ssw = MMU030_SSW_FC | MMU030_SSW_RC;
-                       }
+                       regs.mmu_ssw = MMU030_SSW_FB | MMU030_SSW_RB;
                } else {
                        regs.mmu_ssw = MMU030_SSW_FB | MMU030_SSW_RB;
                }
@@ -1837,6 +1839,7 @@ void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc)
        regs.mmu_ssw |= flags;
        regs.mmu_ssw |= fc;
        regs.mmu_ssw |= islrmw030 ? MMU030_SSW_RM : 0;
+       regs.mmu_fault_addr = addr;
        // temporary store in 68040+ variables because stack frame creation may modify them.
        regs.wb3_data = mmu030_data_buffer_out;
        regs.wb2_address = mmu030_state[1];
@@ -1844,21 +1847,19 @@ void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc)
        mm030_stageb_address = addr;
 
 #if MMUDEBUG
-       write_log(_T("MMU: %02x la=%08X SSW=%04x read=%d size=%d fc=%d pc=%08x ob=%08x "),
+       write_log(_T("MMU: %02x la=%08X SSW=%04x read=%d size=%d fc=%d pc=%08x ob=%08x"),
                (mmu030_state[1] & MMU030_STATEFLAG1_LASTWRITE) ? 0xa : 0xb,
                addr, regs.mmu_ssw, read, (flags & MMU030_SSW_SIZE_B) ? 1 : (flags & MMU030_SSW_SIZE_W) ? 2 : 4, fc,
-               regs.instruction_pc, mmu030_data_buffer_out, mmu030_opcode & 0xffff);
+               regs.instruction_pc, mmu030_data_buffer_out);
        dump_opcode(mmu030_opcode & 0xffff);
+       if (regs.opcode != mmu030_opcode)
+               dump_opcode(regs.opcode & 0xffff);
        write_log(_T("\n"));
 #endif
 
        ismoves030 = false;
        islrmw030 = false;
 
-#if 0
-       if (addr == 0xc1026ea0)
-               write_log("!");
-#endif
 #if 0
        if (mmu030_state[1] & MMU030_STATEFLAG1_SUBACCESS0)
                write_log("!");
@@ -1927,7 +1928,7 @@ static uaecptr mmu030_put_atc(uaecptr addr, int l, uae_u32 fc, uae_u32 size) {
     uae_u32 addr_mask = mmu030.translation.page.imask;
     uae_u32 physical_addr = mmu030.atc[l].physical.addr&addr_mask;
 
-#if MMU030_ATC_DBG_MSG
+#if MMU030_ATC_DBG_MSG > 1
     write_log(_T("ATC match(%i): page addr = %08X, index = %08X\n"),
               l, physical_addr, page_index);
 #endif
@@ -1949,7 +1950,7 @@ static uaecptr mmu030_get_atc(uaecptr addr, int l, uae_u32 fc, uae_u32 size) {
     uae_u32 addr_mask = mmu030.translation.page.imask;
     uae_u32 physical_addr = mmu030.atc[l].physical.addr&addr_mask;
 
-#if MMU030_ATC_DBG_MSG
+#if MMU030_ATC_DBG_MSG > 1
     write_log(_T("ATC match(%i): page addr = %08X, index = %08X\n"), l,
               physical_addr, page_index);
 #endif
@@ -1971,7 +1972,7 @@ static uaecptr mmu030_get_i_atc(uaecptr addr, int l, uae_u32 fc, uae_u32 size) {
        uae_u32 addr_mask = mmu030.translation.page.imask;
        uae_u32 physical_addr = mmu030.atc[l].physical.addr&addr_mask;
 
-#if MMU030_ATC_DBG_MSG
+#if MMU030_ATC_DBG_MSG > 1
        write_log(_T("ATC match(%i): page addr = %08X, index = %08X\n"), l,
                physical_addr, page_index);
 #endif
@@ -2002,7 +2003,7 @@ static uaecptr mmu030_put_atc_generic(uaecptr addr, int l, uae_u32 fc, int flags
     uae_u32 addr_mask = mmu030.translation.page.imask;
     uae_u32 physical_addr = mmu030.atc[l].physical.addr & addr_mask;
 
-#if MMU030_ATC_DBG_MSG
+#if MMU030_ATC_DBG_MSG > 1
     write_log(_T("ATC match(%i): page addr = %08X, index = %08X\n"),
               l, physical_addr, page_index);
 #endif
@@ -2022,7 +2023,7 @@ static uae_u32 mmu030_get_atc_generic(uaecptr addr, int l, uae_u32 fc, int flags
     uae_u32 addr_mask = mmu030.translation.page.imask;
     uae_u32 physical_addr = mmu030.atc[l].physical.addr & addr_mask;
 
-#if MMU030_ATC_DBG_MSG
+#if MMU030_ATC_DBG_MSG > 1
     write_log(_T("ATC match(%i): page addr = %08X, index = %08X\n"), l,
               physical_addr, page_index);
 #endif
@@ -2269,8 +2270,8 @@ uae_u32 mmu030_get_ilong(uaecptr addr, uae_u32 fc)
        mmu030.mmu030_last_logical_address = 0xffffffff;
 #endif
 
-       mmu030_cache_state = CACHE_ENABLE_ALL;
-       if (fc != 7 && (!tt_enabled || !mmu030_match_ttr_access(addr,fc,false)) && mmu030.enabled) {
+       mmu030_cache_state = CACHE_ENABLE_ALL;
+       if (fc != 7 && (!tt_enabled || !mmu030_match_ttr_access(addr, fc, false)) && mmu030.enabled) {
                int atc_line_num = mmu030_logical_is_in_atc(addr, fc, false);
                if (atc_line_num >= 0) {
                        addr = mmu030_get_i_atc(addr, atc_line_num, fc, MMU030_SSW_SIZE_L);
@@ -2284,8 +2285,8 @@ uae_u32 mmu030_get_ilong(uaecptr addr, uae_u32 fc)
        return v;
 }
 
-uae_u16 mmu030_get_iword(uaecptr addr, uae_u32 fc) {
-
+uae_u16 mmu030_get_iword(uaecptr addr, uae_u32 fc)
+{
        uae_u16 v;
 #if MMU_IPAGECACHE030
        if (((addr & mmu030.translation.page.imask) | fc) == mmu030.mmu030_last_logical_address) {
@@ -2301,8 +2302,8 @@ uae_u16 mmu030_get_iword(uaecptr addr, uae_u32 fc) {
        mmu030.mmu030_last_logical_address = 0xffffffff;
 #endif
 
-       mmu030_cache_state = CACHE_ENABLE_ALL;
-       if (fc != 7 && (!tt_enabled || !mmu030_match_ttr_access(addr,fc,false)) && mmu030.enabled) {
+       mmu030_cache_state = CACHE_ENABLE_ALL;
+       if (fc != 7 && (!tt_enabled || !mmu030_match_ttr_access(addr, fc, false)) && mmu030.enabled) {
                int atc_line_num = mmu030_logical_is_in_atc(addr, fc, false);
                if (atc_line_num >= 0) {
                        addr = mmu030_get_i_atc(addr, atc_line_num, fc, MMU030_SSW_SIZE_W);
@@ -3206,12 +3207,12 @@ uae_u32 REGPARAM2 get_disp_ea_020_mmu030c (uae_u32 base, int idx)
        // + whatever the instruction itself does.
 
        if (mmu030_state[1] & (1 << idx)) {
-               m68k_incpci (((mmu030_state[2] >> (idx * 4)) & 15) * 2);
+               m68k_incpci(((mmu030_state[2] >> (idx * 4)) & 15) * 2);
                return mmu030_disp_store[idx];
        }
 
        oldidx = mmu030_idx;
-       dp = next_iword_mmu030c_state ();
+       dp = next_iword_mmu030c_state();
        pcadd += 1;
        
        reg = (dp >> 12) & 15;
@@ -3227,20 +3228,20 @@ uae_u32 REGPARAM2 get_disp_ea_020_mmu030c (uae_u32 base, int idx)
                        regd = 0;
 
                if ((dp & 0x30) == 0x20) {
-                       base += (uae_s32)(uae_s16) next_iword_mmu030c_state ();
+                       base += (uae_s32)(uae_s16) next_iword_mmu030c_state();
                        pcadd += 1;
                }
                if ((dp & 0x30) == 0x30) {
-                       base += next_ilong_mmu030c_state ();
+                       base += next_ilong_mmu030c_state();
                        pcadd += 2;
                }
 
                if ((dp & 0x3) == 0x2) {
-                       outer = (uae_s32)(uae_s16) next_iword_mmu030c_state ();
+                       outer = (uae_s32)(uae_s16) next_iword_mmu030c_state();
                        pcadd += 1;
                }
                if ((dp & 0x3) == 0x3) {
-                       outer = next_ilong_mmu030c_state ();
+                       outer = next_ilong_mmu030c_state();
                        pcadd += 2;
                }
 
@@ -3248,7 +3249,7 @@ uae_u32 REGPARAM2 get_disp_ea_020_mmu030c (uae_u32 base, int idx)
                        base += regd;
                }
                if (dp & 0x3) {
-                       base = get_long_mmu030c_state (base);
+                       base = get_long_mmu030c_state(base);
                }
                if (dp & 0x4) {
                        base += regd;
@@ -3275,9 +3276,9 @@ void m68k_do_rte_mmu030c (uaecptr a7)
 
        uae_u16 sr = get_word_mmu030c(a7);
        uae_u32 pc = get_long_mmu030c(a7 + 2);
-       uae_u16 format = get_word_mmu030c (a7 + 6);
+       uae_u16 format = get_word_mmu030c(a7 + 6);
        uae_u16 frame = format >> 12;
-       uae_u16 ssw = get_word_mmu030c (a7 + 10);
+       uae_u16 ssw = get_word_mmu030c(a7 + 10);
        uae_u32 fault_addr = get_long_mmu030c(a7 + 16);
        // Data output buffer
        uae_u32 mmu030_data_buffer_out_v = get_long_mmu030c(a7 + 0x18);
@@ -3423,6 +3424,15 @@ void m68k_do_rte_mmu030c (uaecptr a7)
                if ((ssw & MMU030_SSW_FB) && !(ssw & MMU030_SSW_RB)) {
                        regs.prefetch020_valid[2] = 1;
                        write_log(_T("Software fixed stage B! opcode = %04x\n"), regs.prefetch020[2]);
+#if 0
+                       if (!regs.prefetch020_valid[0]) {
+                               regs.prefetch020[0] = regs.prefetch020[1];
+                               regs.prefetch020[1] = regs.prefetch020[2];
+                               regs.prefetch020_valid[0] = regs.prefetch020_valid[1];
+                               regs.prefetch020_valid[1] = regs.prefetch020_valid[2];
+                               regs.prefetch020_valid[2] = 0;
+                       }
+#endif
                }
                if ((ssw & MMU030_SSW_FC) && !(ssw & MMU030_SSW_RC)) {
                        regs.prefetch020_valid[1] = 1;
@@ -3458,16 +3468,18 @@ void m68k_do_rte_mmu030c (uaecptr a7)
        m68k_setpci (pc);
 
        if (!(ssw & (MMU030_SSW_DF << 1))) {
-               if (!regs.prefetch020_valid[0] && regs.prefetch020_valid[2]) {
-                       // Prefetch was software fixed, continue pipeline refill
-                       fill_prefetch_030_ntx_continue();
-               } else if (regs.prefetch020_valid[0] && regs.prefetch020_valid[1]) {
-                       // Finished?
+               // software fixed?
+               if (((ssw & MMU030_SSW_FB) && !(ssw & MMU030_SSW_RB)) || ((ssw & MMU030_SSW_FC) && !(ssw & MMU030_SSW_RC))) {
                        fill_prefetch_030_ntx_continue();
-               } else if (mmu030_opcode == -1) {
-                       // Previous branch instruction finished successfully but its pipeline refill
-                       // step caused the exception, retry the refill, do not retry branch instruction.
-                       fill_prefetch_030_ntx();
+               } else {
+                       // pipeline refill in progress?
+                       if (mmu030_opcode == -1) {
+#if MMU030_ALWAYS_FULL_PREFETCH
+                               fill_prefetch_030_ntx();
+#else
+                               fill_prefetch_030_ntx_continue();
+#endif
+                       }
                }
        }
 
@@ -3541,6 +3553,7 @@ void m68k_do_rte_mmu030c (uaecptr a7)
        if (mmu030_state[1] & MMU030_STATEFLAG1_LASTWRITE) {
                mmu030_retry = false;
                if (doprefetch) {
+                       mmu030_opcode = -1;
                        fill_prefetch_030_ntx();
                }
        }
index 1e7a0890768a92382aba2309db18fb9fbaf1b5b5..634e901804ffbabf8cd09c41b67989df9fd526db 100644 (file)
@@ -420,6 +420,8 @@ static bool needmmufixup(void)
                case i_LINK:
                case i_RTD:
                case i_RTR:
+               case i_RTE:
+               case i_RTS:
                        return false;
                }
        }
@@ -530,17 +532,7 @@ static void get_prefetch_020_continue(void)
 {
        if (!isprefetch020())
                return;
-       if (using_ce020) {
-               if (using_ce020 > 1)
-                       out("continue_ce030_prefetch();\n");
-               else
-                       out("continue_ce020_prefetch();\n");
-       } else {
-               if (using_prefetch_020 > 1)
-                       out("continue_030_prefetch();\n");
-               else
-                       out("continue_020_prefetch();\n");
-       }
+       get_prefetch_020();
 }
 
 static void returntail (bool iswrite)
@@ -6846,7 +6838,7 @@ static void gen_opcode (unsigned int opcode)
                } else {
                        fill_prefetch_full_ntx(0);
                }
-               branch_inst = 1;
+               branch_inst = m68k_pc_total;
                next_cpu_level = cpu_level - 1;
                break;
        case i_RTD:
@@ -6879,7 +6871,7 @@ static void gen_opcode (unsigned int opcode)
                } else {
                        fill_prefetch_full(0);
                }
-               branch_inst = 1;
+               branch_inst = m68k_pc_total;
                next_level_040_to_030();
                break;
        case i_LINK:
@@ -7009,7 +7001,7 @@ static void gen_opcode (unsigned int opcode)
                } else {
                        fill_prefetch_full(0);
                }
-               branch_inst = 1;
+               branch_inst = m68k_pc_total;
                if (!next_level_040_to_030()) {
                        if (!next_level_020_to_010())
                                next_level_000();
@@ -7111,7 +7103,7 @@ static void gen_opcode (unsigned int opcode)
                } else {
                        fill_prefetch_full(0);
                }
-               branch_inst = 1;
+               branch_inst = m68k_pc_total;
                tail_ce020_done = true;
                next_cpu_level = cpu_level - 1;
                break;
@@ -7233,7 +7225,7 @@ static void gen_opcode (unsigned int opcode)
                        } else {
                                fill_prefetch_next_empty();
                        }
-                       branch_inst = 1;
+                       branch_inst = m68k_pc_total;
                        next_level_040_to_030();
                        next_level_000();
        }
@@ -7282,7 +7274,7 @@ static void gen_opcode (unsigned int opcode)
                } else {
                        fill_prefetch_full(0);
                }
-               branch_inst = 1;
+               branch_inst = m68k_pc_total;
                next_level_000();
                break;
        case i_BSR:
@@ -7380,7 +7372,7 @@ static void gen_opcode (unsigned int opcode)
                } else {
                        fill_prefetch_full(0);
                }
-               branch_inst = 1;
+               branch_inst = m68k_pc_total;
                if (!next_level_040_to_030()) {
                        if (!next_level_020_to_010())
                                next_level_000();
@@ -7472,7 +7464,7 @@ static void gen_opcode (unsigned int opcode)
                        fill_prefetch_full_000_special(0, NULL);
                }
                insn_n_cycles = curi->size == sz_byte ? 8 : 12;
-               branch_inst = 1;
+               branch_inst = -m68k_pc_total;
 bccl_not68020:
                if (!next_level_040_to_030())
                        next_level_020_to_010();
@@ -7701,7 +7693,7 @@ bccl_not68020:
                clear_m68k_offset();
                get_prefetch_020_continue();
                fill_prefetch_full_000_special(-1, "if (!cctrue(%d)) {\nm68k_dreg(regs, srcreg) = (m68k_dreg(regs, srcreg) & ~0xffff) | (((src - 1)) & 0xffff);\n}\n", curi->cc);
-               branch_inst = 1;
+               branch_inst = -m68k_pc_total;
                if (!next_level_040_to_030()) {
                        if (!next_level_020_to_010())
                                next_level_000();
@@ -9304,7 +9296,7 @@ static void generate_one_opcode (int rp, const char *extra)
        cputbltmp[opcode].disp020[1] = 0;
        if (genamode8r_offset[1] > 0)
                cputbltmp[opcode].disp020[1] = m68k_pc_total - genamode8r_offset[1] + 2;
-       cputbltmp[opcode].branch = branch_inst;
+       cputbltmp[opcode].branch = branch_inst / 2;
 
        if (m68k_pc_total > 0)
                out("/* %d %d,%d %c */\n",
index 13691ac1ca2afb456ddf9fd11c2c8879a18bf4db..417aa60a94c7c641231a67cd0bb2bac519efbb07 100644 (file)
@@ -532,7 +532,7 @@ STATIC_INLINE uae_u32 get_ilong_mmu030_state (int o)
        uae_u32 v;
     uae_u32 addr = m68k_getpci () + o;
        ACCESS_CHECK_GET
-    v = uae_mmu030_get_ilong (addr);
+    v = uae_mmu030_get_ilong(addr);
        ACCESS_EXIT_GET
        return v;
 }
@@ -551,7 +551,7 @@ STATIC_INLINE uae_u32 next_ilong_mmu030_state (void)
        uae_u32 v;
     uae_u32 addr = m68k_getpci ();
        ACCESS_CHECK_GET_PC(4);
-    v = uae_mmu030_get_ilong (addr);
+    v = uae_mmu030_get_ilong(addr);
     m68k_incpci (4);
        ACCESS_EXIT_GET
        return v;
@@ -860,10 +860,8 @@ STATIC_INLINE uae_u32 get_iword_mmu030c_state (int o)
 STATIC_INLINE uae_u32 get_ilong_mmu030c_state (int o)
 {
        uae_u32 v;
-       ACCESS_CHECK_GET;
-       v = get_word_030_prefetch(o + 0) << 16;
-       v |= get_word_030_prefetch(o + 2);
-       ACCESS_EXIT_GET
+       v = get_iword_mmu030c_state(o + 0) << 16;
+       v |= get_iword_mmu030c_state(o + 2) & 0xffff;
        return v;
 }
 STATIC_INLINE uae_u32 get_iword_mmu030c_opcode_state(int o)
@@ -884,11 +882,8 @@ STATIC_INLINE uae_u32 next_iword_mmu030c_state (void)
 STATIC_INLINE uae_u32 next_ilong_mmu030c_state (void)
 {
        uae_u32 v;
-       ACCESS_CHECK_GET_PC(4);
-       v = get_word_030_prefetch(0) << 16;
-       v |= get_word_030_prefetch(2);
-    m68k_incpci (4);
-       ACCESS_EXIT_GET
+       v = next_iword_mmu030c_state() << 16;
+       v |= next_iword_mmu030c_state() & 0xffff;
        return v;
 }
 
index 061fdda1107429dfaa41e2e3872b48d591a57cc2..ecd781ff7e9a83716dea029e5fce22f47037408c 100644 (file)
@@ -62,7 +62,7 @@ struct cputbl {
        uae_u16 opcode;
        uae_s8 length;
        uae_s8 disp020[2];
-       uae_u8 branch;
+       uae_s8 branch;
 };
 
 #ifdef JIT
index 9214dbfda1c3b8665626d2e1a944230fdac1ef1c..b85b16064b638c8fea4bcf30eb8910b9762c54b4 100644 (file)
@@ -120,7 +120,7 @@ struct cputbl_data
 {
        uae_s16 length;
        uae_s8 disp020[2];
-       uae_u8 branch;
+       uae_s8 branch;
 };
 static struct cputbl_data cpudatatbl[65536];
 
@@ -7765,7 +7765,7 @@ static void pipeline_020(uaecptr pc)
 #endif
        // illegal instructions, TRAP, TRAPV, A-line, F-line don't stop prefetches
        int branch = cpudatatbl[w].branch;
-       if (regs.pipeline_pos > 0 && branch) {
+       if (regs.pipeline_pos > 0 && branch > 0) {
                // Short branches (Bcc.s) still do one more prefetch.
 #if 0
                // RTS and other unconditional single opcode instruction stop immediately.
index 9a7918622d8eefaa5f02474581f6b2d4fc343bd2..ec19665aca510d3862ec1b4ef72d2068f48c0b35 100644 (file)
@@ -1566,34 +1566,34 @@ void Exception_build_stack_frame(uae_u32 oldpc, uae_u32 currpc, uae_u32 ssw, int
                // used when instruction's last write causes bus fault
                m68k_areg(regs, 7) -= 4;
                if (format == 0xb) {
-                       x_put_long(m68k_areg(regs, 7), mmu030_disp_store[0]);
+                       x_put_long(m68k_areg(regs, 7), mmu030_disp_store[0]); // 28 0x1c
                } else {
                        uae_u32 ps = (regs.prefetch020_valid[0] ? 1 : 0) | (regs.prefetch020_valid[1] ? 2 : 0) | (regs.prefetch020_valid[2] ? 4 : 0);
                        ps |= ((regs.pipeline_r8[0] & 7) << 8);
                        ps |= ((regs.pipeline_r8[1] & 7) << 11);
                        ps |= ((regs.pipeline_pos & 15) << 16);
                        ps |= ((regs.pipeline_stop & 15) << 20);
-                       x_put_long(m68k_areg(regs, 7), ps);
+                       x_put_long(m68k_areg(regs, 7), ps); // 28 0x1c
                }
                m68k_areg(regs, 7) -= 4;
                // Data output buffer = value that was going to be written
-               x_put_long(m68k_areg(regs, 7), regs.wb3_data);
+               x_put_long(m68k_areg(regs, 7), regs.wb3_data); // 24 0x18
                m68k_areg(regs, 7) -= 4;
                if (format == 0xb) {
-                       x_put_long(m68k_areg(regs, 7), (mmu030_opcode & 0xffff) | (regs.prefetch020[0] << 16));  // Internal register (opcode storage)
+                       x_put_long(m68k_areg(regs, 7), (mmu030_opcode & 0xffff) | (regs.prefetch020[0] << 16));  // Internal register (opcode storage) 20 0x14
                } else {
-                       x_put_long(m68k_areg(regs, 7), regs.irc | (regs.prefetch020[0] << 16));  // Internal register (opcode storage)
+                       x_put_long(m68k_areg(regs, 7), regs.irc | (regs.prefetch020[0] << 16));  // Internal register (opcode storage)  20 0x14
                }
                m68k_areg(regs, 7) -= 4;
-               x_put_long(m68k_areg(regs, 7), regs.mmu_fault_addr); // data cycle fault address
+               x_put_long(m68k_areg(regs, 7), regs.mmu_fault_addr); // data cycle fault address 16 0x10
                m68k_areg(regs, 7) -= 2;
-               x_put_word(m68k_areg(regs, 7), regs.prefetch020[2]);  // Instr. pipe stage B
+               x_put_word(m68k_areg(regs, 7), regs.prefetch020[2]);  // Instr. pipe stage B 14 0x0e
                m68k_areg(regs, 7) -= 2;
-               x_put_word(m68k_areg(regs, 7), regs.prefetch020[1]);  // Instr. pipe stage C
+               x_put_word(m68k_areg(regs, 7), regs.prefetch020[1]);  // Instr. pipe stage C 12 0x0c
                m68k_areg(regs, 7) -= 2;
-               x_put_word(m68k_areg(regs, 7), ssw);
+               x_put_word(m68k_areg(regs, 7), ssw); // 10 0x0a
                m68k_areg(regs, 7) -= 2;
-               x_put_word(m68k_areg(regs, 7), regs.wb2_address); // = mmu030_state[1]);
+               x_put_word(m68k_areg(regs, 7), regs.wb2_address); // = mmu030_state[1]); 8 0x08
                break;
        default:
                write_log(_T("Unknown exception stack frame format: %X\n"), format);