]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
68030 MMU hardware bus error support.
authorToni Wilen <twilen@winuae.net>
Mon, 6 Jan 2020 09:00:51 +0000 (11:00 +0200)
committerToni Wilen <twilen@winuae.net>
Mon, 6 Jan 2020 09:00:51 +0000 (11:00 +0200)
cpummu30.cpp
gencpu.cpp

index 4d744c5477a6fb278dc62a6780d24da97ebb6daa..e209848c5c23d1ba9a61e6010a3607e6536fbbd8 100644 (file)
@@ -36,6 +36,7 @@
 #include "newcpu.h"
 #include "debug.h"
 #include "cpummu030.h"
+#include "cputbl.h"
 
 #define MMU030_OP_DBG_MSG 0
 #define MMU030_ATC_DBG_MSG 0
@@ -1859,6 +1860,18 @@ void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc)
        THROW(2);
 }
 
+static void mmu030_hardware_bus_error(uaecptr addr, uae_u32 v, bool read, int size, uae_u32 fc)
+{
+       int flags = size == sz_byte ? MMU030_SSW_SIZE_B : (size == sz_word ? MMU030_SSW_SIZE_W : MMU030_SSW_SIZE_L);
+       if (!read) {
+               mmu030_data_buffer_out = v;
+       } else {
+               flags |= MMU030_SSW_RW;
+       }
+       mmu030_page_fault(addr, read, flags, fc);
+
+}
+
 static void mmu030_add_data_read_cache(uaecptr addr, uaecptr phys, uae_u32 fc)
 {
 #if MMU_DPAGECACHE030
@@ -2078,6 +2091,10 @@ void mmu030_put_long(uaecptr addr, uae_u32 val, uae_u32 fc)
        }
        cacheablecheck(addr);
        x_phys_put_long(addr,val);
+#if BUS_ERROR_EMULATION
+       if (cpu_bus_error)
+               mmu030_hardware_bus_error(addr, val, false, sz_long, fc);
+#endif
 }
 
 void mmu030_put_word(uaecptr addr, uae_u16 val, uae_u32 fc)
@@ -2104,6 +2121,10 @@ void mmu030_put_word(uaecptr addr, uae_u16 val, uae_u32 fc)
        }
        cacheablecheck(addr);
        x_phys_put_word(addr,val);
+#if BUS_ERROR_EMULATION
+       if (cpu_bus_error)
+               mmu030_hardware_bus_error(addr, val, false, sz_word, fc);
+#endif
 }
 
 void mmu030_put_byte(uaecptr addr, uae_u8 val, uae_u32 fc)
@@ -2130,6 +2151,10 @@ void mmu030_put_byte(uaecptr addr, uae_u8 val, uae_u32 fc)
        }
        cacheablecheck(addr);
        x_phys_put_byte(addr,val);
+#if BUS_ERROR_EMULATION
+       if (cpu_bus_error)
+               mmu030_hardware_bus_error(addr, val, false, sz_byte, fc);
+#endif
 }
 
 
@@ -2156,7 +2181,12 @@ uae_u32 mmu030_get_long(uaecptr addr, uae_u32 fc)
                }
        }
        cacheablecheck(addr);
-       return x_phys_get_long(addr);
+       uae_u32 v = x_phys_get_long(addr);
+#if BUS_ERROR_EMULATION
+       if (cpu_bus_error)
+               mmu030_hardware_bus_error(addr, v, true, sz_long, fc);
+#endif
+       return v;
 }
 
 uae_u16 mmu030_get_word(uaecptr addr, uae_u32 fc)
@@ -2182,7 +2212,12 @@ uae_u16 mmu030_get_word(uaecptr addr, uae_u32 fc)
                }
        }
        cacheablecheck(addr);
-       return x_phys_get_word(addr);
+       uae_u16 v = x_phys_get_word(addr);
+#if BUS_ERROR_EMULATION
+       if (cpu_bus_error)
+               mmu030_hardware_bus_error(addr, v, true, sz_word, fc);
+#endif
+       return v;
 }
 
 uae_u8 mmu030_get_byte(uaecptr addr, uae_u32 fc)
