#include "newcpu.h"
#include "debug.h"
#include "cpummu030.h"
+#include "cputbl.h"
#define MMU030_OP_DBG_MSG 0
#define MMU030_ATC_DBG_MSG 0
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
}
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)
}
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)
}
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
}
}
}
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)
}
}
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)
}
}
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
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;
}
}
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
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;
}
}
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 */
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)
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) {
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);
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)