psxbios: experimental vsync HLE
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / new_dynarec.c
index d37615e..090165e 100644 (file)
@@ -37,6 +37,7 @@ static Jit g_jit;
 #include "new_dynarec_config.h"
 #include "../psxhle.h"
 #include "../psxinterpreter.h"
+#include "../psxcounters.h"
 #include "../gte.h"
 #include "emu_if.h" // emulator interface
 #include "linkage_offsets.h"
@@ -6500,6 +6501,15 @@ void new_dynarec_print_stats(void)
 #endif
 }
 
+static void force_intcall(int i)
+{
+  memset(&dops[i], 0, sizeof(dops[i]));
+  dops[i].itype = INTCALL;
+  dops[i].rs1 = CCREG;
+  dops[i].is_exception = 1;
+  cinfo[i].ba = -1;
+}
+
 static int apply_hacks(void)
 {
   int i;
@@ -6534,22 +6544,29 @@ static int apply_hacks(void)
       return 1;
     }
   }
+  if (Config.HLE)
+  {
+    if (start <= psxRegs.biosBranchCheck && psxRegs.biosBranchCheck < start + i*4)
+    {
+      i = (psxRegs.biosBranchCheck - start) / 4u + 23;
+      if (dops[i].is_jump && !dops[i+1].bt)
+      {
+        force_intcall(i);
+        dops[i+1].is_ds = 0;
+      }
+    }
+  }
   return 0;
 }
 
-static int is_ld_use_hazard(int ld_rt, const struct decoded_insn *op)
-{
-  return ld_rt != 0 && (ld_rt == op->rs1 || ld_rt == op->rs2)
-    && op->itype != LOADLR && op->itype != CJUMP && op->itype != SJUMP;
-}
-
-static void force_intcall(int i)
+static int is_ld_use_hazard(const struct decoded_insn *op_ld,
+  const struct decoded_insn *op)
 {
-  memset(&dops[i], 0, sizeof(dops[i]));
-  dops[i].itype = INTCALL;
-  dops[i].rs1 = CCREG;
-  dops[i].is_exception = 1;
-  cinfo[i].ba = -1;
+  if (op_ld->rt1 == 0 || (op_ld->rt1 != op->rs1 && op_ld->rt1 != op->rs2))
+    return 0;
+  if (op_ld->itype == LOADLR && op->itype == LOADLR)
+    return op_ld->rt1 == op_ld->rs1;
+  return op->itype != CJUMP && op->itype != SJUMP;
 }
 
 static void disassemble_one(int i, u_int src)
@@ -6932,7 +6949,7 @@ static noinline void pass1_disassemble(u_int pagelimit)
           else
             dop = &dops[t];
         }
-        if ((dop && is_ld_use_hazard(dops[i].rt1, dop))
+        if ((dop && is_ld_use_hazard(&dops[i], dop))
             || (!dop && Config.PreciseExceptions)) {
           // jump target wants DS result - potential load delay effect
           SysPrintf("load delay in DS @%08x (%08x)\n", start + i*4, start);
@@ -6949,7 +6966,7 @@ static noinline void pass1_disassemble(u_int pagelimit)
       }
     }
     else if (i > 0 && dops[i-1].is_delay_load
-             && is_ld_use_hazard(dops[i-1].rt1, &dops[i])
+             && is_ld_use_hazard(&dops[i-1], &dops[i])
              && (i < 2 || !dops[i-2].is_ujump)) {
       SysPrintf("load delay @%08x (%08x)\n", start + i*4, start);
       for (j = i - 1; j > 0 && dops[j-1].is_delay_load; j--)