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) {
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);
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;
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)
{
}
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)
}
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)
}
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
}
}
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;
}
}
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;
}
}
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;
}
#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
}
}
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;
}
#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
}
}
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;
}
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)
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)
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;
}
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;
}
static int loopmode;
static int loopmodeextra;
static int loopmode_set;
+static int postfix;
#define GENA_GETV_NO_FETCH 0
#define GENA_GETV_FETCH 1
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)
{
static void do_instruction_buserror(void)
{
- if (!using_bus_error || using_mmu)
+ if (!needbuserror())
return;
if (bus_error_text[0]) {
static void check_prefetch_bus_error(int offset, int secondprefetchmode)
{
- if (!using_bus_error || using_mmu)
+ if (!needbuserror())
return;
if (offset < 0) {
{
int mnemo = g_instr->mnemo;
- if (!using_bus_error || using_mmu)
+ if (!needbuserror())
return;
// basic support
"#endif\n");
}
-static int postfix;
-
-
static char *decodeEA (amodes mode, wordsizes size)
{
static char buffer[80];
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;
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
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);
{
uae_u32 v;
ACCESS_CHECK_GET
+ ismoves030 = true;
v = sfc030_get_long(addr);
+ ismoves030 = false;
ACCESS_EXIT_GET
return v;
}
{
uae_u32 v;
ACCESS_CHECK_GET
+ ismoves030 = true;
v = sfc030_get_word(addr);
+ ismoves030 = false;
ACCESS_EXIT_GET
return v;
}
{
uae_u32 v;
ACCESS_CHECK_GET
+ ismoves030 = true;
v = sfc030_get_byte(addr);
+ ismoves030 = false;
ACCESS_EXIT_GET
return v;
}
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
}
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);
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)
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;
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);
}
}
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);
}
}
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)
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);
}
}
}
#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;
}
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)
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);
}
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];
}
}
-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)
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;
}