From 8bccdd17109b041fc6a3a4ab72877d5bb2843ebe Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sun, 10 Sep 2023 20:58:02 +0200 Subject: [PATCH] libpcsxcore: Add database for Lightrec hacks And add entries for the infamous Formula One games. These games do tricks with the instruction cache that are hard to emulate properly in an interpreter, and almost impossible in a dynamic recompiler. Funnily enough, emulating the CPU less accurately by only invalidating cached code on DMA writes and never on CPU writes make these games work. These hacks will also make Lightrec generate faster code, but they are unsafe by nature, and that's why they are conditionally enabled. Signed-off-by: Paul Cercueil --- libpcsxcore/database.c | 46 +++++++++++++++++++++++++++++++++++ libpcsxcore/lightrec/plugin.c | 4 +++ 2 files changed, 50 insertions(+) diff --git a/libpcsxcore/database.c b/libpcsxcore/database.c index 5edb9611..ed959eaa 100644 --- a/libpcsxcore/database.c +++ b/libpcsxcore/database.c @@ -1,10 +1,16 @@ #include "misc.h" #include "sio.h" #include "new_dynarec/new_dynarec.h" +#include "lightrec/plugin.h" /* It's duplicated from emu_if.c */ #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +/* Corresponds to LIGHTREC_OPT_INV_DMA_ONLY of lightrec.h */ +#define LIGHTREC_HACK_INV_DMA_ONLY (1 << 0) + +u32 lightrec_hacks; + static const char * const MemorycardHack_db[] = { /* Lifeforce Tenka, also known as Codename Tenka */ @@ -75,6 +81,35 @@ cycle_multiplier_overrides[] = { "SLES02064", 222 }, }; +static const struct +{ + const char * const id; + u32 hacks; +} +lightrec_hacks_db[] = +{ + /* Formula One Arcade */ + { "SCES03886", LIGHTREC_HACK_INV_DMA_ONLY }, + + /* Formula One '99 */ + { "SLUS00870", LIGHTREC_HACK_INV_DMA_ONLY }, + { "SCPS10101", LIGHTREC_HACK_INV_DMA_ONLY }, + { "SCES01979", LIGHTREC_HACK_INV_DMA_ONLY }, + { "SLES01979", LIGHTREC_HACK_INV_DMA_ONLY }, + + /* Formula One 2000 */ + { "SLUS01134", LIGHTREC_HACK_INV_DMA_ONLY }, + { "SCES02777", LIGHTREC_HACK_INV_DMA_ONLY }, + { "SCES02778", LIGHTREC_HACK_INV_DMA_ONLY }, + { "SCES02779", LIGHTREC_HACK_INV_DMA_ONLY }, + + /* Formula One 2001 */ + { "SCES03404", LIGHTREC_HACK_INV_DMA_ONLY }, + { "SCES03423", LIGHTREC_HACK_INV_DMA_ONLY }, + { "SCES03424", LIGHTREC_HACK_INV_DMA_ONLY }, + { "SCES03524", LIGHTREC_HACK_INV_DMA_ONLY }, +}; + /* Function for automatic patching according to GameID. */ void Apply_Hacks_Cdrom() { @@ -122,4 +157,15 @@ void Apply_Hacks_Cdrom() break; } } + + lightrec_hacks = 0; + + for (i = 0; drc_is_lightrec() && i < ARRAY_SIZE(lightrec_hacks_db); i++) { + if (strcmp(CdromId, lightrec_hacks_db[i].id) == 0) + { + lightrec_hacks = lightrec_hacks_db[i].hacks; + SysPrintf("using lightrec_hacks: 0x%x\n", lightrec_hacks); + break; + } + } } diff --git a/libpcsxcore/lightrec/plugin.c b/libpcsxcore/lightrec/plugin.c index 7248c178..d3e4b33f 100644 --- a/libpcsxcore/lightrec/plugin.c +++ b/libpcsxcore/lightrec/plugin.c @@ -66,6 +66,8 @@ static bool use_lightrec_interpreter; static bool use_pcsx_interpreter; static bool block_stepping; +extern u32 lightrec_hacks; + enum my_cp2_opcodes { OP_CP2_RTPS = 0x01, OP_CP2_NCLIP = 0x06, @@ -468,6 +470,8 @@ static int lightrec_plugin_init(void) lightrec_map, ARRAY_SIZE(lightrec_map), &lightrec_ops); + lightrec_set_unsafe_opt_flags(lightrec_state, lightrec_hacks); + // fprintf(stderr, "M=0x%lx, P=0x%lx, R=0x%lx, H=0x%lx\n", // (uintptr_t) psxM, // (uintptr_t) psxP, -- 2.39.5