]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
68030 MMU state handling simplified.
authorToni Wilen <twilen@winuae.net>
Sat, 4 Jan 2020 12:22:21 +0000 (14:22 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 4 Jan 2020 12:22:21 +0000 (14:22 +0200)
cpummu30.cpp
include/cpummu030.h
newcpu.cpp
newcpu_common.cpp

index 3eef9a26a589ca305611b5448103ea51e81f7946..46a73ac341e1ee9a68b411dd083286e1ec9f8f83 100644 (file)
@@ -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++;
                        }
                }
        }
index e0d155452ef241a832184e2a67c0fa8a885e260e..8222b5ffa27a280249b23fb004819d651afd843e 100644 (file)
@@ -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);
 }
index 05dbe4640ad208cfa6de5c02b06e825eccad109b..7ec25511105ad1c7e15550ffb4ab9eba76131752 100644 (file)
@@ -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;
index 8403991a8a5fc18f938fb1c06e0f51f4c4705511..13c79001bf5e638ea1041c07f045ca085ff11414 100644 (file)
@@ -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]);