@@ -2208,12 +2243,18 @@ uae_u8 mmu030_get_byte(uaecptr addr, uae_u32 fc)
                }
        }
        cacheablecheck(addr);
-       return x_phys_get_byte(addr);
+       uae_u8 v = x_phys_get_byte(addr);
+#if BUS_ERROR_EMULATION
+       if (cpu_bus_error)
+               mmu030_hardware_bus_error(addr, v, true, sz_byte, fc);
+#endif
+       return v;
 }
 
 
 uae_u32 mmu030_get_ilong(uaecptr addr, uae_u32 fc)
 {
+       uae_u32 v;
 #if MMU_IPAGECACHE030
        if (((addr & mmu030.translation.page.imask) | fc) == mmu030.mmu030_last_logical_address) {
 #if MMU_DIRECT_ACCESS
@@ -2221,7 +2262,12 @@ uae_u32 mmu030_get_ilong(uaecptr addr, uae_u32 fc)
                return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]);
 #else
                mmu030_cache_state = mmu030.mmu030_cache_state;
-               return x_phys_get_ilong(mmu030.mmu030_last_physical_address + (addr & mmu030.translation.page.mask));
+               v = x_phys_get_ilong(mmu030.mmu030_last_physical_address + (addr & mmu030.translation.page.mask));
+#if BUS_ERROR_EMULATION
+               if (cpu_bus_error)
+                       mmu030_hardware_bus_error(addr, v, true, sz_long, fc);
+#endif
+               return v;
 #endif
        }
        mmu030.mmu030_last_logical_address = 0xffffffff;
@@ -2238,11 +2284,17 @@ uae_u32 mmu030_get_ilong(uaecptr addr, uae_u32 fc)
                }
        }
        cacheablecheck(addr);
-       return x_phys_get_ilong(addr);
+       v = x_phys_get_ilong(addr);
+#if BUS_ERROR_EMULATION
+       if (cpu_bus_error)
+               mmu030_hardware_bus_error(addr, v, true, sz_long, fc);
+#endif
+       return v;
 }
 
 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) {
 #if MMU_DIRECT_ACCESS
@@ -2250,7 +2302,12 @@ uae_u16 mmu030_get_iword(uaecptr addr, uae_u32 fc) {
                return (p[0] << 8) | p[1];
 #else
                mmu030_cache_state = mmu030.mmu030_cache_state;
-               return x_phys_get_iword(mmu030.mmu030_last_physical_address + (addr & mmu030.translation.page.mask));
+               v = x_phys_get_iword(mmu030.mmu030_last_physical_address + (addr & mmu030.translation.page.mask));
+#if BUS_ERROR_EMULATION
+               if (cpu_bus_error)
+                       mmu030_hardware_bus_error(addr, v, true, sz_word, fc);
+#endif
+               return v;
 #endif
        }
        mmu030.mmu030_last_logical_address = 0xffffffff;
@@ -2267,7 +2324,12 @@ uae_u16 mmu030_get_iword(uaecptr addr, uae_u32 fc) {
                }
        }
        cacheablecheck(addr);
-       return x_phys_get_iword(addr);
+       v = x_phys_get_iword(addr);
+#if BUS_ERROR_EMULATION
+       if (cpu_bus_error)
+               mmu030_hardware_bus_error(addr, v, true, sz_word, fc);
+#endif
+       return v;
 }
 
 /* Not commonly used access function */
@@ -2293,6 +2355,11 @@ static void mmu030_put_generic_lrmw(uaecptr addr, uae_u32 val, uae_u32 fc, int s
                x_phys_put_word(addr, val);
        else
                x_phys_put_long(addr, val);
+
+#if BUS_ERROR_EMULATION
+       if (cpu_bus_error)
+               mmu030_hardware_bus_error(addr, val, false, size, fc);
+#endif
 }
 
 void mmu030_put_generic(uaecptr addr, uae_u32 val, uae_u32 fc, int size, int flags)
