From 0aa7361c7c226c94d0f9ae4779bcc635454ef276 Mon Sep 17 00:00:00 2001 From: notaz Date: Thu, 18 Apr 2024 21:12:41 +0300 Subject: [PATCH] new experimental TurboCD option --- frontend/libretro.c | 12 +++++++++++ frontend/libretro_core_options.h | 20 +++++++++++++++---- frontend/main.c | 2 ++ frontend/menu.c | 6 +++++- libpcsxcore/cdrom.c | 34 +++++++++++++++++++++++++++----- libpcsxcore/misc.c | 2 +- libpcsxcore/psxcommon.h | 1 + 7 files changed, 66 insertions(+), 11 deletions(-) diff --git a/frontend/libretro.c b/frontend/libretro.c index 6a719ae4..7ad4caa8 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -2191,6 +2191,8 @@ bool retro_load_game(const struct retro_game_info *info) if (check_unsatisfied_libcrypt()) show_notification("LibCrypt protected game with missing SBI detected", 3000, 3); + if (Config.TurboCD) + show_notification("TurboCD is ON", 700, 2); return true; } @@ -2473,6 +2475,16 @@ static void update_variables(bool in_flight) display_internal_fps = true; } + var.value = NULL; + var.key = "pcsx_rearmed_cd_turbo"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "enabled") == 0) + Config.TurboCD = true; + else + Config.TurboCD = false; + } + #ifdef HAVE_CDROM var.value = NULL; var.key = "pcsx_rearmed_phys_cd_readahead"; diff --git a/frontend/libretro_core_options.h b/frontend/libretro_core_options.h index 451ee478..e79e9027 100644 --- a/frontend/libretro_core_options.h +++ b/frontend/libretro_core_options.h @@ -97,13 +97,11 @@ struct retro_core_option_v2_category option_cats_us[] = { "Compatibility Fixes", "Configure settings/workarounds required for correct operation of specific games." }, -#if !defined(DRC_DISABLE) && !defined(LIGHTREC) { "speed_hack", "Speed Hacks (Advanced)", "Configure hacks that may improve performance at the expense of decreased accuracy/stability." }, -#endif { NULL, NULL, NULL }, }; @@ -1572,6 +1570,20 @@ struct retro_core_option_v2_definition option_defs_us[] = { }, "disabled", }, + { + "pcsx_rearmed_cd_turbo", + "Turbo CD", + NULL, + "This makes the emulated CD-ROM extremely fast and can reduce loading times in some cases. Warning: many games were not programmed to handle such a speed. The game (or even the emulator) MAY CRASH at ANY TIME if this is enabled.", + NULL, + "speed_hack", + { + { "disabled", NULL }, + { "enabled", NULL }, + { NULL, NULL }, + }, + "disabled", + }, #if !defined(DRC_DISABLE) && !defined(LIGHTREC) { "pcsx_rearmed_nocompathacks", @@ -1634,13 +1646,13 @@ struct retro_core_option_v2_definition option_defs_us[] = { "pcsx_rearmed_nostalls", "Disable CPU/GTE Stalls", NULL, - "Will cause some games to run too quickly." + "Will cause some games to run too quickly. Should be disabled in almost all cases." #if defined(LIGHTREC) " Interpreter only." #endif , NULL, - "compat_hack", + "speed_hack", { { "disabled", NULL }, { "enabled", NULL }, diff --git a/frontend/main.c b/frontend/main.c index ce7eca6c..6df1731d 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -417,6 +417,8 @@ void emu_on_new_cd(int show_hud_msg) SysPrintf("note: running with HLE BIOS, expect compatibility problems\n"); SysPrintf("----------------------------------------------------------\n"); } + if (Config.TurboCD) + SysPrintf("note: TurboCD is enabled, this breaks games\n"); if (show_hud_msg) { if (check_unsatisfied_libcrypt()) diff --git a/frontend/menu.c b/frontend/menu.c index 58efd218..39f0a697 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -410,6 +410,7 @@ static const struct { CE_CONFIG_VAL(GpuListWalking), CE_CONFIG_VAL(FractionalFramerate), CE_CONFIG_VAL(PreciseExceptions), + CE_CONFIG_VAL(TurboCD), CE_INTVAL(region), CE_INTVAL_V(g_scaler, 3), CE_INTVAL(g_gamma), @@ -1660,10 +1661,11 @@ static const char h_cfg_gpul[] = "Try enabling this if the game misses some gr "causes a performance hit"; static const char h_cfg_ffps[] = "Instead of 50/60fps for PAL/NTSC use ~49.75/59.81\n" "Closer to real hw but doesn't match modern displays."; +static const char h_cfg_tcd[] = "Greatly reduce CD load times. Breaks some games."; 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_BP, AMO_CPU, AMO_GPUL, AMO_FFPS }; +enum { AMO_XA, AMO_CDDA, AMO_IC, AMO_BP, AMO_CPU, AMO_GPUL, AMO_FFPS, AMO_TCD }; static menu_entry e_menu_adv_options[] = { @@ -1676,6 +1678,7 @@ static menu_entry e_menu_adv_options[] = mee_onoff_h ("BP exception emulation", 0, menu_iopts[AMO_BP], 1, h_cfg_exc), mee_enum_h ("GPU l-list slow walking",0, menu_iopts[AMO_GPUL], men_autooo, h_cfg_gpul), mee_enum_h ("Fractional framerate", 0, menu_iopts[AMO_FFPS], men_autooo, h_cfg_ffps), + mee_onoff_h ("Turbo CD-ROM ", 0, menu_iopts[AMO_TCD], 1, h_cfg_tcd), #if !defined(DRC_DISABLE) || defined(LIGHTREC) mee_onoff_h ("Disable dynarec (slow!)",0, menu_iopts[AMO_CPU], 1, h_cfg_nodrc), #endif @@ -1696,6 +1699,7 @@ static int menu_loop_adv_options(int id, int keys) { &Config.icache_emulation, &menu_iopts[AMO_IC] }, { &Config.PreciseExceptions, &menu_iopts[AMO_BP] }, { &Config.Cpu, &menu_iopts[AMO_CPU] }, + { &Config.TurboCD, &menu_iopts[AMO_TCD] }, }; int i; for (i = 0; i < ARRAY_SIZE(opts); i++) diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index d4d14742..200dcf98 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -111,7 +111,7 @@ static struct { u8 AdpcmActive; u32 LastReadSeekCycles; - u8 unused7; + u8 RetryDetected; u8 DriveState; // enum drive_state u8 FastForward; @@ -576,6 +576,14 @@ static void cdrPlayInterrupt_Autopause() cdr.ReportDelay--; } +static boolean canDoTurbo(void) +{ + u32 c = psxRegs.cycle; + return Config.TurboCD && !cdr.RetryDetected && !cdr.AdpcmActive + //&& c - psxRegs.intCycle[PSXINT_SPUDMA].sCycle > (u32)cdReadTime * 2 + && c - psxRegs.intCycle[PSXINT_MDECOUTDMA].sCycle > (u32)cdReadTime * 16; +} + static int cdrSeekTime(unsigned char *target) { int diff = msf2sec(cdr.SetSectorPlay) - msf2sec(target); @@ -654,6 +662,11 @@ static void msfiSub(u8 *msfi, u32 count) } } +static int msfiEq(const u8 *a, const u8 *b) +{ + return a[0] == b[0] && a[1] == b[1] && a[2] == b[2]; +} + void cdrPlayReadInterrupt(void) { int hit = CDR_prefetch(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2]); @@ -822,6 +835,9 @@ void cdrInterrupt(void) { { for (i = 0; i < 3; i++) set_loc[i] = btoi(cdr.Param[i]); + cdr.RetryDetected = msfiEq(cdr.SetSector, set_loc) + && !cdr.SetlocPending; + //cdr.RetryDetected |= msfiEq(cdr.Param, cdr.Transfer); memcpy(cdr.SetSector, set_loc, 3); cdr.SetSector[3] = 0; cdr.SetlocPending = 1; @@ -1103,7 +1119,8 @@ void cdrInterrupt(void) { StopReading(); SetPlaySeekRead(cdr.StatP, STATUS_SEEK | STATUS_ROTATING); - seekTime = cdrSeekTime(cdr.SetSector); + if (!canDoTurbo()) + seekTime = cdrSeekTime(cdr.SetSector); memcpy(cdr.SetSectorPlay, cdr.SetSector, 4); cdr.DriveState = DRIVESTATE_SEEK; CDR_prefetch(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], @@ -1252,6 +1269,8 @@ void cdrInterrupt(void) { cycles += seekTime; if (Config.hacks.cdr_read_timing) cycles = cdrAlignTimingHack(cycles); + else if (canDoTurbo()) + cycles = cdReadTime / 2; CDRPLAYREAD_INT(cycles, 1); SetPlaySeekRead(cdr.StatP, STATUS_SEEK); @@ -1443,6 +1462,8 @@ unsigned char cdrRead0(void) { cdr.Ctrl |= cdr.AdpcmActive << 2; cdr.Ctrl |= cdr.ResultReady << 5; + //cdr.Ctrl &= ~0x40; + //if (cdr.FifoOffset != DATA_SIZE) cdr.Ctrl |= 0x40; // data fifo not empty // What means the 0x10 and the 0x08 bits? I only saw it used by the bios @@ -1642,7 +1663,7 @@ void cdrWrite3(unsigned char rt) { } void psxDma3(u32 madr, u32 bcr, u32 chcr) { - u32 cdsize, max_words; + u32 cdsize, max_words, cycles; int size; u8 *ptr; @@ -1688,7 +1709,8 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { } psxCpu->Clear(madr, cdsize / 4); - set_event(PSXINT_CDRDMA, (cdsize / 4) * 24); + cycles = (cdsize / 4) * 24; + set_event(PSXINT_CDRDMA, cycles); HW_DMA3_CHCR &= SWAPu32(~0x10000000); if (chcr & 0x100) { @@ -1697,8 +1719,10 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { } else { // halted - psxRegs.cycle += (cdsize/4) * 24 - 20; + psxRegs.cycle += cycles - 20; } + if (canDoTurbo() && cdr.Reading && cdr.FifoOffset >= 2048) + CDRPLAYREAD_INT(cycles + 4096, 1); return; default: diff --git a/libpcsxcore/misc.c b/libpcsxcore/misc.c index 889639d6..47a32cce 100644 --- a/libpcsxcore/misc.c +++ b/libpcsxcore/misc.c @@ -379,7 +379,7 @@ int CheckCdrom() { time[2] = itob(0x10); if (!Config.HLE && Config.SlowBoot) { - // boot to BIOS in case of CDDA ir lid open + // boot to BIOS in case of CDDA or lid is open CDR_getStatus(&stat); if ((stat.Status & 0x10) || stat.Type == 2 || !CDR_readTrack(time)) return 0; diff --git a/libpcsxcore/psxcommon.h b/libpcsxcore/psxcommon.h index 53bda973..0a0bd863 100644 --- a/libpcsxcore/psxcommon.h +++ b/libpcsxcore/psxcommon.h @@ -142,6 +142,7 @@ typedef struct { boolean icache_emulation; boolean DisableStalls; boolean PreciseExceptions; + boolean TurboCD; int cycle_multiplier; // 100 for 1.0 int cycle_multiplier_override; s8 GpuListWalking; -- 2.39.2