From 58777ba5649593c4dac5e388a20196ecd14bc846 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Wed, 21 Oct 2015 20:23:19 +0300 Subject: [PATCH] Memory-cycle exact updates, JIT on/off was not safe, warp mode limiter, trace mode timing fix. --- cfgfile.cpp | 31 ++++++++++-- custom.cpp | 23 +++++++-- debug.cpp | 2 +- include/newcpu.h | 2 +- include/options.h | 1 + jit/compemu_prefs.cpp | 5 +- main.cpp | 11 ++--- newcpu.cpp | 108 +++++++++++++++++++++++++++++++++++++----- 8 files changed, 153 insertions(+), 30 deletions(-) diff --git a/cfgfile.cpp b/cfgfile.cpp index b027acee..ba21e0d8 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -236,6 +236,8 @@ static const TCHAR *autoext2[] = { _T("disabled"), _T("copy"), _T("replace"), 0 static const TCHAR *leds[] = { _T("power"), _T("df0"), _T("df1"), _T("df2"), _T("df3"), _T("hd"), _T("cd"), _T("fps"), _T("cpu"), _T("snd"), _T("md"), 0 }; static const int leds_order[] = { 3, 6, 7, 8, 9, 4, 5, 2, 1, 0, 9 }; static const TCHAR *lacer[] = { _T("off"), _T("i"), _T("p"), 0 }; +/* another boolean to choice update.. */ +static const TCHAR *cycleexact[] = { _T("false"), _T("memory"), _T("true"), 0 }; static const TCHAR *hdcontrollers[] = { _T("uae"), @@ -1861,7 +1863,14 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) // must be after cpu_cycle_exact cfgfile_write_bool (f, _T("cpu_memory_cycle_exact"), p->cpu_memory_cycle_exact); cfgfile_write_bool (f, _T("blitter_cycle_exact"), p->blitter_cycle_exact); - cfgfile_write_bool (f, _T("cycle_exact"), p->cpu_cycle_exact && p->blitter_cycle_exact ? 1 : 0); + // must be after cpu_cycle_exact, cpu_memory_cycle_exact and blitter_cycle_exact + if (p->cpu_cycle_exact && p->blitter_cycle_exact) + cfgfile_write_str (f, _T("cycle_exact"), cycleexact[2]); + else if (p->cpu_memory_cycle_exact && p->blitter_cycle_exact) + cfgfile_write_str (f, _T("cycle_exact"), cycleexact[1]); + else + cfgfile_write_str (f, _T("cycle_exact"), cycleexact[0]); + cfgfile_dwrite_bool (f, _T("fpu_no_unimplemented"), p->fpu_no_unimplemented); cfgfile_dwrite_bool (f, _T("cpu_no_unimplemented"), p->int_no_unimplemented); cfgfile_write_bool (f, _T("fpu_strict"), p->fpu_strict); @@ -1894,6 +1903,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_dwrite (f, _T("state_replay_buffers"), _T("%d"), p->statecapturebuffersize); cfgfile_dwrite_bool (f, _T("state_replay_autoplay"), p->inprec_autoplay); cfgfile_dwrite_bool (f, _T("warp"), p->turbo_emulation); + cfgfile_dwrite (f, _T("warp_limit"), _T("%d"), p->turbo_emulation_limit); #ifdef FILESYS write_filesys_config (p, f); @@ -2496,6 +2506,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) || cfgfile_intval (option, value, _T("sound_stereo_mixing_delay"), &p->sound_mixed_stereo_delay, 1) || cfgfile_intval (option, value, _T("sampler_frequency"), &p->sampler_freq, 1) || cfgfile_intval (option, value, _T("sampler_buffer"), &p->sampler_buffer, 1) + || cfgfile_intval (option, value, _T("warp_limit"), &p->turbo_emulation_limit, 1) || cfgfile_intval (option, value, _T("gfx_framerate"), &p->gfx_framerate, 1) || cfgfile_intval (option, value, _T("gfx_top_windowed"), &p->gfx_size_win.x, 1) @@ -4197,7 +4208,7 @@ static bool cfgfile_read_board_rom(struct uae_prefs *p, const TCHAR *option, con static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCHAR *value) { int tmpval, dummyint, i; - bool tmpbool, dummybool; + bool dummybool; TCHAR tmpbuf[CONFIG_BLEN]; if (cfgfile_yesno (option, value, _T("cpu_cycle_exact"), &p->cpu_cycle_exact)) { @@ -4214,11 +4225,19 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH } if (cfgfile_yesno (option, value, _T("cpu_memory_cycle_exact"), &p->cpu_memory_cycle_exact)) { if (!p->cpu_memory_cycle_exact) - p->cpu_cycle_exact = false; + p->blitter_cycle_exact = p->cpu_cycle_exact = false; return 1; } - if (cfgfile_yesno (option, value, _T("cycle_exact"), &tmpbool)) { - p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = tmpbool; + if (cfgfile_strval (option, value, _T("cycle_exact"), &tmpval, cycleexact, 0)) { + if (tmpval > 0) { + p->blitter_cycle_exact = true; + p->cpu_cycle_exact = tmpval > 1; + p->cpu_memory_cycle_exact = true; + } else { + p->blitter_cycle_exact = false; + p->cpu_cycle_exact = false; + p->cpu_memory_cycle_exact = false; + } if (p->cpu_model >= 68020 && p->cachesize > 0) p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = false; // if old version and CE and fastest possible: set to approximate @@ -6091,6 +6110,7 @@ void default_prefs (struct uae_prefs *p, int type) p->uaeserial = 0; p->cpu_idle = 0; p->turbo_emulation = 0; + p->turbo_emulation_limit = 0; p->headless = 0; p->catweasel = 0; p->tod_hack = 0; @@ -6354,6 +6374,7 @@ static void buildin_default_prefs (struct uae_prefs *p) p->uaeserial = 0; p->cpu_idle = 0; p->turbo_emulation = 0; + p->turbo_emulation_limit = 0; p->catweasel = 0; p->tod_hack = 0; p->maprom = 0; diff --git a/custom.cpp b/custom.cpp index 72960a36..e7a90dd9 100644 --- a/custom.cpp +++ b/custom.cpp @@ -3793,15 +3793,24 @@ void compute_vsynctime (void) } if (!fake_vblank_hz) fake_vblank_hz = vblank_hz; - if (currprefs.turbo_emulation) - vsynctimebase = vsynctimebase_orig = 1; - else - vsynctimebase = vsynctimebase_orig = (int)(syncbase / fake_vblank_hz); + + if (currprefs.turbo_emulation) { + if (currprefs.turbo_emulation_limit > 0) { + vsynctimebase = (int)(syncbase / currprefs.turbo_emulation_limit); + } else { + vsynctimebase = 1; + } + } else { + vsynctimebase = (int)(syncbase / fake_vblank_hz); + } + vsynctimebase_orig = vsynctimebase; + #if 0 if (!picasso_on) { updatedisplayarea (); } #endif + if (islinetoggle ()) { shpos += 0.5; } @@ -9672,6 +9681,12 @@ void check_prefs_changed_custom (void) if (!config_changed) return; currprefs.gfx_framerate = changed_prefs.gfx_framerate; + if (currprefs.turbo_emulation_limit != changed_prefs.turbo_emulation_limit) { + currprefs.turbo_emulation_limit = changed_prefs.turbo_emulation_limit; + if (changed_prefs.turbo_emulation) { + warpmode (changed_prefs.turbo_emulation); + } + } if (currprefs.turbo_emulation != changed_prefs.turbo_emulation) warpmode (changed_prefs.turbo_emulation); if (inputdevice_config_change_test ()) diff --git a/debug.cpp b/debug.cpp index 9ff761fe..584f940f 100644 --- a/debug.cpp +++ b/debug.cpp @@ -5157,7 +5157,7 @@ int mmu_init(int mode, uaecptr parm, uaecptr parm2) wasjit = currprefs.cachesize; changed_prefs.cachesize = 0; console_out (_T("MMU: JIT disabled\n")); - check_prefs_changed_comp (); + check_prefs_changed_comp(false); } if (mode == 0) { if (mmu_enabled) { diff --git a/include/newcpu.h b/include/newcpu.h index 09bb4768..d7460a64 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -670,7 +670,7 @@ extern void compemu_reset(void); #define flush_icache(uaecptr, int) do {} while (0) #define flush_icache_hard(uaecptr, int) do {} while (0) #endif -bool check_prefs_changed_comp (void); +bool check_prefs_changed_comp (bool); extern void flush_dcache (uaecptr, int); extern void flush_mmu (uaecptr, int); diff --git a/include/options.h b/include/options.h index 386b1b51..e975a704 100644 --- a/include/options.h +++ b/include/options.h @@ -467,6 +467,7 @@ struct uae_prefs { int boot_rom; bool rom_readwrite; int turbo_emulation; + int turbo_emulation_limit; bool headless; int filesys_limit; int filesys_max_name; diff --git a/jit/compemu_prefs.cpp b/jit/compemu_prefs.cpp index 3d14214a..003b6f55 100644 --- a/jit/compemu_prefs.cpp +++ b/jit/compemu_prefs.cpp @@ -3,7 +3,7 @@ ********************************************************************/ extern bool have_done_picasso; -bool check_prefs_changed_comp (void) +bool check_prefs_changed_comp (bool checkonly) { bool changed = 0; static int cachesize_prev, comptrust_prev; @@ -20,6 +20,9 @@ bool check_prefs_changed_comp (void) currprefs.fpu_strict != changed_prefs.fpu_strict) changed = 1; + if (checkonly) + return changed; + currprefs.comptrustbyte = changed_prefs.comptrustbyte; currprefs.comptrustword = changed_prefs.comptrustword; currprefs.comptrustlong = changed_prefs.comptrustlong; diff --git a/main.cpp b/main.cpp index 598298c5..1fb28a87 100644 --- a/main.cpp +++ b/main.cpp @@ -221,7 +221,7 @@ void fixup_cpu (struct uae_prefs *p) error_log (_T("24-bit address space is not supported with 68040/060 configurations.")); p->address_space_24 = 0; } - if (p->cpu_model < 68020 && p->fpu_model && (p->cpu_compatible || p->cpu_cycle_exact)) { + if (p->cpu_model < 68020 && p->fpu_model && (p->cpu_compatible || p->cpu_memory_cycle_exact)) { error_log (_T("FPU is not supported with 68000/010 configurations.")); p->fpu_model = 0; } @@ -246,7 +246,7 @@ void fixup_cpu (struct uae_prefs *p) break; } - if (p->cpu_thread && (p->cpu_compatible || p->ppc_mode || p->cpu_cycle_exact || p->cpu_memory_cycle_exact || p->cpu_model < 68020)) { + if (p->cpu_thread && (p->cpu_compatible || p->ppc_mode || p->cpu_memory_cycle_exact || p->cpu_model < 68020)) { p->cpu_thread = false; error_log(_T("Threaded CPU mode is not compatible with PPC emulation, More compatible or Cycle Exact modes. CPU type must be 68020 or higher.")); } @@ -281,7 +281,7 @@ void fixup_cpu (struct uae_prefs *p) p->mmu_model = 0; } - if (p->cachesize && (p->cpu_cycle_exact || p->cpu_memory_cycle_exact)) { + if (p->cachesize && p->cpu_memory_cycle_exact) { error_log (_T("JIT and cycle-exact can't be enabled simultaneously.")); p->cachesize = 0; } @@ -305,10 +305,10 @@ void fixup_cpu (struct uae_prefs *p) error_log (_T("Immediate blitter and waiting blits can't be enabled simultaneously.\n")); p->waiting_blits = 0; } - if (p->cpu_cycle_exact || p->cpu_memory_cycle_exact) + if (p->cpu_memory_cycle_exact) p->cpu_compatible = true; - if ((p->cpu_cycle_exact || p->cpu_memory_cycle_exact) && p->produce_sound == 0) { + if (p->cpu_memory_cycle_exact && p->produce_sound == 0) { p->produce_sound = 1; error_log(_T("Cycle-exact mode requires at least Disabled but emulated sound setting.")); } @@ -329,7 +329,6 @@ void fixup_prefs (struct uae_prefs *p) built_in_chipset_prefs (p); fixup_cpu (p); - if (p->cpuboard_type && p->cpuboardmem1_size > cpuboard_maxmemory(p)) { error_log(_T("Unsupported accelerator board memory size %d (0x%x).\n"), p->cpuboardmem1_size, p->cpuboardmem1_size); p->cpuboardmem1_size = cpuboard_maxmemory(p); diff --git a/newcpu.cpp b/newcpu.cpp index e24d4fbb..ce150f28 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -1503,6 +1503,7 @@ static void update_68k_cycles (void) static void prefs_changed_cpu (void) { fixup_cpu (&changed_prefs); + check_prefs_changed_comp(false); currprefs.cpu_model = changed_prefs.cpu_model; currprefs.fpu_model = changed_prefs.fpu_model; currprefs.mmu_model = changed_prefs.mmu_model; @@ -1519,7 +1520,7 @@ static int check_prefs_changed_cpu2(void) int changed = 0; #ifdef JIT - changed = check_prefs_changed_comp() ? 1 : 0; + changed = check_prefs_changed_comp(true) ? 1 : 0; #endif if (changed || currprefs.cpu_model != changed_prefs.cpu_model @@ -1601,7 +1602,7 @@ void init_m68k (void) #ifdef JIT /* We need to check whether NATMEM settings have changed * before starting the CPU */ - check_prefs_changed_comp (); + check_prefs_changed_comp(false); #endif } @@ -2188,6 +2189,7 @@ CHK: Illegal Instruction: Privilege violation: +Trace: Line A: Line F: @@ -2248,7 +2250,7 @@ static void Exception_ce000 (int nr) start = 0; else if (nr >= 32 && nr < 32 + 16) // TRAP #x start = 4; - else if (nr == 4 || nr == 8 || nr == 10 || nr == 11) // ILLG, PRIV, LINEA, LINEF + else if (nr == 4 || nr == 8 || nr == 9 || nr == 10 || nr == 11) // ILLG, PRIV, TRACE, LINEA, LINEF start = 4; } @@ -4863,19 +4865,24 @@ static void m68k_run_2ce (void) } while (!exit) { +#if 0 static int prevopcode; +#endif r->instruction_pc = m68k_getpc (); +#if 0 if (regs.irc == 0xfffb) { gui_message (_T("OPCODE %04X HAS FAULTY PREFETCH! PC=%08X"), prevopcode, r->instruction_pc); } +#endif //write_log (_T("%x %04x\n"), r->instruction_pc, regs.irc); r->opcode = regs.irc; +#if 0 prevopcode = r->opcode; regs.irc = 0xfffb; - +#endif //write_log (_T("%08x %04x\n"), r->instruction_pc, opcode); #if DEBUG_CD32CDTVIO @@ -4952,23 +4959,100 @@ static void m68k_run_2p (void) { struct regstruct *r = ®s; bool exit = false; + bool first = true; while (!exit) { TRY(prb) { + + if (first) { + if (cpu_tracer < 0) { + memcpy (&r->regs, &cputrace.regs, 16 * sizeof (uae_u32)); + r->ir = cputrace.ir; + r->irc = cputrace.irc; + r->sr = cputrace.sr; + r->usp = cputrace.usp; + r->isp = cputrace.isp; + r->intmask = cputrace.intmask; + r->stopped = cputrace.stopped; + + r->msp = cputrace.msp; + r->vbr = cputrace.vbr; + r->caar = cputrace.caar; + r->cacr = cputrace.cacr; + r->cacheholdingdata020 = cputrace.cacheholdingdata020; + r->cacheholdingaddr020 = cputrace.cacheholdingaddr020; + r->prefetch020addr = cputrace.prefetch020addr; + memcpy (&r->prefetch020, &cputrace.prefetch020, CPU_PIPELINE_MAX * sizeof (uae_u32)); + memcpy (&caches020, &cputrace.caches020, sizeof caches020); + + m68k_setpc (cputrace.pc); + if (!r->stopped) { + if (cputrace.state > 1) + Exception (cputrace.state); + else if (cputrace.state == 1) + (*cpufunctbl[cputrace.opcode])(cputrace.opcode); + } + if (regs.stopped) + set_special (SPCFLAG_STOP); + set_cpu_tracer (false); + goto cont; + } + set_cpu_tracer (false); + first = false; + } + while (!exit) { r->instruction_pc = m68k_getpc (); + r->opcode = regs.irc; #if DEBUG_CD32CDTVIO out_cd32io (m68k_getpc ()); #endif - x_do_cycles (cpu_cycles); + if (cpu_tracer) { - r->opcode = regs.irc; - count_instr (r->opcode); +#if CPUTRACE_DEBUG + validate_trace (); +#endif + memcpy (&cputrace.regs, &r->regs, 16 * sizeof (uae_u32)); + cputrace.opcode = r->opcode; + cputrace.ir = r->ir; + cputrace.irc = r->irc; + cputrace.sr = r->sr; + cputrace.usp = r->usp; + cputrace.isp = r->isp; + cputrace.intmask = r->intmask; + cputrace.stopped = r->stopped; + cputrace.state = 1; + cputrace.pc = m68k_getpc (); + + cputrace.msp = r->msp; + cputrace.vbr = r->vbr; + cputrace.caar = r->caar; + cputrace.cacr = r->cacr; + cputrace.cacheholdingdata020 = r->cacheholdingdata020; + cputrace.cacheholdingaddr020 = r->cacheholdingaddr020; + cputrace.prefetch020addr = r->prefetch020addr; + memcpy (&cputrace.prefetch020, &r->prefetch020, CPU_PIPELINE_MAX * sizeof (uae_u32)); + memcpy (&cputrace.caches020, &caches020, sizeof caches020); + + cputrace.memoryoffset = 0; + cputrace.cyclecounter = cputrace.cyclecounter_pre = cputrace.cyclecounter_post = 0; + cputrace.readcounter = cputrace.writecounter = 0; + } + + if (inputrecord_debug & 4) { + if (input_record > 0) + inprec_recorddebug_cpu (1); + else if (input_play > 0) + inprec_playdebug_cpu (1); + } + + x_do_cycles (cpu_cycles); cpu_cycles = (*cpufunctbl[r->opcode])(r->opcode); cpu_cycles = adjust_cycles (cpu_cycles); +cont: if (r->spcflags) { if (do_specialties (cpu_cycles)) exit = true;; @@ -6714,10 +6798,11 @@ void m68k_setstopped (void) regs.stopped = 1; /* A traced STOP instruction drops through immediately without actually stopping. */ - if ((regs.spcflags & SPCFLAG_DOTRACE) == 0) + if ((regs.spcflags & SPCFLAG_DOTRACE) == 0) { set_special (SPCFLAG_STOP); - else + } else { m68k_resumestopped (); + } } void m68k_resumestopped (void) @@ -6725,9 +6810,8 @@ void m68k_resumestopped (void) if (!regs.stopped) return; regs.stopped = 0; - if (currprefs.cpu_cycle_exact) { - if (currprefs.cpu_model == 68000) - x_do_cycles (6 * cpucycleunit); + if (currprefs.cpu_cycle_exact && currprefs.cpu_model == 68000) { + x_do_cycles (6 * cpucycleunit); } fill_prefetch (); unset_special (SPCFLAG_STOP); -- 2.47.3