From a3203cf4f2f21b0f2f74c5e494e3f5ba58225eae Mon Sep 17 00:00:00 2001
From: notaz <notasas@gmail.com>
Date: Wed, 17 Nov 2021 01:35:43 +0200
Subject: [PATCH] drc: add a timing hack for Internal Section

---
 libpcsxcore/database.c                | 12 +++++++++++-
 libpcsxcore/new_dynarec/new_dynarec.c | 20 ++++++++++++++++----
 libpcsxcore/new_dynarec/new_dynarec.h |  2 ++
 3 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/libpcsxcore/database.c b/libpcsxcore/database.c
index f383e361..ac19d576 100644
--- a/libpcsxcore/database.c
+++ b/libpcsxcore/database.c
@@ -1,6 +1,6 @@
 #include "misc.h"
-#include "../plugins/dfsound/spu_config.h"
 #include "sio.h"
+#include "new_dynarec/new_dynarec.h"
 
 /* It's duplicated from emu_if.c */
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
@@ -33,4 +33,14 @@ void Apply_Hacks_Cdrom()
 			McdDisable[1] = 1;
 		}
 	}
+
+	/* Dynarec game-specific hacks */
+	new_dynarec_hacks &= ~NDHACK_OVERRIDE_CYCLE_M;
+
+	/* Internal Section is fussy about timings */
+	if (strcmp(CdromId, "SLPS01868") == 0)
+	{
+		cycle_multiplier_override = 200;
+		new_dynarec_hacks |= NDHACK_OVERRIDE_CYCLE_M;
+	}
 }
diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c
index 4ec3c53c..4e09592d 100644
--- a/libpcsxcore/new_dynarec/new_dynarec.c
+++ b/libpcsxcore/new_dynarec/new_dynarec.c
@@ -442,11 +442,14 @@ static void do_clear_cache(void)
 #define NO_CYCLE_PENALTY_THR 12
 
 int cycle_multiplier; // 100 for 1.0
+int cycle_multiplier_override;
 
 static int CLOCK_ADJUST(int x)
 {
+  int m = cycle_multiplier_override
+        ? cycle_multiplier_override : cycle_multiplier;
   int s=(x>>31)|1;
-  return (x * cycle_multiplier + s * 50) / 100;
+  return (x * m + s * 50) / 100;
 }
 
 static u_int get_page(u_int vaddr)
@@ -6631,16 +6634,25 @@ void new_dynarec_cleanup(void)
 
 static u_int *get_source_start(u_int addr, u_int *limit)
 {
+  if (!(new_dynarec_hacks & NDHACK_OVERRIDE_CYCLE_M))
+    cycle_multiplier_override = 0;
+
   if (addr < 0x00200000 ||
-    (0xa0000000 <= addr && addr < 0xa0200000)) {
+    (0xa0000000 <= addr && addr < 0xa0200000))
+  {
     // used for BIOS calls mostly?
     *limit = (addr&0xa0000000)|0x00200000;
     return (u_int *)(rdram + (addr&0x1fffff));
   }
   else if (!Config.HLE && (
     /* (0x9fc00000 <= addr && addr < 0x9fc80000) ||*/
-    (0xbfc00000 <= addr && addr < 0xbfc80000))) {
-    // BIOS
+    (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
+    if (!(new_dynarec_hacks & NDHACK_OVERRIDE_CYCLE_M))
+      cycle_multiplier_override = 200;
+
     *limit = (addr & 0xfff00000) | 0x80000;
     return (u_int *)((u_char *)psxR + (addr&0x7ffff));
   }
diff --git a/libpcsxcore/new_dynarec/new_dynarec.h b/libpcsxcore/new_dynarec/new_dynarec.h
index a19bff0b..bab33793 100644
--- a/libpcsxcore/new_dynarec/new_dynarec.h
+++ b/libpcsxcore/new_dynarec/new_dynarec.h
@@ -5,10 +5,12 @@ extern int pending_exception;
 extern int stop;
 extern int new_dynarec_did_compile;
 extern int cycle_multiplier; // 100 for 1.0
+extern int cycle_multiplier_override;
 
 #define NDHACK_NO_SMC_CHECK	(1<<0)
 #define NDHACK_GTE_UNNEEDED	(1<<1)
 #define NDHACK_GTE_NO_FLAGS	(1<<2)
+#define NDHACK_OVERRIDE_CYCLE_M	(1<<3)
 extern int new_dynarec_hacks;
 
 void new_dynarec_init(void);
-- 
2.39.5