psxinterpreter: use cycle_multiplier also
authornotaz <notasas@gmail.com>
Sat, 1 Oct 2022 20:43:39 +0000 (23:43 +0300)
committernotaz <notasas@gmail.com>
Sat, 1 Oct 2022 21:52:26 +0000 (00:52 +0300)
not just ari64

frontend/main.c
frontend/menu.c
libpcsxcore/database.c
libpcsxcore/new_dynarec/emu_if.c
libpcsxcore/new_dynarec/new_dynarec.c
libpcsxcore/new_dynarec/new_dynarec.h
libpcsxcore/psxcommon.h
libpcsxcore/psxinterpreter.c
libpcsxcore/r3000a.c
libpcsxcore/r3000a.h

index 5033cec..fbb184a 100644 (file)
@@ -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;
index e78c370..ef0bf4c 100644 (file)
@@ -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);
 
index 52d17a7..561aede 100644 (file)
@@ -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;
                }
        }
index b679d9d..dc17f2d 100644 (file)
@@ -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;
index 2b57e59..276ef8a 100644 (file)
@@ -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) {
index e328465..d18ff63 100644 (file)
@@ -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)
index a57194c..522abbc 100644 (file)
@@ -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 {
index ea20cab..4ae9417 100644 (file)
@@ -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() {
index 858896c..ddf8388 100644 (file)
@@ -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();
index 6ba74de..1c58b17 100644 (file)
@@ -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;