bool mmu030_retry;
int mmu030_opcode;
int mmu030_opcode_stageb;
+int mmu030_fake_prefetch;
uae_u16 mmu030_state[3];
uae_u32 mmu030_data_buffer;
uae_u32 mmu030_disp_store[2];
#define TC_TIC_MASK 0x000000F0
#define TC_TID_MASK 0x0000000F
+static void mmu030_do_fake_prefetch(void)
+{
+ uaecptr pc = m68k_getpci();
+ // fetch next opcode before MMU state switches.
+ // There are programs that do following:
+ // - enable MMU
+ // - JMP (An)
+ // "enable MMU" unmaps memory under us.
+ TRY (prb) {
+ mmu030_fake_prefetch = x_prefetch(0);
+ } CATCH (prb) {
+ // didn't work, oh well..
+ mmu030_fake_prefetch = -1;
+ } ENDTRY
+ write_log(_T("MMU030 fake prefetched %04X\n"), mmu030_fake_prefetch);
+}
-bool mmu030_decode_tc(uae_u32 TC) {
-
+bool mmu030_decode_tc(uae_u32 TC)
+{
/* Set MMU condition */
if (TC & TC_ENABLE_TRANSLATION) {
+ if (!mmu030.enabled)
+ mmu030_do_fake_prefetch();
mmu030.enabled = true;
} else {
- if (mmu030.enabled)
+ if (mmu030.enabled) {
+ mmu030_do_fake_prefetch();
write_log(_T("MMU disabled\n"));
+ }
mmu030.enabled = false;
return false;
}
if (atc_line_num >= 0) {
return mmu030_get_iword_atc(addr, atc_line_num, fc);
- }
- else {
+ } else {
mmu030_table_search(addr, fc, false, 0);
return mmu030_get_iword_atc(addr, mmu030_logical_is_in_atc(addr, fc, false), fc);
}
mmusr_030 = 0;
mmu030_flush_atc_all();
}
+ mmu030_set_funcs();
+}
+
+void mmu030_set_funcs(void)
+{
+ if (currprefs.mmu_model != 68030)
+ return;
if (currprefs.cpu_cycle_exact || currprefs.cpu_compatible) {
x_phys_get_iword = get_word_icache030;
x_phys_get_ilong = get_long_icache030;
extern uae_u32 mm030_stageb_address;
extern int mmu030_idx;
extern bool mmu030_retry;
-extern int mmu030_opcode, mmu030_opcode_stageb;
+extern int mmu030_opcode, mmu030_opcode_stageb, mmu030_fake_prefetch;
extern uae_u16 mmu030_state[3];
extern uae_u32 mmu030_data_buffer;
extern uae_u32 mmu030_disp_store[2];
void mmu030_flush_atc_page_fc(uaecptr logical_addr, uae_u32 fc_base, uae_u32 fc_mask);
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);
int mmu030_match_ttr(uaecptr addr, uae_u32 fc, bool write);
}
set_x_cp_funcs();
+ mmu030_set_funcs();
}
Exception_build_stack_frame(oldpc, currpc, regs.mmu_fslw, nr, 0x4);
} else if (nr == 3) { // address error
Exception_build_stack_frame(last_fault_for_exception_3, currpc, 0, nr, 0x2);
- write_log (_T("Exception %d (%x) at %x -> %x!\n"), nr, last_fault_for_exception_3, currpc, get_long (regs.vbr + 4 * nr));
+ write_log (_T("Exception %d (%x) at %x -> %x!\n"), nr, last_fault_for_exception_3, currpc, get_long_debug (regs.vbr + 4 * nr));
} else if (nr == 5 || nr == 6 || nr == 7 || nr == 9) {
Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0x2);
} else if (regs.m && interrupt) { /* M + Interrupt */
}
#endif
-#if 0
- if (!uae_int_requested && !uaenet_int_requested && currprefs.cpu_idle && currprefs.m68k_speed != 0 && (regs.spcflags & SPCFLAG_STOP)
-#ifdef WITH_PPC
- && ppc_state != PPC_STATE_ACTIVE
-#endif
- ) {
- /* sleep 1ms if STOP-instruction is executed
- * but only if we have free frametime left to prevent slowdown
- */
- {
- static int sleepcnt, lvpos, zerocnt;
- if (vpos != lvpos) {
- lvpos = vpos;
- frame_time_t rpt = read_processor_time ();
- if ((int)rpt - (int)vsyncmaxtime < 0) {
- sleepcnt--;
-#if 0
- if (pissoff == 0 && currprefs.cachesize && --zerocnt < 0) {
- sleepcnt = -1;
- zerocnt = IDLETIME / 4;
- }
-#endif
- if (sleepcnt < 0) {
- sleepcnt = IDLETIME / 2;
- cpu_sleep_millis(1);
- }
- }
- }
- }
- }
-#endif
}
if (regs.spcflags & SPCFLAG_TRACE)
struct flag_struct f;
mmu030_opcode_stageb = -1;
+ mmu030_fake_prefetch = -1;
retry:
TRY (prb) {
for (;;) {
mmu030_state[0] = mmu030_state[1] = mmu030_state[2] = 0;
mmu030_opcode = -1;
- if (mmu030_opcode_stageb < 0) {
- regs.opcode = get_iword_mmu030 (0);
+ if (mmu030_fake_prefetch >= 0) {
+ regs.opcode = mmu030_fake_prefetch;
+ mmu030_fake_prefetch = -1;
+ } else if (mmu030_opcode_stageb < 0) {
+ regs.opcode = x_prefetch (0);
} else {
regs.opcode = mmu030_opcode_stageb;
mmu030_opcode_stageb = -1;
count_instr (regs.opcode);
do_cycles (cpu_cycles);
mmu030_retry = false;
+
cpu_cycles = (*cpufunctbl[regs.opcode])(regs.opcode);
cnt--; // so that we don't get in infinite loop if things go horribly wrong
if (!mmu030_retry)
goto retry;
} ENDTRY
}
-/* "cycle exact" 68020/030 */
+/* "cycle exact" 68020/030 */
static void m68k_run_2ce (void)
{