From 0071e6d17b9c2e310200cb5ce16e682e6384c86d Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 4 Jan 2020 14:22:21 +0200 Subject: [PATCH] 68030 MMU state handling simplified. --- cpummu30.cpp | 72 +++++++++++++++++++++++---------------------- include/cpummu030.h | 69 +++++++++++++++++-------------------------- newcpu.cpp | 6 ++-- newcpu_common.cpp | 4 +-- 4 files changed, 69 insertions(+), 82 deletions(-) diff --git a/cpummu30.cpp b/cpummu30.cpp index 3eef9a26..46a73ac3 100644 --- a/cpummu30.cpp +++ b/cpummu30.cpp @@ -55,7 +55,7 @@ static int bBusErrorReadWrite; static int atcindextable[32]; static int tt_enabled; -int mmu030_idx; +int mmu030_idx, mmu030_idx_done; uae_u32 mm030_stageb_address; bool mmu030_retry; @@ -1804,8 +1804,10 @@ void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc) #endif #if 0 - if (addr == 0xBFE201) + if (addr == 0x00016060) write_log("!"); +#endif +#if 0 if (mmu030_state[1] & MMU030_STATEFLAG1_SUBACCESS0) write_log("!"); if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) @@ -2750,7 +2752,7 @@ void m68k_do_rte_mmu030 (uaecptr a7) uae_u32 mmu030_data_buffer_out_v = get_long_mmu030(a7 + 0x18); // Internal register, our opcode storage area uae_u32 oc = get_long_mmu030(a7 + 0x14); - int idxsize = -1; + int idxsize = -1, idxsize_done = -1; // Fetch last word, real CPU does it to allow OS bus handler to map // the page if frame crosses pages and following page is not resident. @@ -2790,7 +2792,7 @@ void m68k_do_rte_mmu030 (uaecptr a7) mmu030_state[1] = mmu030_state_1; mmu030_state[2] = 0; mmu030_opcode = oc; - mmu030_idx = 0; + mmu030_idx = mmu030_idx_done = 0; m68k_areg(regs, 7) += 32; @@ -2817,12 +2819,12 @@ void m68k_do_rte_mmu030 (uaecptr a7) mmu030_fmovem_store_1 = get_long_mmu030(a7 + 0x5c - (8 + 1) * 4); } - idxsize = get_word_mmu030(a7 + 0x36); - for (int i = 0; i < idxsize + 1; i++) { - mmu030_ad_v[i].done = i < idxsize; + uae_u16 v = get_word_mmu030(a7 + 0x36); + idxsize = v & 0xff; + idxsize_done = (v >> 8) & 0xff; + for (int i = 0; i < idxsize_done; i++) { mmu030_ad_v[i].val = get_long_mmu030(a7 + 0x5c - (i + 1) * 4); } - mmu030_ad_v[idxsize + 1].done = false; // did we have data fault but DF bit cleared? if (ssw & (MMU030_SSW_DF << 1) && !(ssw & MMU030_SSW_DF)) { @@ -2836,10 +2838,9 @@ void m68k_do_rte_mmu030 (uaecptr a7) // if movem, skip next move mmu030_state_1 |= MMU030_STATEFLAG1_MOVEM2; } else { - mmu030_ad_v[idxsize].done = true; if (ssw & MMU030_SSW_RW) { // Read and no DF: use value in data input buffer - mmu030_ad_v[idxsize].val = mmu030_data_buffer_in_v; + mmu030_ad_v[idxsize_done++].val = mmu030_data_buffer_in_v; } } unalign_clear(); @@ -2851,8 +2852,8 @@ void m68k_do_rte_mmu030 (uaecptr a7) mmu030_opcode_stageb = stageb; write_log(_T("Software fixed stage B! opcode = %04x\n"), stageb); } else { - mmu030_ad_v[idxsize].done = true; mmu030_ad_v[idxsize].val = stageb; + idxsize_done = idxsize; write_log(_T("Software fixed stage B! opcode = %04X, opword = %04x\n"), mmu030_opcode_v, stageb); } } @@ -2875,8 +2876,8 @@ void m68k_do_rte_mmu030 (uaecptr a7) mmu030_fmovem_store[1] = mmu030_fmovem_store_1; mmu030_data_buffer_out = mmu030_data_buffer_out_v; mmu030_idx = idxsize; - for (int i = 0; i <= mmu030_idx + 1; i++) { - mmu030_ad[i].done = mmu030_ad_v[i].done; + mmu030_idx_done = idxsize_done; + for (int i = 0; i < idxsize_done; i++) { mmu030_ad[i].val = mmu030_ad_v[i].val; } @@ -2895,7 +2896,7 @@ void m68k_do_rte_mmu030 (uaecptr a7) if ((ssw & MMU030_SSW_DF) && (ssw & MMU030_SSW_RM)) { // Locked-Read-Modify-Write restarts whole instruction. - mmu030_ad[0].done = false; + idxsize_done = 0; } else if (ssw & MMU030_SSW_DF) { @@ -2942,8 +2943,8 @@ void m68k_do_rte_mmu030 (uaecptr a7) if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) { mmu030_state[1] |= MMU030_STATEFLAG1_MOVEM2; } else if (idxsize >= 0) { - mmu030_ad[idxsize].val = mmu030_data_buffer_out; - mmu030_ad[idxsize].done = true; + mmu030_ad[mmu030_idx_done].val = mmu030_data_buffer_out; + mmu030_idx_done++; } } else { if (mmu030_state[1] & MMU030_STATEFLAG1_SUBACCESS0) { @@ -2965,7 +2966,7 @@ void m68k_do_rte_mmu030 (uaecptr a7) if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) { mmu030_state[1] |= MMU030_STATEFLAG1_MOVEM2; } else if (idxsize >= 0) { - mmu030_ad[idxsize].done = true; + mmu030_idx_done++; } } @@ -3003,7 +3004,7 @@ uae_u32 REGPARAM2 get_disp_ea_020_mmu030 (uae_u32 base, int idx) uae_u16 dp; int reg; uae_u32 v; - int oldidx; + int oldidx, oldidx2; int pcadd = 0; // we need to do this hack here because in worst case we don't have enough @@ -3016,6 +3017,7 @@ uae_u32 REGPARAM2 get_disp_ea_020_mmu030 (uae_u32 base, int idx) } oldidx = mmu030_idx; + oldidx2 = mmu030_idx_done; dp = next_iword_mmu030_state (); pcadd += 1; @@ -3067,7 +3069,7 @@ uae_u32 REGPARAM2 get_disp_ea_020_mmu030 (uae_u32 base, int idx) mmu030_state[2] |= pcadd << (idx * 4); mmu030_disp_store[idx] = v; mmu030_idx = oldidx; - mmu030_ad[mmu030_idx].done = false; + mmu030_idx_done = oldidx2; return v; } @@ -3093,7 +3095,7 @@ uae_u32 REGPARAM2 get_disp_ea_020_mmu030c (uae_u32 base, int idx) uae_u16 dp; int reg; uae_u32 v; - int oldidx; + int oldidx, oldidx2; int pcadd = 0; // we need to do this hack here because in worst case we don't have enough @@ -3106,6 +3108,7 @@ uae_u32 REGPARAM2 get_disp_ea_020_mmu030c (uae_u32 base, int idx) } oldidx = mmu030_idx; + oldidx2 = mmu030_idx_done; dp = next_iword_mmu030c_state (); pcadd += 1; @@ -3157,7 +3160,7 @@ uae_u32 REGPARAM2 get_disp_ea_020_mmu030c (uae_u32 base, int idx) mmu030_state[2] |= pcadd << (idx * 4); mmu030_disp_store[idx] = v; mmu030_idx = oldidx; - mmu030_ad[mmu030_idx].done = false; + mmu030_idx_done = oldidx2; return v; } @@ -3180,7 +3183,7 @@ void m68k_do_rte_mmu030c (uaecptr a7) uae_u32 oc = get_long_mmu030c(a7 + 0x14); uae_u32 stagesbc = get_long_mmu030c(a7 + 12); - int idxsize = -1; + int idxsize = -1, idxsize_done = -1; bool doprefetch = true; // Fetch last word, real CPU does it to allow OS bus handler to map @@ -3234,7 +3237,7 @@ void m68k_do_rte_mmu030c (uaecptr a7) mmu030_state[0] = 0; mmu030_state[1] = mmu030_state_1; mmu030_state[2] = 0; - mmu030_idx = 0; + mmu030_idx = mmu030_idx_done = 0; doprefetch = false; @@ -3263,12 +3266,12 @@ void m68k_do_rte_mmu030c (uaecptr a7) mmu030_fmovem_store_1 = get_long_mmu030c(a7 + 0x5c - (8 + 1) * 4); } - idxsize = get_word_mmu030c(a7 + 0x36); - for (int i = 0; i < idxsize + 1; i++) { - mmu030_ad_v[i].done = i < idxsize; + uae_u16 v = get_word_mmu030c(a7 + 0x36); + idxsize = v & 0xff; + idxsize_done = (v >> 8) & 0xff; + for (int i = 0; i < idxsize_done; i++) { mmu030_ad_v[i].val = get_long_mmu030c(a7 + 0x5c - (i + 1) * 4); } - mmu030_ad_v[idxsize + 1].done = false; // did we have data fault but DF bit cleared? if (ssw & (MMU030_SSW_DF << 1) && !(ssw & MMU030_SSW_DF)) { @@ -3282,10 +3285,9 @@ void m68k_do_rte_mmu030c (uaecptr a7) // if movem, skip next move mmu030_state_1 |= MMU030_STATEFLAG1_MOVEM2; } else { - mmu030_ad_v[idxsize].done = true; if (ssw & MMU030_SSW_RW) { // Read and no DF: use value in data input buffer - mmu030_ad_v[idxsize].val = mmu030_data_buffer_in_v; + mmu030_ad_v[idxsize_done++].val = mmu030_data_buffer_in_v; } } unalign_clear(); @@ -3330,8 +3332,8 @@ void m68k_do_rte_mmu030c (uaecptr a7) mmu030_fmovem_store[1] = mmu030_fmovem_store_1; mmu030_data_buffer_out = mmu030_data_buffer_out_v; mmu030_idx = idxsize; - for (int i = 0; i <= mmu030_idx + 1; i++) { - mmu030_ad[i].done = mmu030_ad_v[i].done; + mmu030_idx_done = idxsize_done; + for (int i = 0; i < idxsize_done; i++) { mmu030_ad[i].val = mmu030_ad_v[i].val; } @@ -3364,7 +3366,7 @@ void m68k_do_rte_mmu030c (uaecptr a7) if ((ssw & MMU030_SSW_DF) && (ssw & MMU030_SSW_RM)) { // Locked-Read-Modify-Write restarts whole instruction. - mmu030_ad[0].done = false; + mmu030_idx_done = 0; } else if (ssw & MMU030_SSW_DF) { // retry faulted access @@ -3404,8 +3406,8 @@ void m68k_do_rte_mmu030c (uaecptr a7) if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) { mmu030_state[1] |= MMU030_STATEFLAG1_MOVEM2; } else if (idxsize >= 0) { - mmu030_ad[idxsize].val = mmu030_data_buffer_out; - mmu030_ad[idxsize].done = true; + mmu030_ad[mmu030_idx_done].val = mmu030_data_buffer_out; + mmu030_idx_done++; } } else { if (mmu030_state[1] & MMU030_STATEFLAG1_SUBACCESS0) { @@ -3427,7 +3429,7 @@ void m68k_do_rte_mmu030c (uaecptr a7) if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) { mmu030_state[1] |= MMU030_STATEFLAG1_MOVEM2; } else if (idxsize >= 0) { - mmu030_ad[idxsize].done = true; + mmu030_idx_done++; } } } diff --git a/include/cpummu030.h b/include/cpummu030.h index e0d15545..8222b5ff 100644 --- a/include/cpummu030.h +++ b/include/cpummu030.h @@ -16,7 +16,7 @@ extern uae_u16 mmusr_030; #define MAX_MMU030_ACCESS 9 extern uae_u32 mm030_stageb_address; -extern int mmu030_idx; +extern int mmu030_idx, mmu030_idx_done; extern bool mmu030_retry; extern int mmu030_opcode, mmu030_opcode_stageb; extern int mmu030_fake_prefetch; @@ -46,7 +46,6 @@ extern uae_u8 mmu030_cache_state, mmu030_cache_state_default; struct mmu030_access { - bool done; uae_u32 val; }; extern struct mmu030_access mmu030_ad[MAX_MMU030_ACCESS + 1]; @@ -261,41 +260,41 @@ static ALWAYS_INLINE void uae_mmu030_put_byte_fcx(uaecptr addr, uae_u32 val, int mmu030_put_byte(addr, val, fc); } - #define ACCESS_CHECK_PUT \ - if (!mmu030_ad[mmu030_idx].done) { \ - mmu030_data_buffer_out = v; \ - } else { \ - mmu030_idx++; \ + if (mmu030_idx++ < mmu030_idx_done) { \ return; \ + } else { \ + mmu030_data_buffer_out = v; \ } #define ACCESS_CHECK_GET \ - if (mmu030_ad[mmu030_idx].done) { \ - v = mmu030_ad[mmu030_idx].val; \ - mmu030_idx++; \ + if (mmu030_idx++ < mmu030_idx_done) { \ + v = mmu030_ad[mmu030_idx - 1].val; \ return v; \ } #define ACCESS_CHECK_GET_PC(pc) \ - if (mmu030_ad[mmu030_idx].done) { \ - v = mmu030_ad[mmu030_idx].val; \ - mmu030_idx++; \ - m68k_incpci (pc); \ + if (mmu030_idx++ < mmu030_idx_done) { \ + v = mmu030_ad[mmu030_idx - 1].val; \ + m68k_incpci(pc); \ return v; \ } #define ACCESS_EXIT_PUT \ - mmu030_ad[mmu030_idx].val = mmu030_data_buffer_out; \ - mmu030_ad[mmu030_idx].done = true; \ - mmu030_idx++; \ - mmu030_ad[mmu030_idx].done = false; + mmu030_ad[mmu030_idx_done++].val = mmu030_data_buffer_out; #define ACCESS_EXIT_GET \ - mmu030_ad[mmu030_idx].val = v; \ - mmu030_ad[mmu030_idx].done = true; \ - mmu030_idx++; \ - mmu030_ad[mmu030_idx].done = false; + mmu030_ad[mmu030_idx_done++].val = v; + +STATIC_INLINE uae_u32 state_store_mmu030(uae_u32 v) +{ + if (mmu030_idx++ < mmu030_idx_done) { + v = mmu030_ad[mmu030_idx - 1].val; + } else { + mmu030_ad[mmu030_idx_done++].val = v; + } + return v; +} // non-cache @@ -602,20 +601,6 @@ STATIC_INLINE uae_u32 next_ilong_mmu030 (void) return v; } -STATIC_INLINE uae_u32 state_store_mmu030(uae_u32 v) -{ - if (mmu030_ad[mmu030_idx].done) { - v = mmu030_ad[mmu030_idx].val; - mmu030_idx++; - } else { - mmu030_ad[mmu030_idx].val = v; - mmu030_ad[mmu030_idx].done = true; - mmu030_idx++; - mmu030_ad[mmu030_idx].done = false; - } - return v; -} - extern void m68k_do_rts_mmu030 (void); extern void m68k_do_rte_mmu030 (uaecptr a7); extern void flush_mmu030 (uaecptr, int); @@ -651,7 +636,7 @@ static ALWAYS_INLINE void mmu030_put_fc_long(uaecptr addr, uae_u32 val, uae_u32 static ALWAYS_INLINE uae_u32 sfc030c_get_long(uaecptr addr) { #if MMUDEBUG > 2 - write_log(_T("sfc030_get_long: FC = %i\n"),fc); + write_log(_T("sfc030_get_long: FC = %i\n"), regs.sfc); #endif return read_data_030_fc_lget(addr, regs.sfc); } @@ -659,7 +644,7 @@ static ALWAYS_INLINE uae_u32 sfc030c_get_long(uaecptr addr) static ALWAYS_INLINE uae_u16 sfc030c_get_word(uaecptr addr) { #if MMUDEBUG > 2 - write_log(_T("sfc030_get_word: FC = %i\n"),fc); + write_log(_T("sfc030_get_word: FC = %i\n"), regs.sfc); #endif return read_data_030_fc_wget(addr, regs.sfc); } @@ -667,7 +652,7 @@ static ALWAYS_INLINE uae_u16 sfc030c_get_word(uaecptr addr) static ALWAYS_INLINE uae_u8 sfc030c_get_byte(uaecptr addr) { #if MMUDEBUG > 2 - write_log(_T("sfc030_get_byte: FC = %i\n"),fc); + write_log(_T("sfc030_get_byte: FC = %i\n"), regs.sfc); #endif return read_data_030_fc_bget(addr, regs.sfc); } @@ -675,7 +660,7 @@ static ALWAYS_INLINE uae_u8 sfc030c_get_byte(uaecptr addr) static ALWAYS_INLINE void dfc030c_put_long(uaecptr addr, uae_u32 val) { #if MMUDEBUG > 2 - write_log(_T("dfc030_put_long: %08X = %08X FC = %i\n"), addr, val, fc); + write_log(_T("dfc030_put_long: %08X = %08X FC = %i\n"), addr, val, regs.dfc); #endif write_data_030_fc_lput(addr, val, regs.dfc); } @@ -683,7 +668,7 @@ static ALWAYS_INLINE void dfc030c_put_long(uaecptr addr, uae_u32 val) static ALWAYS_INLINE void dfc030c_put_word(uaecptr addr, uae_u16 val) { #if MMUDEBUG > 2 - write_log(_T("dfc030_put_word: %08X = %04X FC = %i\n"), addr, val, fc); + write_log(_T("dfc030_put_word: %08X = %04X FC = %i\n"), addr, val, regs.dfc); #endif write_data_030_fc_wput(addr, val, regs.dfc); } @@ -691,7 +676,7 @@ static ALWAYS_INLINE void dfc030c_put_word(uaecptr addr, uae_u16 val) static ALWAYS_INLINE void dfc030c_put_byte(uaecptr addr, uae_u8 val) { #if MMUDEBUG > 2 - write_log(_T("dfc030_put_byte: %08X = %02X FC = %i\n"), addr, val, fc); + write_log(_T("dfc030_put_byte: %08X = %02X FC = %i\n"), addr, val, regs.dfc); #endif write_data_030_fc_bput(addr, val, regs.dfc); } diff --git a/newcpu.cpp b/newcpu.cpp index 05dbe464..7ec25511 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -5248,7 +5248,7 @@ insretry: } mmu030_opcode = regs.opcode; - mmu030_ad[0].done = false; + mmu030_idx_done = 0; cnt = 50; for (;;) { @@ -9015,7 +9015,7 @@ void fill_prefetch_030_ntx(void) int idx = 0; pc &= ~3; - mmu030_idx = 0; + mmu030_idx = mmu030_idx_done = 0; reset_pipeline_state(); regs.cacheholdingdata_valid = 1; regs.cacheholdingaddr020 = 0xffffffff; @@ -9049,7 +9049,7 @@ void fill_prefetch_030_ntx_continue (void) uaecptr pc_orig = pc; int idx = 0; - mmu030_idx = 0; + mmu030_idx = mmu030_idx_done = 0; reset_pipeline_state(); regs.cacheholdingdata_valid = 1; regs.cacheholdingaddr020 = 0xffffffff; diff --git a/newcpu_common.cpp b/newcpu_common.cpp index 8403991a..13c79001 100644 --- a/newcpu_common.cpp +++ b/newcpu_common.cpp @@ -1410,7 +1410,7 @@ void Exception_build_stack_frame(uae_u32 oldpc, uae_u32 currpc, uae_u32 ssw, int if (!(ssw & MMU030_SSW_RW)) { mmu030_ad[mmu030_idx].val = regs.wb3_data; } - for (i = 0; i < mmu030_idx + 1; i++) { + for (i = 0; i < mmu030_idx_done; i++) { m68k_areg(regs, 7) -= 4; x_put_long(m68k_areg(regs, 7), mmu030_ad[i].val); } @@ -1434,7 +1434,7 @@ void Exception_build_stack_frame(uae_u32 oldpc, uae_u32 currpc, uae_u32 ssw, int } // version & internal information (We store index here) m68k_areg(regs, 7) -= 2; - x_put_word(m68k_areg(regs, 7), mmu030_idx); + x_put_word(m68k_areg(regs, 7), (mmu030_idx & 0xff) | ((mmu030_idx_done & 0xff) << 8)); // 3* internal registers m68k_areg(regs, 7) -= 2; x_put_word(m68k_areg(regs, 7), mmu030_state[2]); -- 2.47.3