From: Toni Wilen Date: Mon, 6 Jan 2020 09:00:51 +0000 (+0200) Subject: 68030 MMU hardware bus error support. X-Git-Tag: 4400~188 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=0bc0c9514ad5bfeee14fffc7cb24f27615038bf6;p=francis%2Fwinuae.git 68030 MMU hardware bus error support. --- diff --git a/cpummu30.cpp b/cpummu30.cpp index 4d744c54..e209848c 100644 --- a/cpummu30.cpp +++ b/cpummu30.cpp @@ -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) diff --git a/gencpu.cpp b/gencpu.cpp index 407404fe..f786b8bb 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -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