From 4183d40cd0d49176e16a2bff10e2f44746503cff Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 5 Apr 2020 17:33:06 +0300 Subject: [PATCH] Hardware bus error support update. --- cpummu.cpp | 12 ++++++++ cpummu30.cpp | 73 ++++++--------------------------------------- gencpu.cpp | 27 +++++++++++++---- include/cpummu.h | 1 + include/cpummu030.h | 15 +++++++++- include/newcpu.h | 2 +- memory.cpp | 72 ++++++++++++++++++++++---------------------- newcpu.cpp | 33 +++++++++++++++----- 8 files changed, 120 insertions(+), 115 deletions(-) diff --git a/cpummu.cpp b/cpummu.cpp index 9f273ab3..2037e98e 100644 --- a/cpummu.cpp +++ b/cpummu.cpp @@ -371,6 +371,18 @@ static ALWAYS_INLINE int mmu_get_fc(bool super, bool data) return (super ? 4 : 0) | (data ? 1 : 2); } +void mmu_hardware_bus_error(uaecptr addr, uae_u32 v, bool read, bool ins, int size) +{ + uae_u32 fc; + + if (ismoves) { + fc = read ? regs.sfc : regs.dfc; + } else { + fc = (regs.s ? 4 : 0) | (ins ? 2 : 1); + } + mmu_bus_error(addr, v, fc, !read, size, 0, true); +} + void mmu_bus_error(uaecptr addr, uae_u32 val, int fc, bool write, int size,uae_u32 status060, bool nonmmu) { if (currprefs.mmu_model == 68040) { diff --git a/cpummu30.cpp b/cpummu30.cpp index 43ed4d42..433c669a 100644 --- a/cpummu30.cpp +++ b/cpummu30.cpp @@ -72,6 +72,7 @@ uae_u32 mmu030_disp_store[2]; uae_u32 mmu030_fmovem_store[2]; uae_u8 mmu030_cache_state; struct mmu030_access mmu030_ad[MAX_MMU030_ACCESS + 1]; +bool ismoves030; static void mmu030_ptest_atc_search(uaecptr logical_addr, uae_u32 fc, bool write); static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level); @@ -1802,6 +1803,7 @@ void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc) fc = regs.mmu_ssw & MMU030_SSW_FC_MASK; flags = regs.mmu_ssw & ~(MMU030_SSW_FC | MMU030_SSW_RC | MMU030_SSW_FB | MMU030_SSW_RB | MMU030_SSW_RW | 7); } + ismoves030 = false; regs.wb3_status = 0; regs.wb2_status = 0; regs.mmu_fault_addr = addr; @@ -1860,19 +1862,22 @@ void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc) THROW(2); } -#if HARDWARE_BUS_ERROR_EMULATION -static void mmu030_hardware_bus_error(uaecptr addr, uae_u32 v, bool read, int size, uae_u32 fc) +void mmu030_hardware_bus_error(uaecptr addr, uae_u32 v, bool read, bool ins, int size) { int flags = size == sz_byte ? MMU030_SSW_SIZE_B : (size == sz_word ? MMU030_SSW_SIZE_W : MMU030_SSW_SIZE_L); + int fc; + if (ismoves030) { + fc = read ? regs.sfc : regs.dfc; + } else { + fc = (regs.s ? 4 : 0) | (ins ? 2 : 1); + } if (!read) { mmu030_data_buffer_out = v; } else { flags |= MMU030_SSW_RW; } - hardware_bus_error = 0; mmu030_page_fault(addr, read, flags, fc); } -#endif static void mmu030_add_data_read_cache(uaecptr addr, uaecptr phys, uae_u32 fc) { @@ -2093,10 +2098,6 @@ void mmu030_put_long(uaecptr addr, uae_u32 val, uae_u32 fc) } cacheablecheck(addr); x_phys_put_long(addr,val); -#if HARDWARE_BUS_ERROR_EMULATION - if (hardware_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) @@ -2123,10 +2124,6 @@ void mmu030_put_word(uaecptr addr, uae_u16 val, uae_u32 fc) } cacheablecheck(addr); x_phys_put_word(addr,val); -#if HARDWARE_BUS_ERROR_EMULATION - if (hardware_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) @@ -2153,10 +2150,6 @@ void mmu030_put_byte(uaecptr addr, uae_u8 val, uae_u32 fc) } cacheablecheck(addr); x_phys_put_byte(addr,val); -#if HARDWARE_BUS_ERROR_EMULATION - if (hardware_bus_error) - mmu030_hardware_bus_error(addr, val, false, sz_byte, fc); -#endif } @@ -2184,10 +2177,6 @@ uae_u32 mmu030_get_long(uaecptr addr, uae_u32 fc) } cacheablecheck(addr); uae_u32 v = x_phys_get_long(addr); -#if HARDWARE_BUS_ERROR_EMULATION - if (hardware_bus_error) - mmu030_hardware_bus_error(addr, v, true, sz_long, fc); -#endif return v; } @@ -2215,10 +2204,6 @@ uae_u16 mmu030_get_word(uaecptr addr, uae_u32 fc) } cacheablecheck(addr); uae_u16 v = x_phys_get_word(addr); -#if HARDWARE_BUS_ERROR_EMULATION - if (hardware_bus_error) - mmu030_hardware_bus_error(addr, v, true, sz_word, fc); -#endif return v; } @@ -2246,10 +2231,6 @@ uae_u8 mmu030_get_byte(uaecptr addr, uae_u32 fc) } cacheablecheck(addr); uae_u8 v = x_phys_get_byte(addr); -#if HARDWARE_BUS_ERROR_EMULATION - if (hardware_bus_error) - mmu030_hardware_bus_error(addr, v, true, sz_byte, fc); -#endif return v; } @@ -2265,10 +2246,6 @@ uae_u32 mmu030_get_ilong(uaecptr addr, uae_u32 fc) #else mmu030_cache_state = mmu030.mmu030_cache_state; v = x_phys_get_ilong(mmu030.mmu030_last_physical_address + (addr & mmu030.translation.page.mask)); -#if HARDWARE_BUS_ERROR_EMULATION - if (hardware_bus_error) - mmu030_hardware_bus_error(addr, v, true, sz_long, fc); -#endif return v; #endif } @@ -2287,10 +2264,6 @@ uae_u32 mmu030_get_ilong(uaecptr addr, uae_u32 fc) } cacheablecheck(addr); v = x_phys_get_ilong(addr); -#if HARDWARE_BUS_ERROR_EMULATION - if (hardware_bus_error) - mmu030_hardware_bus_error(addr, v, true, sz_long, fc); -#endif return v; } @@ -2305,10 +2278,6 @@ uae_u16 mmu030_get_iword(uaecptr addr, uae_u32 fc) { #else mmu030_cache_state = mmu030.mmu030_cache_state; v = x_phys_get_iword(mmu030.mmu030_last_physical_address + (addr & mmu030.translation.page.mask)); -#if HARDWARE_BUS_ERROR_EMULATION - if (hardware_bus_error) - mmu030_hardware_bus_error(addr, v, true, sz_word, fc); -#endif return v; #endif } @@ -2327,10 +2296,6 @@ uae_u16 mmu030_get_iword(uaecptr addr, uae_u32 fc) { } cacheablecheck(addr); v = x_phys_get_iword(addr); -#if HARDWARE_BUS_ERROR_EMULATION - if (hardware_bus_error) - mmu030_hardware_bus_error(addr, v, true, sz_word, fc); -#endif return v; } @@ -2357,11 +2322,6 @@ 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 HARDWARE_BUS_ERROR_EMULATION - if (hardware_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) @@ -2390,11 +2350,6 @@ 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 HARDWARE_BUS_ERROR_EMULATION - if (hardware_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) @@ -2420,11 +2375,6 @@ static uae_u32 mmu030_get_generic_lrmw(uaecptr addr, uae_u32 fc, int size, int f else v = x_phys_get_long(addr); -#if HARDWARE_BUS_ERROR_EMULATION - if (hardware_bus_error) - mmu030_hardware_bus_error(addr, v, true, size, fc); -#endif - return v; } @@ -2456,11 +2406,6 @@ uae_u32 mmu030_get_generic(uaecptr addr, uae_u32 fc, int size, int flags) else v = x_phys_get_long(addr); -#if HARDWARE_BUS_ERROR_EMULATION - if (hardware_bus_error) - mmu030_hardware_bus_error(addr, v, true, size, fc); -#endif - return v; } diff --git a/gencpu.cpp b/gencpu.cpp index b639a23e..c5c9237c 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -117,6 +117,7 @@ static char g_srcname[100]; static int loopmode; static int loopmodeextra; static int loopmode_set; +static int postfix; #define GENA_GETV_NO_FETCH 0 #define GENA_GETV_FETCH 1 @@ -299,6 +300,23 @@ static instr *curi_ce020; static bool no_prefetch_ce020; static bool got_ea_ce020; +static bool needbuserror(void) +{ + if (!using_bus_error) + return false; + if (using_mmu) + return false; +#if CPU_TESTER + return true; +#else + // only 68000/010 need cpuemu internal bus error handling + // 68020+ use CATCH/TRY method + if (postfix >= 10 && postfix < 20) + return true; + return false; +#endif +} + // 68010-40 needs different implementation than 68060 static bool next_level_060_to_040(void) { @@ -760,7 +778,7 @@ static char bus_error_code[1000], bus_error_code2[1000]; static void do_instruction_buserror(void) { - if (!using_bus_error || using_mmu) + if (!needbuserror()) return; if (bus_error_text[0]) { @@ -799,7 +817,7 @@ static void check_bus_error_ins_opcode(int offset) static void check_prefetch_bus_error(int offset, int secondprefetchmode) { - if (!using_bus_error || using_mmu) + if (!needbuserror()) return; if (offset < 0) { @@ -2069,7 +2087,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 || using_mmu) + if (!needbuserror()) return; // basic support @@ -8691,9 +8709,6 @@ static void generate_includes (FILE * f, int id) "#endif\n"); } -static int postfix; - - static char *decodeEA (amodes mode, wordsizes size) { static char buffer[80]; diff --git a/include/cpummu.h b/include/cpummu.h index b645197e..83b650e8 100644 --- a/include/cpummu.h +++ b/include/cpummu.h @@ -176,6 +176,7 @@ extern void mmu_bus_error_ttr_write_fault(uaecptr addr, bool super, bool data, u extern int mmu_match_ttr_write(uaecptr addr, bool super, bool data, uae_u32 val, int size); extern int mmu_match_ttr_maybe_write(uaecptr addr, bool super, bool data, int size, bool write); extern uaecptr mmu_translate(uaecptr addr, uae_u32 val, bool super, bool data, bool write, int size); +extern void mmu_hardware_bus_error(uaecptr addr, uae_u32 v, bool read, bool ins, int size); extern uae_u32 REGPARAM3 mmu060_get_rmw_bitfield (uae_u32 src, uae_u32 bdata[2], uae_s32 offset, int width) REGPARAM; extern void REGPARAM3 mmu060_put_rmw_bitfield (uae_u32 dst, uae_u32 bdata[2], uae_u32 val, uae_s32 offset, int width) REGPARAM; diff --git a/include/cpummu030.h b/include/cpummu030.h index 8222b5ff..3ddddcf4 100644 --- a/include/cpummu030.h +++ b/include/cpummu030.h @@ -26,6 +26,7 @@ extern uae_u32 mmu030_data_buffer_out; extern uae_u32 mmu030_disp_store[2]; extern uae_u32 mmu030_fmovem_store[2]; extern uae_u8 mmu030_cache_state, mmu030_cache_state_default; +extern bool ismoves030; #define MMU030_STATEFLAG1_FMOVEM 0x2000 #define MMU030_STATEFLAG1_MOVEM1 0x4000 @@ -70,7 +71,7 @@ void mmu030_flush_atc_all(void); void mmu030_reset(int hardreset); void mmu030_set_funcs(void); uaecptr mmu030_translate(uaecptr addr, bool super, bool data, bool write); - +void mmu030_hardware_bus_error(uaecptr addr, uae_u32 v, bool read, bool ins, int size); void mmu030_put_long(uaecptr addr, uae_u32 val, uae_u32 fc); void mmu030_put_word(uaecptr addr, uae_u16 val, uae_u32 fc); void mmu030_put_byte(uaecptr addr, uae_u8 val, uae_u32 fc); @@ -366,7 +367,9 @@ static ALWAYS_INLINE uae_u32 sfc030_get_long_state(uaecptr addr) { uae_u32 v; ACCESS_CHECK_GET + ismoves030 = true; v = sfc030_get_long(addr); + ismoves030 = false; ACCESS_EXIT_GET return v; } @@ -374,7 +377,9 @@ static ALWAYS_INLINE uae_u16 sfc030_get_word_state(uaecptr addr) { uae_u32 v; ACCESS_CHECK_GET + ismoves030 = true; v = sfc030_get_word(addr); + ismoves030 = false; ACCESS_EXIT_GET return v; } @@ -382,7 +387,9 @@ static ALWAYS_INLINE uae_u8 sfc030_get_byte_state(uaecptr addr) { uae_u32 v; ACCESS_CHECK_GET + ismoves030 = true; v = sfc030_get_byte(addr); + ismoves030 = false; ACCESS_EXIT_GET return v; } @@ -390,19 +397,25 @@ static ALWAYS_INLINE uae_u8 sfc030_get_byte_state(uaecptr addr) static ALWAYS_INLINE void dfc030_put_long_state(uaecptr addr, uae_u32 v) { ACCESS_CHECK_PUT + ismoves030 = true; dfc030_put_long(addr, v); + ismoves030 = false; ACCESS_EXIT_PUT } static ALWAYS_INLINE void dfc030_put_word_state(uaecptr addr, uae_u32 v) { ACCESS_CHECK_PUT + ismoves030 = true; dfc030_put_word(addr, v); + ismoves030 = false; ACCESS_EXIT_PUT } static ALWAYS_INLINE void dfc030_put_byte_state(uaecptr addr, uae_u32 v) { ACCESS_CHECK_PUT + ismoves030 = true; dfc030_put_byte(addr, v); + ismoves030 = false; ACCESS_EXIT_PUT } diff --git a/include/newcpu.h b/include/newcpu.h index 1849ce75..ae219e94 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -736,7 +736,7 @@ extern void exception3_write_access(uae_u32 opcode, uaecptr addr, int size, uae_ extern void exception3_read_prefetch(uae_u32 opcode, uaecptr addr); extern void exception3_read_prefetch_only(uae_u32 opcode, uaecptr addr); extern void exception3_notinstruction(uae_u32 opcode, uaecptr addr); -extern void exception2 (uaecptr addr, bool read, int size, uae_u32 fc); +extern void hardware_exception2(uaecptr addr, uae_u32 v, bool read, bool ins, int size); extern void exception2_setup(uae_u32 opcode, uaecptr addr, bool read, int size, uae_u32 fc); extern void exception2_read(uae_u32 opcode, uaecptr addr, int size, int fc); extern void exception2_write(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int fc); diff --git a/memory.cpp b/memory.cpp index a553dbbb..0a15b8d1 100644 --- a/memory.cpp +++ b/memory.cpp @@ -223,7 +223,7 @@ static bool maybe_map_boot_rom(uaecptr addr) return false; } -static void dummylog (int rw, uaecptr addr, int size, uae_u32 val, int ins) +static void dummylog(int rw, uaecptr addr, int size, uae_u32 val, int ins) { /* ignore Zorro3 expansion space */ if (addr >= AUTOCONFIG_Z3 && addr <= AUTOCONFIG_Z3 + 0x200) @@ -238,7 +238,7 @@ static void dummylog (int rw, uaecptr addr, int size, uae_u32 val, int ins) return; if (addr >= 0x07f7fff0 && addr <= 0x07ffffff) return; - if (debugmem_extinvalidmem(addr, val, rw ? size : -size)) + if (debugmem_extinvalidmem(addr, val, rw ? (1 << size) : -(1 << size))) return; if ((illegal_count >= MAX_ILG && MAX_ILG > 0) && !memwatch_access_validator) return; @@ -246,13 +246,13 @@ static void dummylog (int rw, uaecptr addr, int size, uae_u32 val, int ins) illegal_count++; if (ins) { write_log (_T("WARNING: Illegal opcode %cget at %08x PC=%x\n"), - size == 2 ? 'w' : 'l', addr, M68K_GETPC); + size == sz_word ? 'w' : 'l', addr, M68K_GETPC); } else if (rw) { write_log (_T("Illegal %cput at %08x=%08x PC=%x\n"), - size == 1 ? 'b' : size == 2 ? 'w' : 'l', addr, val, M68K_GETPC); + size == sz_byte ? 'b' : size == sz_word ? 'w' : 'l', addr, val, M68K_GETPC); } else { write_log (_T("Illegal %cget at %08x PC=%x\n"), - size == 1 ? 'b' : size == 2 ? 'w' : 'l', addr, M68K_GETPC); + size == sz_byte ? 'b' : size == sz_word ? 'w' : 'l', addr, M68K_GETPC); } } @@ -297,11 +297,11 @@ void dummy_put (uaecptr addr, int size, uae_u32 val) flash_write(addr, val); #endif - if (gary_nonrange(addr) || (size > 1 && gary_nonrange(addr + size - 1))) { + if (gary_nonrange(addr) || (size > sz_byte && gary_nonrange(addr + (1 << size) - 1))) { if (gary_timeout) - gary_wait (addr, size, true); + gary_wait(addr, size, true); if (gary_toenb && currprefs.mmu_model) - exception2 (addr, true, size, regs.s ? 4 : 0); + hardware_exception2(addr, val, false, false, size); } } @@ -317,7 +317,7 @@ static uae_u32 nonexistingdata(void) uae_u32 dummy_get_safe(uaecptr addr, int size, bool inst, uae_u32 defvalue) { uae_u32 v = defvalue; - uae_u32 mask = size == 4 ? 0xffffffff : (1 << (size * 8)) - 1; + uae_u32 mask = size == sz_long ? 0xffffffff : (1 << ((1 << size) * 8)) - 1; if (currprefs.cpu_model >= 68040) return v & mask; if (!currprefs.cpu_compatible) @@ -332,17 +332,17 @@ uae_u32 dummy_get_safe(uaecptr addr, int size, bool inst, uae_u32 defvalue) if (currprefs.cs_unmapped_space == 2) return 0xffffffff & mask; if ((currprefs.cpu_model <= 68010) || (currprefs.cpu_model == 68020 && (currprefs.chipset_mask & CSMASK_AGA) && currprefs.address_space_24)) { - if (size == 4) { - v = regs.db & 0xffff; + if (size == sz_long) { + v = regs.irc & 0xffff; if (addr & 1) v = (v << 8) | (v >> 8); v = (v << 16) | v; - } else if (size == 2) { - v = regs.db & 0xffff; + } else if (size == sz_word) { + v = regs.irc & 0xffff; if (addr & 1) v = (v << 8) | (v >> 8); } else { - v = regs.db; + v = regs.irc; v = (addr & 1) ? (v & 0xff) : ((v >> 8) & 0xff); } } @@ -382,17 +382,17 @@ uae_u32 dummy_get (uaecptr addr, int size, bool inst, uae_u32 defvalue) } #endif - if ((size == 2 || size == 4) && inst && maybe_map_boot_rom(addr)) { - if (size == 2) + if ((size == sz_word || size == sz_long) && inst && maybe_map_boot_rom(addr)) { + if (size == sz_word) return get_word(addr); return get_long(addr); } - if (gary_nonrange(addr) || (size > 1 && gary_nonrange(addr + size - 1))) { + if (gary_nonrange(addr) || (size > sz_byte && gary_nonrange(addr + (1 << size) - 1))) { if (gary_timeout) - gary_wait (addr, size, false); + gary_wait(addr, size, false); if (gary_toenb) - exception2 (addr, false, size, (regs.s ? 4 : 0) | (inst ? 0 : 1)); + hardware_exception2(addr, 0, true, false, size); return v; } @@ -402,53 +402,53 @@ uae_u32 dummy_get (uaecptr addr, int size, bool inst, uae_u32 defvalue) static uae_u32 REGPARAM2 dummy_lget (uaecptr addr) { if (currprefs.illegal_mem) - dummylog (0, addr, 4, 0, 0); - return dummy_get (addr, 4, false, nonexistingdata()); + dummylog(0, addr, sz_long, 0, 0); + return dummy_get(addr, sz_long, false, nonexistingdata()); } uae_u32 REGPARAM2 dummy_lgeti (uaecptr addr) { if (currprefs.illegal_mem) - dummylog (0, addr, 4, 0, 1); - return dummy_get (addr, 4, true, nonexistingdata()); + dummylog(0, addr, sz_long, 0, 1); + return dummy_get(addr, sz_long, true, nonexistingdata()); } static uae_u32 REGPARAM2 dummy_wget (uaecptr addr) { if (currprefs.illegal_mem) - dummylog (0, addr, 2, 0, 0); - return dummy_get (addr, 2, false, nonexistingdata()); + dummylog(0, addr, sz_word, 0, 0); + return dummy_get(addr, sz_word, false, nonexistingdata()); } uae_u32 REGPARAM2 dummy_wgeti (uaecptr addr) { if (currprefs.illegal_mem) - dummylog (0, addr, 2, 0, 1); - return dummy_get (addr, 2, true, nonexistingdata()); + dummylog(0, addr, sz_word, 0, 1); + return dummy_get(addr, sz_word, true, nonexistingdata()); } static uae_u32 REGPARAM2 dummy_bget (uaecptr addr) { if (currprefs.illegal_mem) - dummylog (0, addr, 1, 0, 0); - return dummy_get (addr, 1, false, nonexistingdata()); + dummylog(0, addr, sz_byte, 0, 0); + return dummy_get(addr, sz_byte, false, nonexistingdata()); } static void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l) { if (currprefs.illegal_mem) - dummylog (1, addr, 4, l, 0); - dummy_put (addr, 4, l); + dummylog(1, addr, sz_long, l, 0); + dummy_put(addr, sz_long, l); } static void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w) { if (currprefs.illegal_mem) - dummylog (1, addr, 2, w, 0); - dummy_put (addr, 2, w); + dummylog(1, addr, sz_word, w, 0); + dummy_put(addr, sz_word, w); } static void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b) { if (currprefs.illegal_mem) - dummylog (1, addr, 1, b, 0); - dummy_put (addr, 1, b); + dummylog(1, addr, sz_byte, b, 0); + dummy_put(addr, sz_byte, b); } static int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size) @@ -1144,7 +1144,7 @@ uae_u8 *REGPARAM2 default_xlate (uaecptr addr) memory_map_dump (); } if (0 || (gary_toenb && (gary_nonrange(addr) || (size > 1 && gary_nonrange(addr + size - 1))))) { - exception2 (addr, false, size, regs.s ? 4 : 0); + hardware_exception2(addr, 0, true, true, size); } else { cpu_halt(CPU_HALT_OPCODE_FETCH_FROM_NON_EXISTING_ADDRESS); } diff --git a/newcpu.cpp b/newcpu.cpp index d64ad64d..e97df264 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -89,6 +89,7 @@ static int baseclock; int m68k_pc_indirect; bool m68k_interrupt_delay; static bool m68k_reset_delay; +static bool ismoves_nommu; static volatile uae_atomic uae_interrupt; static volatile uae_atomic uae_interrupts2[IRQ_SOURCE_MAX]; @@ -7242,19 +7243,25 @@ void exception2_setup(uae_u32 opcode, uaecptr addr, bool read, int size, uae_u32 } } -void exception2(uaecptr addr, bool read, int size, uae_u32 fc) +// Common hardware bus error entry point. Both for MMU and non-MMU emulation. +void hardware_exception2(uaecptr addr, uae_u32 v, bool read, bool ins, int size) { if (currprefs.mmu_model) { if (currprefs.mmu_model == 68030) { - uae_u32 flags = size == 1 ? MMU030_SSW_SIZE_B : (size == 2 ? MMU030_SSW_SIZE_W : MMU030_SSW_SIZE_L); - mmu030_page_fault (addr, read, flags, fc); + mmu030_hardware_bus_error(addr, v, read, ins, size); } else { - mmu_bus_error (addr, 0, fc, read == false, size, 0, true); + mmu_hardware_bus_error(addr, v, read, ins, size); } - } else { - exception2_setup(regs.opcode, addr, read, size == 1 ? 0 : (size == 2 ? 1 : 2), fc); - THROW(2); + return; + } + int fc = (regs.s ? 4 : 0) | (ins ? 2 : 1); + if (ismoves_nommu) { + ismoves_nommu = false; + fc = read ? regs.sfc : regs.dfc; } + // Non-MMU + exception2_setup(regs.opcode, addr, read, size, fc); + THROW(2); } void exception2_read(uae_u32 opcode, uaecptr addr, int size, int fc) @@ -9489,36 +9496,48 @@ extern bool cpuboard_fc_check(uaecptr addr, uae_u32 *v, int size, bool write); uae_u32 sfc_nommu_get_byte(uaecptr addr) { uae_u32 v; + ismoves_nommu = true; if (!cpuboard_fc_check(addr, &v, 0, false)) v = x_get_byte(addr); + ismoves_nommu = false; return v; } uae_u32 sfc_nommu_get_word(uaecptr addr) { uae_u32 v; + ismoves_nommu = true; if (!cpuboard_fc_check(addr, &v, 1, false)) v = x_get_word(addr); + ismoves_nommu = false; return v; } uae_u32 sfc_nommu_get_long(uaecptr addr) { uae_u32 v; + ismoves_nommu = true; if (!cpuboard_fc_check(addr, &v, 2, false)) v = x_get_long(addr); + ismoves_nommu = false; return v; } void dfc_nommu_put_byte(uaecptr addr, uae_u32 v) { + ismoves_nommu = true; if (!cpuboard_fc_check(addr, &v, 0, true)) x_put_byte(addr, v); + ismoves_nommu = false; } void dfc_nommu_put_word(uaecptr addr, uae_u32 v) { + ismoves_nommu = true; if (!cpuboard_fc_check(addr, &v, 1, true)) x_put_word(addr, v); + ismoves_nommu = false; } void dfc_nommu_put_long(uaecptr addr, uae_u32 v) { + ismoves_nommu = true; if (!cpuboard_fc_check(addr, &v, 2, true)) x_put_long(addr, v); + ismoves_nommu = false; } -- 2.47.3