new experimental TurboCD option
authornotaz <notasas@gmail.com>
Thu, 18 Apr 2024 18:12:41 +0000 (21:12 +0300)
committernotaz <notasas@gmail.com>
Thu, 18 Apr 2024 23:42:29 +0000 (02:42 +0300)
frontend/libretro.c
frontend/libretro_core_options.h
frontend/main.c
frontend/menu.c
libpcsxcore/cdrom.c
libpcsxcore/misc.c
libpcsxcore/psxcommon.h

index 6a719ae..7ad4caa 100644 (file)
@@ -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";
index 451ee47..e79e902 100644 (file)
@@ -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 },
index ce7eca6..6df1731 100644 (file)
@@ -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())
index 58efd21..39f0a69 100644 (file)
@@ -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++)
index d4d1474..200dcf9 100644 (file)
@@ -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:
index 889639d..47a32cc 100644 (file)
@@ -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;
index 53bda97..0a0bd86 100644 (file)
@@ -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;