]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Fix 68030 MMU regression.
authorToni Wilen <twilen@winuae.net>
Sun, 5 Jan 2020 15:06:49 +0000 (17:06 +0200)
committerToni Wilen <twilen@winuae.net>
Sun, 5 Jan 2020 15:06:49 +0000 (17:06 +0200)
cpummu30.cpp
newcpu_common.cpp

index 59bf12172c206b6bbc2b45817101e5f3e98d1be4..21825925f501524ade6cd2e71778152ce8f0e68d 100644 (file)
@@ -2842,7 +2842,7 @@ void m68k_do_rte_mmu030 (uaecptr a7)
                uae_u16 v = get_word_mmu030(a7 + 0x36);
                idxsize = v & 0xff;
                idxsize_done = (v >> 8) & 0xff;
-               for (int i = 0; i < idxsize_done; i++) {
+               for (int i = 0; i < idxsize_done + 1; i++) {
                        mmu030_ad_v[i].val = get_long_mmu030(a7 + 0x5c - (i + 1) * 4);
                }
 
@@ -2860,8 +2860,9 @@ void m68k_do_rte_mmu030 (uaecptr a7)
                        } else {
                                if (ssw & MMU030_SSW_RW) {
                                        // Read and no DF: use value in data input buffer
-                                       mmu030_ad_v[idxsize_done++].val = mmu030_data_buffer_in_v;
-                               }
+                                       mmu030_ad_v[idxsize_done].val = mmu030_data_buffer_in_v;
+                               } // else: use value idxsize_done that was saved from regs.wb3_data;
+                               idxsize_done++;
                        }
                        unalign_clear();
                }
@@ -2897,7 +2898,7 @@ void m68k_do_rte_mmu030 (uaecptr a7)
                mmu030_data_buffer_out = mmu030_data_buffer_out_v;
                mmu030_idx = idxsize;
                mmu030_idx_done = idxsize_done;
-               for (int i = 0; i < idxsize_done; i++) {
+               for (int i = 0; i < idxsize_done + 1; i++) {
                        mmu030_ad[i].val = mmu030_ad_v[i].val;
                }
 
@@ -3289,7 +3290,7 @@ void m68k_do_rte_mmu030c (uaecptr a7)
                uae_u16 v = get_word_mmu030c(a7 + 0x36);
                idxsize = v & 0xff;
                idxsize_done = (v >> 8) & 0xff;
-               for (int i = 0; i < idxsize_done; i++) {
+               for (int i = 0; i < idxsize_done + 1; i++) {
                        mmu030_ad_v[i].val = get_long_mmu030c(a7 + 0x5c - (i + 1) * 4);
                }
 
@@ -3307,8 +3308,9 @@ void m68k_do_rte_mmu030c (uaecptr a7)
                        } else {
                                if (ssw & MMU030_SSW_RW) {
                                        // Read and no DF: use value in data input buffer
-                                       mmu030_ad_v[idxsize_done++].val = mmu030_data_buffer_in_v;
+                                       mmu030_ad_v[idxsize_done].val = mmu030_data_buffer_in_v;
                                }
+                               idxsize_done++;
                        }
                        unalign_clear();
                }
@@ -3353,7 +3355,7 @@ void m68k_do_rte_mmu030c (uaecptr a7)
                mmu030_data_buffer_out = mmu030_data_buffer_out_v;
                mmu030_idx = idxsize;
                mmu030_idx_done = idxsize_done;
-               for (int i = 0; i < idxsize_done; i++) {
+               for (int i = 0; i < idxsize_done + 1; i++) {
                        mmu030_ad[i].val = mmu030_ad_v[i].val;
                }
 
index 2dbb8545a6d9139e36d6d709c9690c8e46917b22..cbda589510e8845f5f93c79a980cf33dbe0b735a 100644 (file)
@@ -1408,9 +1408,11 @@ void Exception_build_stack_frame(uae_u32 oldpc, uae_u32 currpc, uae_u32 ssw, int
                }
 #endif
                if (!(ssw & MMU030_SSW_RW)) {
-                       mmu030_ad[mmu030_idx].val = regs.wb3_data;
+                       // written value that caused fault but was not yet written to memory
+                       // this value is used in cpummu030 when write is retried.
+                       mmu030_ad[mmu030_idx_done].val = regs.wb3_data;
                }
-               for (i = 0; i < mmu030_idx_done; i++) {
+               for (i = 0; i < mmu030_idx_done + 1; i++) {
                        m68k_areg(regs, 7) -= 4;
                        x_put_long(m68k_areg(regs, 7), mmu030_ad[i].val);
                }