@@ -2321,11 +2388,17 @@ void mmu030_put_generic(uaecptr addr, uae_u32 val, uae_u32 fc, int size, int fla
                x_phys_put_word(addr, val);
        else
                x_phys_put_long(addr, val);
+
+#if BUS_ERROR_EMULATION
+       if (cpu_bus_error)
+               mmu030_hardware_bus_error(addr, val, false, size, fc);
+#endif
 }
 
 static uae_u32 mmu030_get_generic_lrmw(uaecptr addr, uae_u32 fc, int size, int flags)
 {
-       mmu030_cache_state = CACHE_ENABLE_ALL;
+       uae_u32 v;
+       mmu030_cache_state = CACHE_ENABLE_ALL;
        if (fc != 7 && (!tt_enabled || !mmu030_match_lrmw_ttr_access(addr,fc)) && mmu030.enabled) {
                int atc_line_num = mmu030_logical_is_in_atc(addr, fc, true);
                if (atc_line_num>=0) {
@@ -2339,15 +2412,24 @@ static uae_u32 mmu030_get_generic_lrmw(uaecptr addr, uae_u32 fc, int size, int f
 
        cacheablecheck(addr);
        if (size == sz_byte)
-               return x_phys_get_byte(addr);
+               v = x_phys_get_byte(addr);
        else if (size == sz_word)
-               return x_phys_get_word(addr);
-       return x_phys_get_long(addr);
+               v = x_phys_get_word(addr);
+       else
+               v = x_phys_get_long(addr);
+
+#if BUS_ERROR_EMULATION
+       if (cpu_bus_error)
+               mmu030_hardware_bus_error(addr, v, true, size, fc);
+#endif
+
+       return v;
 }
 
 uae_u32 mmu030_get_generic(uaecptr addr, uae_u32 fc, int size, int flags)
 {
-       mmu030_cache_state = CACHE_ENABLE_ALL;
+       uae_u32 v;
+       mmu030_cache_state = CACHE_ENABLE_ALL;
 
        if (flags & MMU030_SSW_RM) {
                return mmu030_get_generic_lrmw(addr, fc, size, flags);
@@ -2366,10 +2448,18 @@ uae_u32 mmu030_get_generic(uaecptr addr, uae_u32 fc, int size, int flags)
 
        cacheablecheck(addr);
        if (size == sz_byte)
-               return x_phys_get_byte(addr);
+               v = x_phys_get_byte(addr);
        else if (size == sz_word)
-               return x_phys_get_word(addr);
-       return x_phys_get_long(addr);
+               v = x_phys_get_word(addr);
+       else
+               v = x_phys_get_long(addr);
+
+#if BUS_ERROR_EMULATION
+       if (cpu_bus_error)
+               mmu030_hardware_bus_error(addr, v, true, size, fc);
+#endif
+
+       return v;
 }
 
 uae_u8 uae_mmu030_check_fc(uaecptr addr, bool write, uae_u32 size)
index 407404fe2ff66257361be15ddd74647ee97d18c5..f786b8bb8e51720f8e42aba976801d4a9bb55eb8 100644 (file)
@@ -591,7 +591,7 @@ static char bus_error_code[1000], bus_error_code2[1000];
 
 static void do_instruction_buserror(void)
 {
-       if (!using_bus_error)
+       if (!using_bus_error || using_mmu)
                return;
 
        if (bus_error_text[0]) {
@@ -619,7 +619,7 @@ static void check_bus_error_ins(int offset)
 
 static void check_prefetch_bus_error(int offset, int secondprefetchmode)
 {
-       if (!using_bus_error)
+       if (!using_bus_error || using_mmu)
                return;
 
        if (offset < 0) {
@@ -1751,7 +1751,7 @@ static void check_bus_error(const char *name, int offset, int write, int size, c
 {
        int mnemo = g_instr->mnemo;
 
-       if (!using_bus_error)
+       if (!using_bus_error || using_mmu)
                return;
 
        // basic support