From 1fcc151bc9b7d6f0ef873d32555ff7b8a3d3e075 Mon Sep 17 00:00:00 2001 From: "R. Belmont" Date: Mon, 21 Feb 2011 21:40:58 +0000 Subject: [PATCH] M680x0 updates [Hans Ostermeyer] - Instruction cache emulated on '020 and later - Fixed interaction between MMU and bfextu/bfexts/bfins - Added fsgldiv, fsglmul, and fscc FPU instructions - Fixed fault address in stack frame - Fixed supervisor violation bit in MMU status register - Add fmovem modes 1 and 3 - Various other MMU fixes --- src/emu/cpu/m68000/m68k_in.c | 68 +++++++++++++++++++++------------ src/emu/cpu/m68000/m68kcpu.c | 22 ++++++----- src/emu/cpu/m68000/m68kcpu.h | 73 +++++++++++++++++++++++++++++++----- src/emu/cpu/m68000/m68kfpu.c | 73 ++++++++++++++++++++++++++++++++---- src/emu/cpu/m68000/m68kmmu.h | 60 ++++++++++++++++------------- 5 files changed, 221 insertions(+), 75 deletions(-) diff --git a/src/emu/cpu/m68000/m68k_in.c b/src/emu/cpu/m68000/m68k_in.c index 29c1b8b0883..8e76a54c97b 100644 --- a/src/emu/cpu/m68000/m68k_in.c +++ b/src/emu/cpu/m68000/m68k_in.c @@ -2634,17 +2634,20 @@ M68KMAKE_OP(bfexts, 32, ., .) if(BIT_5(word2)) width = REG_D[width&7]; - /* Offset is signed so we have to use ugly math =( */ - ea += offset / 8; - offset %= 8; - if(offset < 0) + if(BIT_B(word2)) { - offset += 8; - ea--; + /* Offset is signed so we have to use ugly math =( */ + ea += offset / 8; + offset %= 8; + if(offset < 0) + { + offset += 8; + ea--; + } } width = ((width-1) & 31) + 1; - data = m68ki_read_32(m68k, ea); + data = (offset+width) < 16 ? (m68ki_read_16(m68k, ea) << 16) : m68ki_read_32(m68k, ea); data = MASK_OUT_ABOVE_32(data< 32) @@ -2813,7 +2819,7 @@ M68KMAKE_OP(bfffo, 32, ., .) } width = ((width-1) & 31) + 1; - data = m68ki_read_32(m68k, ea); + data = (offset+width) < 16 ? (m68ki_read_16(m68k, ea) << 16) : m68ki_read_32(m68k, ea); data = MASK_OUT_ABOVE_32(data< 32) @@ -2902,13 +2908,16 @@ M68KMAKE_OP(bfins, 32, ., .) if(BIT_5(word2)) width = REG_D[width&7]; - /* Offset is signed so we have to use ugly math =( */ - ea += offset / 8; - offset %= 8; - if(offset < 0) + if(BIT_B(word2)) { - offset += 8; - ea--; + /* Offset is signed so we have to use ugly math =( */ + ea += offset / 8; + offset %= 8; + if(offset < 0) + { + offset += 8; + ea--; + } } width = ((width-1) & 31) + 1; @@ -2920,11 +2929,18 @@ M68KMAKE_OP(bfins, 32, ., .) m68k->not_z_flag = insert_base; insert_long = insert_base >> offset; - data_long = m68ki_read_32(m68k, ea); + data_long = (offset+width) < 16 ? (m68ki_read_16(m68k, ea) << 16) : m68ki_read_32(m68k, ea); m68k->v_flag = VFLAG_CLEAR; m68k->c_flag = CFLAG_CLEAR; - m68ki_write_32(m68k, ea, (data_long & ~mask_long) | insert_long); + if((width + offset) < 16) + { + m68ki_write_16(m68k, ea, ((data_long & ~mask_long) | insert_long) >> 16); + } + else + { + m68ki_write_32(m68k, ea, (data_long & ~mask_long) | insert_long); + } if((width + offset) > 32) { @@ -6684,6 +6700,12 @@ M68KMAKE_OP(movec, 32, rc, .) { m68k->cacr = REG_DA[(word2 >> 12) & 15] & 0x0f; } + +// logerror("movec to cacr=%04x\n", m68k->cacr); + if (m68k->cacr & (M68K_CACR_CI | M68K_CACR_CEI)) + { + m68ki_ic_clear(m68k); + } return; } m68ki_exception_illegal(m68k); diff --git a/src/emu/cpu/m68000/m68kcpu.c b/src/emu/cpu/m68000/m68kcpu.c index 563f5e213f7..734e6eef04f 100644 --- a/src/emu/cpu/m68000/m68kcpu.c +++ b/src/emu/cpu/m68000/m68kcpu.c @@ -632,9 +632,9 @@ static CPU_EXECUTE( m68k ) /* Call external hook to peek at CPU */ debugger_instruction_hook(device, REG_PC); - // FIXME: remove this -// void apollo_debug_instruction(device_t *device); -// apollo_debug_instruction(device); + /* call external instruction hook (independent of debug mode) */ + if (m68k->instruction_hook != NULL) + m68k->instruction_hook(device, REG_PC); /* Record previous program counter */ REG_PPC = REG_PC; @@ -672,13 +672,6 @@ static CPU_EXECUTE( m68k ) { UINT32 sr; -// const char * disassemble(m68ki_cpu_core *m68k, offs_t pc); -// logerror( -// "PMMU: pc=%08x sp=%08x va=%08x bus error: %s\n", -// REG_PPC, REG_A[7], m68k->mmu_tmp_buserror_address, -// (m68k->mmu_tmp_buserror_address == REG_PPC) ? "-" -// : disassemble(m68k, REG_PPC)); - m68k->mmu_tmp_buserror_occurred = 0; // restore cpu address registers to value at start of instruction @@ -821,6 +814,15 @@ static CPU_RESET( m68k ) /* flush the MMU's cache */ pmmu_atc_flush(m68k); + + if(CPU_TYPE_IS_EC020_PLUS(m68k->cpu_type)) + { + // clear instruction cache + m68ki_ic_clear(m68k); + } + + // disable instruction hook + m68k->instruction_hook = NULL; } static CPU_DISASSEMBLE( m68k ) diff --git a/src/emu/cpu/m68000/m68kcpu.h b/src/emu/cpu/m68000/m68kcpu.h index 21c7e31bf60..ab94ea2e635 100644 --- a/src/emu/cpu/m68000/m68kcpu.h +++ b/src/emu/cpu/m68000/m68kcpu.h @@ -103,6 +103,15 @@ typedef struct _m68ki_cpu_core m68ki_cpu_core; /* MMU constants */ #define MMU_ATC_ENTRIES (22) // 68851 has 64, 030 has 22 +/* instruction cache constants */ +#define M68K_IC_SIZE 128 + +#define M68K_CACR_IBE 0x10 // Instruction Burst Enable +#define M68K_CACR_CI 0x08 // Clear Instruction Cache +#define M68K_CACR_CEI 0x04 // Clear Entry in Instruction Cache +#define M68K_CACR_FI 0x02 // Freeze Instruction Cache +#define M68K_CACR_EI 0x01 // Enable Instruction Cache + /* ======================================================================== */ /* ================================ MACROS ================================ */ /* ======================================================================== */ @@ -706,6 +715,13 @@ struct _m68ki_cpu_core UINT16 mmu_tmp_rw; /* temporary hack: read/write (1/0) for the mmu */ UINT32 mmu_tmp_buserror_address; /* temporary hack: (first) bus error address */ UINT16 mmu_tmp_buserror_occurred; /* temporary hack: flag that bus error has occurred from mmu */ + + UINT32 ic_address[M68K_IC_SIZE]; /* instruction cache address data */ + UINT16 ic_data[M68K_IC_SIZE]; /* instruction cache content data */ + + /* external instruction hook (does not depend on debug mode) */ + typedef int (*instruction_hook_t)(device_t *device, offs_t curpc); + instruction_hook_t instruction_hook; }; @@ -882,6 +898,43 @@ INLINE void m68kx_write_memory_32_pd(m68ki_cpu_core *m68k, unsigned int address, /* ---------------------------- Read Immediate ---------------------------- */ +// clear the instruction cache +INLINE void m68ki_ic_clear(m68ki_cpu_core *m68k) +{ + int i; + for (i=0; i< M68K_IC_SIZE; i++) { + m68k->ic_address[i] = ~0; + } +} + +// read immediate word using the instruction cache + +INLINE UINT32 m68ki_ic_readimm16(m68ki_cpu_core *m68k, UINT32 address) +{ + if(CPU_TYPE_IS_EC020_PLUS(m68k->cpu_type) && (m68k->cacr & M68K_CACR_EI)) + { + UINT32 ic_offset = (address >> 1) % M68K_IC_SIZE; + if (m68k->ic_address[ic_offset] == address) + { + return m68k->ic_data[ic_offset]; + } + else + { + UINT32 data = m68k->memory.readimm16(address); + if (!m68k->mmu_tmp_buserror_occurred) + { + m68k->ic_data[ic_offset] = data; + m68k->ic_address[ic_offset] = address; + } + return data; + } + } + else + { + return m68k->memory.readimm16(address); + } +} + /* Handles all immediate reads, does address error check, function code setting, * and prefetching if they are enabled in m68kconf.h */ @@ -896,14 +949,14 @@ INLINE UINT32 m68ki_read_imm_16(m68ki_cpu_core *m68k) if(REG_PC != m68k->pref_addr) { - m68k->pref_data = m68k->memory.readimm16(REG_PC); + m68k->pref_data = m68ki_ic_readimm16(m68k, REG_PC); m68k->pref_addr = m68k->mmu_tmp_buserror_occurred ? ~0 : REG_PC; } result = MASK_OUT_ABOVE_16(m68k->pref_data); REG_PC += 2; if (!m68k->mmu_tmp_buserror_occurred) { // prefetch only if no bus error occurred in opcode fetch - m68k->pref_data = m68k->memory.readimm16(REG_PC); + m68k->pref_data = m68ki_ic_readimm16(m68k, REG_PC); m68k->pref_addr = m68k->mmu_tmp_buserror_occurred ? ~0 : REG_PC; // ignore bus error on prefetch m68k->mmu_tmp_buserror_occurred = 0; @@ -924,16 +977,16 @@ INLINE UINT32 m68ki_read_imm_32(m68ki_cpu_core *m68k) if(REG_PC != m68k->pref_addr) { m68k->pref_addr = REG_PC; - m68k->pref_data = m68k->memory.readimm16(m68k->pref_addr); + m68k->pref_data = m68ki_ic_readimm16(m68k, m68k->pref_addr); } temp_val = MASK_OUT_ABOVE_16(m68k->pref_data); REG_PC += 2; m68k->pref_addr = REG_PC; - m68k->pref_data = m68k->memory.readimm16(m68k->pref_addr); + m68k->pref_data = m68ki_ic_readimm16(m68k, m68k->pref_addr); temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | MASK_OUT_ABOVE_16(m68k->pref_data)); REG_PC += 2; - m68k->pref_data = m68k->memory.readimm16(REG_PC); + m68k->pref_data = m68ki_ic_readimm16(m68k, REG_PC); m68k->pref_addr = m68k->mmu_tmp_buserror_occurred ? ~0 : REG_PC; return temp_val; @@ -1543,7 +1596,9 @@ void m68ki_stack_frame_1010(m68ki_cpu_core *m68k, UINT32 sr, UINT32 vector, UINT m68ki_push_16(m68k, 0); /* SPECIAL STATUS REGISTER */ - m68ki_push_16(m68k, 0); + // set bit for: Rerun Faulted bus Cycle, or run pending prefetch + // set FC + m68ki_push_16(m68k, 0x0100 | m68k->mmu_tmp_fc ); /* INTERNAL REGISTER */ m68ki_push_16(m68k, 0); @@ -1590,7 +1645,7 @@ void m68ki_stack_frame_1011(m68ki_cpu_core *m68k, UINT32 sr, UINT32 vector, UINT m68ki_push_32(m68k, 0); /* STAGE B ADDRESS (2 words) */ - m68ki_push_32(m68k, fault_address); + m68ki_push_32(m68k, 0); /* INTERNAL REGISTER (4 words) */ m68ki_push_32(m68k, 0); @@ -1606,7 +1661,7 @@ void m68ki_stack_frame_1011(m68ki_cpu_core *m68k, UINT32 sr, UINT32 vector, UINT m68ki_push_16(m68k, 0); /* DATA CYCLE FAULT ADDRESS (2 words) */ - m68ki_push_32(m68k, 0); + m68ki_push_32(m68k, fault_address); /* INSTRUCTION PIPE STAGE B */ m68ki_push_16(m68k, 0); @@ -1615,7 +1670,7 @@ void m68ki_stack_frame_1011(m68ki_cpu_core *m68k, UINT32 sr, UINT32 vector, UINT m68ki_push_16(m68k, 0); /* SPECIAL STATUS REGISTER */ - m68ki_push_16(m68k, 0); + m68ki_push_16(m68k, 0x0100 | m68k->mmu_tmp_fc); /* INTERNAL REGISTER */ m68ki_push_16(m68k, 0); diff --git a/src/emu/cpu/m68000/m68kfpu.c b/src/emu/cpu/m68000/m68kfpu.c index 15bfb7f812a..9de8f4c7b2d 100644 --- a/src/emu/cpu/m68000/m68kfpu.c +++ b/src/emu/cpu/m68000/m68kfpu.c @@ -1318,6 +1318,11 @@ static void fpgen_rm_reg(m68ki_cpu_core *m68k, UINT16 w2) m68k->remaining_cycles -= 109; break; } +// case 0x0e: // FSIN +// { +// // TODO +// break; +// } case 0x18: // FABS { REG_FP[dst] = source; @@ -1365,6 +1370,12 @@ static void fpgen_rm_reg(m68ki_cpu_core *m68k, UINT16 w2) m68k->remaining_cycles -= 11; break; } + case 0x24: // FSGLDIV + { + REG_FP[dst] = floatx80_div(REG_FP[dst], source); + m68k->remaining_cycles -= 43; // // ? (value is from FDIV) + break; + } case 0x25: // FREM { REG_FP[dst] = floatx80_rem(REG_FP[dst], source); @@ -1372,6 +1383,13 @@ static void fpgen_rm_reg(m68ki_cpu_core *m68k, UINT16 w2) m68k->remaining_cycles -= 43; // guess break; } + case 0x27: // FSGLMUL + { + REG_FP[dst] = floatx80_mul(REG_FP[dst], source); + SET_CONDITION_CODES(m68k, REG_FP[dst]); + m68k->remaining_cycles -= 11; // ? (value is from FMUL) + break; + } case 0x28: // FSUB { REG_FP[dst] = floatx80_sub(REG_FP[dst], source); @@ -1396,7 +1414,7 @@ static void fpgen_rm_reg(m68ki_cpu_core *m68k, UINT16 w2) break; } - default: fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PC-4); + default: fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PPC); } } @@ -1507,6 +1525,10 @@ static void fmovem(m68ki_cpu_core *m68k, UINT16 w2) { switch (mode) { + case 1: // Dynamic register list, postincrement or control addressing mode. + // FIXME: not really tested, but seems to work + reglist = REG_D[(reglist >> 4) & 7]; + case 0: // Static register list, predecrement or control addressing mode { for (i=0; i < 8; i++) @@ -1531,13 +1553,41 @@ static void fmovem(m68ki_cpu_core *m68k, UINT16 w2) break; } - default: fatalerror("040fpu0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4); + case 2: // Static register list, postdecrement or control addressing mode + { + for (i=0; i < 8; i++) + { + if (reglist & (1 << i)) + { + switch (ea >> 3) + { + case 5: // (d16, An) + case 6: // (An) + (Xn) + d8 + store_extended_float80(m68k, mem_addr, REG_FP[7-i]); + mem_addr += 12; + break; + default: + WRITE_EA_FPE(m68k, ea, REG_FP[7-i]); + break; + } + + m68k->remaining_cycles -= 2; + } + } + break; + } + + default: fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4); } } else // From mem to FP regs { switch (mode) { + case 3: // Dynamic register list, predecrement addressing mode. + // FIXME: not really tested, but seems to work + reglist = REG_D[(reglist >> 4) & 7]; + case 2: // Static register list, postincrement or control addressing mode { for (i=0; i < 8; i++) @@ -1561,11 +1611,20 @@ static void fmovem(m68ki_cpu_core *m68k, UINT16 w2) break; } - default: fatalerror("040fpu0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4); + default: fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4); } } } +static void fscc(m68ki_cpu_core *m68k) +{ + int ea = m68k->ir & 0x3f; + int condition = (INT16)(OPER_I_16(m68k)); + + WRITE_EA_8(m68k, ea, TEST_CONDITION(m68k, condition) ? 0xff : 0); + m68k->remaining_cycles -= 7; // ??? +} + static void fbcc16(m68ki_cpu_core *m68k) { INT32 offset; @@ -1646,15 +1705,15 @@ void m68040_fpu_op0(m68ki_cpu_core *m68k) case 1: // FBcc disp16 { - switch ((m68k->ir >> 3) & 0x3) { + switch ((m68k->ir >> 3) & 0x7) { case 1: // FDBcc // TODO: break; default: // FScc (?) - // TODO: - break; + fscc(m68k); + return; } - fatalerror("M68kFPU: unimplemented main op %d with mode %d\n", (m68k->ir >> 6) & 0x3, (m68k->ir >> 3) & 0x7); + fatalerror("M68kFPU: unimplemented main op %d with mode %d at %08X\n", (m68k->ir >> 6) & 0x3, (m68k->ir >> 3) & 0x7, REG_PPC); } case 2: // FBcc disp16 diff --git a/src/emu/cpu/m68000/m68kmmu.h b/src/emu/cpu/m68000/m68kmmu.h index 741e8547871..6fa3d753241 100644 --- a/src/emu/cpu/m68000/m68kmmu.h +++ b/src/emu/cpu/m68000/m68kmmu.h @@ -199,13 +199,13 @@ INLINE UINT32 get_dt2_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 ptest return tbl_entry; } -INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 ptest) +INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 fc, UINT8 ptest) { UINT32 tbl_entry2 = m68k->program->read_dword(tptr); UINT32 tbl_entry = m68k->program->read_dword(tptr + 4); UINT32 dt = tbl_entry2 & M68K_MMU_DF_DT; - m68k->mmu_tmp_sr |= tbl_entry2 & 0x0100 ? M68K_MMU_SR_SUPERVISOR_ONLY : 0; + m68k->mmu_tmp_sr |= ((tbl_entry2 & 0x0100) && !(fc & 4)) ? M68K_MMU_SR_SUPERVISOR_ONLY : 0; m68k->mmu_tmp_sr |= tbl_entry2 & 0x0004 ? M68K_MMU_SR_WRITE_PROTECT : 0; if (!ptest) @@ -272,27 +272,35 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 ptest // first see if this is already in the ATC for (i = 0; i < MMU_ATC_ENTRIES; i++) { - // if tag bits and function code match, we've got it - if (m68k->mmu_atc_tag[i] == atc_tag) + if (m68k->mmu_atc_tag[i] != atc_tag) { - if (m68k->mmu_tmp_rw || !(m68k->mmu_atc_data[i] & M68K_MMU_ATC_WRITE_PR)) - { - // read access or write access and not write protected - if (!m68k->mmu_tmp_rw && !ptest) - { - // FIXME: must set modified in PMMU tables as well - m68k->mmu_atc_data[i] |= M68K_MMU_ATC_MODIFIED; - } - else - { - // FIXME: supervisor mode? - m68k->mmu_tmp_sr = M68K_MMU_SR_MODIFIED; - } - addr_out = (m68k->mmu_atc_data[i]<<8) | (addr_in & ~(~0 << ps)); -// logerror("ATC[%2d] hit: log %08x -> phys %08x pc=%08x fc=%d\n", i, addr_in, addr_out, REG_PPC, fc); -// pmmu_atc_count++; - return addr_out; - } + // tag bits and function code don't match + } + else if (!m68k->mmu_tmp_rw && (m68k->mmu_atc_data[i] & M68K_MMU_ATC_WRITE_PR)) + { + // write mode, but write protected + } + else if (!m68k->mmu_tmp_rw && !(m68k->mmu_atc_data[i] & M68K_MMU_ATC_MODIFIED)) + { + // first write; must set modified in PMMU tables as well + } + else + { + // read access or write access and not write protected + if (!m68k->mmu_tmp_rw && !ptest) + { + // FIXME: must set modified in PMMU tables as well + m68k->mmu_atc_data[i] |= M68K_MMU_ATC_MODIFIED; + } + else + { + // FIXME: supervisor mode? + m68k->mmu_tmp_sr = M68K_MMU_SR_MODIFIED; + } + addr_out = (m68k->mmu_atc_data[i] << 8) | (addr_in & ~(~0 << ps)); +// logerror("ATC[%2d] hit: log %08x -> phys %08x pc=%08x fc=%d\n", i, addr_in, addr_out, REG_PPC, fc); +// pmmu_atc_count++; + return addr_out; } } @@ -344,7 +352,7 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 ptest case M68K_MMU_DF_DT3: // valid 8 byte descriptors tofs *= 8; // if (verbose) logerror("PMMU: reading table A entries at %08x\n", tofs + tptr); - tbl_entry = get_dt3_table_entry(m68k, tofs + tptr, ptest); + tbl_entry = get_dt3_table_entry(m68k, tofs + tptr, fc, ptest); tamode = tbl_entry & M68K_MMU_DF_DT; // if (verbose) logerror("PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tamode, tofs); break; @@ -377,7 +385,7 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 ptest case M68K_MMU_DF_DT3: // 8-byte table B descriptor tofs *= 8; // if (verbose) logerror("PMMU: reading table B entries at %08x\n", tofs + tptr); - tbl_entry = get_dt3_table_entry(m68k, tptr + tofs, ptest); + tbl_entry = get_dt3_table_entry(m68k, tptr + tofs, fc, ptest); tbmode = tbl_entry & M68K_MMU_DF_DT; tbl_entry &= ~M68K_MMU_DF_DT; // if (verbose) logerror("PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tbmode, tofs); @@ -421,7 +429,7 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 ptest case M68K_MMU_DF_DT3: // 8-byte table C descriptor tofs *= 8; // if (verbose) logerror("PMMU: reading table C entries at %08x\n", tofs + tptr); - tbl_entry = get_dt3_table_entry(m68k, tptr+ tofs, ptest); + tbl_entry = get_dt3_table_entry(m68k, tptr+ tofs, fc, ptest); tcmode = tbl_entry & M68K_MMU_DF_DT; // if (verbose) logerror("PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tcmode, tofs); break; @@ -470,7 +478,7 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 ptest m68k->mmu_tmp_buserror_address = addr_in; } } - else if ((m68k->mmu_tmp_sr & M68K_MMU_SR_SUPERVISOR_ONLY) && !(fc & 4)) + else if (m68k->mmu_tmp_sr & M68K_MMU_SR_SUPERVISOR_ONLY) { if (++m68k->mmu_tmp_buserror_occurred == 1) {