From 1562ed57fbcf34e330876840a68ca8853ea71cce Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 1 Oct 2022 23:43:39 +0300 Subject: [PATCH] psxinterpreter: use cycle_multiplier also not just ari64 --- frontend/main.c | 2 +- frontend/menu.c | 10 +++++----- libpcsxcore/database.c | 21 ++++++++++++++------- libpcsxcore/new_dynarec/emu_if.c | 4 +--- libpcsxcore/new_dynarec/new_dynarec.c | 11 ++++------- libpcsxcore/new_dynarec/new_dynarec.h | 3 --- libpcsxcore/psxcommon.h | 10 +++++----- libpcsxcore/psxinterpreter.c | 27 ++++++++++++++++++++++----- libpcsxcore/r3000a.c | 1 + libpcsxcore/r3000a.h | 5 +++-- 10 files changed, 56 insertions(+), 38 deletions(-) diff --git a/frontend/main.c b/frontend/main.c index 5033cec6..fbb184ab 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -132,6 +132,7 @@ void emu_set_default_config(void) Config.Xa = Config.Cdda = 0; Config.icache_emulation = 0; Config.PsxAuto = 1; + Config.cycle_multiplier = CYCLE_MULT_DEFAULT; pl_rearmed_cbs.thread_rendering = 0; @@ -169,7 +170,6 @@ void emu_set_default_config(void) #endif #endif new_dynarec_hacks = 0; - cycle_multiplier = 200; in_type[0] = PSE_PAD_TYPE_STANDARD; in_type[1] = PSE_PAD_TYPE_STANDARD; diff --git a/frontend/menu.c b/frontend/menu.c index e78c370c..ef0bf4c9 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -306,7 +306,7 @@ static void menu_sync_config(void) Config.PsxAuto = 0; Config.PsxType = region - 1; } - cycle_multiplier = 10000 / psx_clock; + Config.cycle_multiplier = 10000 / psx_clock; switch (in_type_sel1) { case 1: in_type[0] = PSE_PAD_TYPE_ANALOGPAD; break; @@ -1535,8 +1535,6 @@ static int menu_loop_plugin_options(int id, int keys) // ------------ adv options menu ------------ #ifndef DRC_DISABLE -static const char h_cfg_psxclk[] = "Over/under-clock the PSX, default is " DEFAULT_PSX_CLOCK_S "\n" - "(lower value - less work for the emu, may be faster)"; static const char h_cfg_noch[] = "Disables game-specific compatibility hacks"; static const char h_cfg_nosmc[] = "Will cause crashes when loading, break memcards"; static const char h_cfg_gteunn[] = "May cause graphical glitches"; @@ -1547,7 +1545,6 @@ static const char h_cfg_stalls[] = "Will cause some games to run too fast"; static menu_entry e_menu_speed_hacks[] = { #ifndef DRC_DISABLE - mee_range_h ("PSX CPU clock, %%", 0, psx_clock, 1, 500, h_cfg_psxclk), mee_onoff_h ("Disable compat hacks", 0, new_dynarec_hacks, NDHACK_NO_COMPAT_HACKS, h_cfg_noch), mee_onoff_h ("Disable SMC checks", 0, new_dynarec_hacks, NDHACK_NO_SMC_CHECK, h_cfg_nosmc), mee_onoff_h ("Assume GTE regs unneeded", 0, new_dynarec_hacks, NDHACK_GTE_UNNEEDED, h_cfg_gteunn), @@ -1579,6 +1576,8 @@ static const char h_cfg_nodrc[] = "Disable dynamic recompiler and use interpret #endif static const char h_cfg_shacks[] = "Breaks games but may give better performance"; static const char h_cfg_icache[] = "Support F1 games (only when dynarec is off)"; +static const char h_cfg_psxclk[] = "Over/under-clock the PSX, default is " DEFAULT_PSX_CLOCK_S "\n" + "(adjust this if the game is too slow/too fast/hangs)"; enum { AMO_XA, AMO_CDDA, AMO_IC, AMO_CPU }; @@ -1593,6 +1592,7 @@ static menu_entry e_menu_adv_options[] = #if !defined(DRC_DISABLE) || defined(LIGHTREC) mee_onoff_h ("Disable dynarec (slow!)",0, menu_iopts[AMO_CPU], 1, h_cfg_nodrc), #endif + mee_range_h ("PSX CPU clock, %", 0, psx_clock, 1, 500, h_cfg_psxclk), mee_handler_h ("[Speed hacks]", menu_loop_speed_hacks, h_cfg_shacks), mee_end, }; @@ -2632,6 +2632,7 @@ void menu_prepare_emu(void) psxCpu->Reset(); } + menu_sync_config(); psxCpu->ApplyConfig(); // core doesn't care about Config.Cdda changes, @@ -2639,7 +2640,6 @@ void menu_prepare_emu(void) if (Config.Cdda) CDR_stop(); - menu_sync_config(); if (cpu_clock > 0) plat_target_cpu_clock_set(cpu_clock); diff --git a/libpcsxcore/database.c b/libpcsxcore/database.c index 52d17a7e..561aedee 100644 --- a/libpcsxcore/database.c +++ b/libpcsxcore/database.c @@ -22,7 +22,7 @@ static const struct const char * const id; int mult; } -new_dynarec_clock_overrides[] = +cycle_multiplier_overrides[] = { /* Internal Section - fussy about timings */ { "SLPS01868", 202 }, @@ -30,6 +30,13 @@ new_dynarec_clock_overrides[] = * changing memcard settings is enough to break/unbreak it */ { "SLPS02528", 190 }, { "SLPS02636", 190 }, +#ifdef DRC_DISABLE /* new_dynarec has a hack for this game */ + /* Parasite Eve II - internal timer checks */ + { "SLUS01042", 125 }, + { "SLUS01055", 125 }, + { "SLES02558", 125 }, + { "SLES12558", 125 }, +#endif }; /* Function for automatic patching according to GameID. */ @@ -51,16 +58,16 @@ void Apply_Hacks_Cdrom() /* Dynarec game-specific hacks */ new_dynarec_hacks_pergame = 0; - cycle_multiplier_override = 0; + Config.cycle_multiplier_override = 0; - for (i = 0; i < ARRAY_SIZE(new_dynarec_clock_overrides); i++) + for (i = 0; i < ARRAY_SIZE(cycle_multiplier_overrides); i++) { - if (strcmp(CdromId, new_dynarec_clock_overrides[i].id) == 0) + if (strcmp(CdromId, cycle_multiplier_overrides[i].id) == 0) { - cycle_multiplier_override = new_dynarec_clock_overrides[i].mult; + Config.cycle_multiplier_override = cycle_multiplier_overrides[i].mult; new_dynarec_hacks_pergame |= NDHACK_OVERRIDE_CYCLE_M; - SysPrintf("using new_dynarec clock override: %d\n", - cycle_multiplier_override); + SysPrintf("using cycle_multiplier_override: %d\n", + Config.cycle_multiplier_override); break; } } diff --git a/libpcsxcore/new_dynarec/emu_if.c b/libpcsxcore/new_dynarec/emu_if.c index b679d9df..dc17f2d4 100644 --- a/libpcsxcore/new_dynarec/emu_if.c +++ b/libpcsxcore/new_dynarec/emu_if.c @@ -394,7 +394,7 @@ static void ari64_apply_config() else new_dynarec_hacks &= ~NDHACK_NO_STALLS; - if (cycle_multiplier != cycle_multiplier_old + if (Config.cycle_multiplier != cycle_multiplier_old || new_dynarec_hacks != new_dynarec_hacks_old) { new_dynarec_clear_full(); @@ -424,8 +424,6 @@ unsigned int address; int pending_exception, stop; unsigned int next_interupt; int new_dynarec_did_compile; -int cycle_multiplier; -int cycle_multiplier_override; int cycle_multiplier_old; int new_dynarec_hacks_pergame; int new_dynarec_hacks_old; diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c index 2b57e59d..276ef8af 100644 --- a/libpcsxcore/new_dynarec/new_dynarec.c +++ b/libpcsxcore/new_dynarec/new_dynarec.c @@ -592,8 +592,6 @@ static void do_clear_cache(void) #define NO_CYCLE_PENALTY_THR 12 -int cycle_multiplier = CYCLE_MULT_DEFAULT; // 100 for 1.0 -int cycle_multiplier_override; int cycle_multiplier_old; static int cycle_multiplier_active; @@ -6233,7 +6231,7 @@ void new_dynarec_clear_full(void) stat_clear(stat_blocks); stat_clear(stat_links); - cycle_multiplier_old = cycle_multiplier; + cycle_multiplier_old = Config.cycle_multiplier; new_dynarec_hacks_old = new_dynarec_hacks; } @@ -6303,7 +6301,6 @@ void new_dynarec_init(void) #endif #endif out = ndrc->translation_cache; - cycle_multiplier=200; new_dynarec_clear_full(); #ifdef HOST_IMM8 // Copy this into local area so we don't have to put it in every literal pool @@ -6360,7 +6357,7 @@ static u_int *get_source_start(u_int addr, u_int *limit) (0xbfc00000 <= addr && addr < 0xbfc80000))) { // BIOS. The multiplier should be much higher as it's uncached 8bit mem, - // but timings in PCSX are too tied to the interpreter's BIAS + // but timings in PCSX are too tied to the interpreter's 2-per-insn assumption if (!HACK_ENABLED(NDHACK_OVERRIDE_CYCLE_M)) cycle_multiplier_active = 200; @@ -9031,8 +9028,8 @@ static int new_recompile_block(u_int addr) return 0; } - cycle_multiplier_active = cycle_multiplier_override && cycle_multiplier == CYCLE_MULT_DEFAULT - ? cycle_multiplier_override : cycle_multiplier; + cycle_multiplier_active = Config.cycle_multiplier_override && Config.cycle_multiplier == CYCLE_MULT_DEFAULT + ? Config.cycle_multiplier_override : Config.cycle_multiplier; source = get_source_start(start, &pagelimit); if (source == NULL) { diff --git a/libpcsxcore/new_dynarec/new_dynarec.h b/libpcsxcore/new_dynarec/new_dynarec.h index e3284654..d18ff630 100644 --- a/libpcsxcore/new_dynarec/new_dynarec.h +++ b/libpcsxcore/new_dynarec/new_dynarec.h @@ -5,9 +5,6 @@ extern int pending_exception; extern int stop; extern int new_dynarec_did_compile; -#define CYCLE_MULT_DEFAULT 175 -extern int cycle_multiplier; // 100 for 1.0 -extern int cycle_multiplier_override; extern int cycle_multiplier_old; #define NDHACK_NO_SMC_CHECK (1<<0) diff --git a/libpcsxcore/psxcommon.h b/libpcsxcore/psxcommon.h index a57194c0..522abbc8 100644 --- a/libpcsxcore/psxcommon.h +++ b/libpcsxcore/psxcommon.h @@ -112,6 +112,8 @@ extern int Log; void __Log(char *fmt, ...); +#define CYCLE_MULT_DEFAULT 175 + typedef struct { char Gpu[MAXPATHLEN]; char Spu[MAXPATHLEN]; @@ -119,7 +121,7 @@ typedef struct { char Pad1[MAXPATHLEN]; char Pad2[MAXPATHLEN]; char Net[MAXPATHLEN]; - char Sio1[MAXPATHLEN]; + char Sio1[MAXPATHLEN]; char Mcd1[MAXPATHLEN]; char Mcd2[MAXPATHLEN]; char Bios[MAXPATHLEN]; @@ -139,6 +141,8 @@ typedef struct { boolean UseNet; boolean icache_emulation; boolean DisableStalls; + int cycle_multiplier; // 100 for 1.0 + int cycle_multiplier_override; u8 Cpu; // CPU_DYNAREC or CPU_INTERPRETER u8 PsxType; // PSX_TYPE_NTSC or PSX_TYPE_PAL #ifdef _WIN32 @@ -163,10 +167,6 @@ extern struct PcsxSaveFuncs SaveFuncs; if (Mode == 0) SaveFuncs.read(f, ptr, size); \ } -// Make the timing events trigger faster as we are currently assuming everything -// takes one cycle, which is not the case on real hardware. -// FIXME: Count the proper cycle and get rid of this -#define BIAS 2 #define PSXCLK 33868800 /* 33.8688 MHz */ enum { diff --git a/libpcsxcore/psxinterpreter.c b/libpcsxcore/psxinterpreter.c index ea20cab9..4ae9417a 100644 --- a/libpcsxcore/psxinterpreter.c +++ b/libpcsxcore/psxinterpreter.c @@ -108,6 +108,17 @@ static u32 INT_ATTR fetchICache(u8 **memRLUT, u32 pc) static u32 (INT_ATTR *fetch)(u8 **memRLUT, u32 pc) = fetchNoCache; +// Make the timing events trigger faster as we are currently assuming everything +// takes one cycle, which is not the case on real hardware. +// FIXME: count cache misses, memory latencies, stalls to get rid of this +static inline void addCycle(void) +{ + assert(psxRegs.subCycleStep >= 0x10000); + psxRegs.subCycle += psxRegs.subCycleStep; + psxRegs.cycle += psxRegs.subCycle >> 16; + psxRegs.subCycle &= 0xffff; +} + static void delayRead(int reg, u32 bpc) { u32 rold, rnew; @@ -458,7 +469,7 @@ static int psxDelayBranchExec(u32 tar) { branch = 0; psxRegs.pc = tar; - psxRegs.cycle += BIAS; + addCycle(); psxBranchTest(); return 1; } @@ -484,7 +495,7 @@ static int psxDelayBranchTest(u32 tar1) { return psxDelayBranchExec(tar2); } debugI(); - psxRegs.cycle += BIAS; + addCycle(); /* * Got a branch at tar1: @@ -497,7 +508,7 @@ static int psxDelayBranchTest(u32 tar1) { return psxDelayBranchExec(tmp1); } debugI(); - psxRegs.cycle += BIAS; + addCycle(); /* * Got a branch at tar2: @@ -523,7 +534,7 @@ static void doBranch(u32 tar) { debugI(); psxRegs.pc += 4; - psxRegs.cycle += BIAS; + addCycle(); // check for load delay tmp = psxRegs.code >> 26; @@ -1076,7 +1087,7 @@ static inline void execI_(u8 **memRLUT, psxRegisters *regs_) { if (Config.Debug) ProcessDebug(); regs_->pc += 4; - regs_->cycle += BIAS; + addCycle(); psxBSC[regs_->code >> 26](regs_, regs_->code); } @@ -1111,6 +1122,8 @@ void intNotify (int note, void *data) { } void intApplyConfig() { + int cycle_mult; + assert(psxBSC[18] == psxCOP2 || psxBSC[18] == psxCOP2_stall); assert(psxBSC[50] == gteLWC2 || psxBSC[50] == gteLWC2_stall); assert(psxBSC[58] == gteSWC2 || psxBSC[58] == gteSWC2_stall); @@ -1149,6 +1162,10 @@ void intApplyConfig() { fetch = fetchNoCache; else fetch = fetchICache; + + cycle_mult = Config.cycle_multiplier_override && Config.cycle_multiplier == CYCLE_MULT_DEFAULT + ? Config.cycle_multiplier_override : Config.cycle_multiplier; + psxRegs.subCycleStep = 0x10000 * cycle_mult / 100; } static void intShutdown() { diff --git a/libpcsxcore/r3000a.c b/libpcsxcore/r3000a.c index 858896c0..ddf83886 100644 --- a/libpcsxcore/r3000a.c +++ b/libpcsxcore/r3000a.c @@ -61,6 +61,7 @@ void psxReset() { psxRegs.CP0.r[12] = 0x10900000; // COP0 enabled | BEV = 1 | TS = 1 psxRegs.CP0.r[15] = 0x00000002; // PRevID = Revision ID, same as R3000A + psxCpu->ApplyConfig(); psxCpu->Reset(); psxHwReset(); diff --git a/libpcsxcore/r3000a.h b/libpcsxcore/r3000a.h index 6ba74de6..1c58b177 100644 --- a/libpcsxcore/r3000a.h +++ b/libpcsxcore/r3000a.h @@ -191,9 +191,10 @@ typedef struct { struct { u32 sCycle, cycle; } intCycle[32]; u32 gteBusyCycle; u32 muldivBusyCycle; + u32 subCycle; /* interpreter cycle counting */ + u32 subCycleStep; // warning: changing anything in psxRegisters requires update of all - // asm in libpcsxcore/new_dynarec/, but this member can be replaced - u32 reserved[2]; + // asm in libpcsxcore/new_dynarec/ } psxRegisters; extern boolean writeok; -- 2.39.5