# libchdr
#ifeq "$(HAVE_CHD)" "1"
LCHDR = deps/libchdr
-LCHDR_LZMA = $(LCHDR)/deps/lzma-22.01
-LCHDR_ZSTD = $(LCHDR)/deps/zstd-1.5.5/lib
+LCHDR_LZMA = $(LCHDR)/deps/lzma-24.05
+LCHDR_ZSTD = $(LCHDR)/deps/zstd-1.5.6/lib
OBJS += $(LCHDR)/src/libchdr_bitstream.o
OBJS += $(LCHDR)/src/libchdr_cdrom.o
OBJS += $(LCHDR)/src/libchdr_chd.o
OBJS += $(LCHDR)/src/libchdr_huffman.o
$(LCHDR)/src/%.o: CFLAGS += -Wno-unused -std=gnu11
OBJS += $(LCHDR_LZMA)/src/Alloc.o
-OBJS += $(LCHDR_LZMA)/src/Bra86.o
-OBJS += $(LCHDR_LZMA)/src/BraIA64.o
OBJS += $(LCHDR_LZMA)/src/CpuArch.o
OBJS += $(LCHDR_LZMA)/src/Delta.o
OBJS += $(LCHDR_LZMA)/src/LzFind.o
-OBJS += $(LCHDR_LZMA)/src/Lzma86Dec.o
OBJS += $(LCHDR_LZMA)/src/LzmaDec.o
OBJS += $(LCHDR_LZMA)/src/LzmaEnc.o
OBJS += $(LCHDR_LZMA)/src/Sort.o
-$(LCHDR_LZMA)/src/%.o: CFLAGS += -Wno-unused -D_7ZIP_ST -I$(LCHDR_LZMA)/include
+$(LCHDR_LZMA)/src/%.o: CFLAGS += -Wno-unused -DZ7_ST -I$(LCHDR_LZMA)/include
$(LCHDR)/src/%.o: CFLAGS += -I$(LCHDR_LZMA)/include
-OBJS += $(LCHDR_ZSTD)/common/debug.o
OBJS += $(LCHDR_ZSTD)/common/entropy_common.o
OBJS += $(LCHDR_ZSTD)/common/error_private.o
OBJS += $(LCHDR_ZSTD)/common/fse_decompress.o
-OBJS += $(LCHDR_ZSTD)/common/pool.o
-OBJS += $(LCHDR_ZSTD)/common/threading.o
OBJS += $(LCHDR_ZSTD)/common/xxhash.o
OBJS += $(LCHDR_ZSTD)/common/zstd_common.o
OBJS += $(LCHDR_ZSTD)/decompress/huf_decompress.o
+OBJS += $(LCHDR_ZSTD)/decompress/huf_decompress_amd64.o
OBJS += $(LCHDR_ZSTD)/decompress/zstd_ddict.o
OBJS += $(LCHDR_ZSTD)/decompress/zstd_decompress_block.o
OBJS += $(LCHDR_ZSTD)/decompress/zstd_decompress.o
$(LCHDR_ZSTD)/common/%.o \
-$(LCHDR_ZSTD)/decompress/%.o: CFLAGS += -DZSTD_DISABLE_ASM -I$(LCHDR_ZSTD)
+$(LCHDR_ZSTD)/decompress/%.o: CFLAGS += -I$(LCHDR_ZSTD)
$(LCHDR)/src/%.o: CFLAGS += -I$(LCHDR_ZSTD)
libpcsxcore/cdriso.o: CFLAGS += -Wno-unused-function
CFLAGS += -DHAVE_CHD -I$(LCHDR)/include
-Subproject commit 5c598c2df3a7717552a76410d79f5af01ff51b1d
+Subproject commit 86b272076d542287d3f03952e7d4efe283e815bf
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;
}
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";
"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 },
};
},
"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",
"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 },
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())
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),
"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[] =
{
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
{ &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++)
u8 AdpcmActive;
u32 LastReadSeekCycles;
- u8 unused7;
+ u8 RetryDetected;
u8 DriveState; // enum drive_state
u8 FastForward;
DRIVESTATE_SEEK,
};
-static struct CdrStat stat;
+static struct CdrStat cdr_stat;
static unsigned int msf2sec(const u8 *msf) {
return ((msf[0] * 60 + msf[1]) * 75) + msf[2];
//StopReading();
SetPlaySeekRead(cdr.StatP, 0);
- if (CDR_getStatus(&stat) == -1)
+ if (CDR_getStatus(&cdr_stat) == -1)
return;
- if (stat.Status & STATUS_SHELLOPEN)
+ if (cdr_stat.Status & STATUS_SHELLOPEN)
{
memset(cdr.Prev, 0xff, sizeof(cdr.Prev));
cdr.DriveState = DRIVESTATE_LID_OPEN;
break;
case DRIVESTATE_LID_OPEN:
- if (CDR_getStatus(&stat) == -1)
- stat.Status &= ~STATUS_SHELLOPEN;
+ if (CDR_getStatus(&cdr_stat) == -1)
+ cdr_stat.Status &= ~STATUS_SHELLOPEN;
// 02, 12, 10
if (!(cdr.StatP & STATUS_SHELLOPEN)) {
else if (cdr.StatP & STATUS_ROTATING) {
cdr.StatP &= ~STATUS_ROTATING;
}
- else if (!(stat.Status & STATUS_SHELLOPEN)) {
+ else if (!(cdr_stat.Status & STATUS_SHELLOPEN)) {
// closed now
CheckCdrom();
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);
}
}
+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]);
static void softReset(void)
{
- CDR_getStatus(&stat);
- if (stat.Status & STATUS_SHELLOPEN) {
+ CDR_getStatus(&cdr_stat);
+ if (cdr_stat.Status & STATUS_SHELLOPEN) {
cdr.DriveState = DRIVESTATE_LID_OPEN;
cdr.StatP = STATUS_SHELLOPEN;
}
{
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;
cdr.sectorsRead = 0;
/*
- Gundam Battle Assault 2: much slower (*)
- - Fixes boot, gameplay
-
- Hokuto no Ken 2: slower
- - Fixes intro + subtitles
-
- InuYasha - Feudal Fairy Tale: slower
- - Fixes battles
+ Gundam Battle Assault 2
+ Hokuto no Ken 2
+ InuYasha - Feudal Fairy Tale
+ Dance Dance Revolution Konamix
+ ...
*/
- /* Gameblabla - Tightening the timings (as taken from Duckstation).
- * The timings from Duckstation are based upon hardware tests.
- * Mednafen's timing don't work for Gundam Battle Assault 2 in PAL/50hz mode,
- * seems to be timing sensitive as it can depend on the CPU's clock speed.
- * */
if (!(cdr.StatP & (STATUS_PLAY | STATUS_READ)))
{
second_resp_time = 7000;
}
else
{
- second_resp_time = (((cdr.Mode & MODE_SPEED) ? 1 : 2) * 1097107);
+ second_resp_time = 2 * 1097107;
}
SetPlaySeekRead(cdr.StatP, 0);
DriveStateOld = cdr.DriveState;
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],
cdr.Result[3] = 0;
// 0x10 - audio | 0x40 - disk missing | 0x80 - unlicensed
- if (CDR_getStatus(&stat) == -1 || stat.Type == 0 || stat.Type == 0xff) {
+ if (CDR_getStatus(&cdr_stat) == -1 || cdr_stat.Type == 0 || cdr_stat.Type == 0xff) {
cdr.Result[1] = 0xc0;
}
else {
- if (stat.Type == 2)
+ if (cdr_stat.Type == 2)
cdr.Result[1] |= 0x10;
if (CdromId[0] == '\0')
cdr.Result[1] |= 0x80;
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);
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
}
void psxDma3(u32 madr, u32 bcr, u32 chcr) {
- u32 cdsize, max_words;
+ u32 cdsize, max_words, cycles;
int size;
u8 *ptr;
}
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) {
}
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:
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;
boolean icache_emulation;
boolean DisableStalls;
boolean PreciseExceptions;
+ boolean TurboCD;
int cycle_multiplier; // 100 for 1.0
int cycle_multiplier_override;
s8 GpuListWalking;
void psxDma2(u32 madr, u32 bcr, u32 chcr) { // GPU
u32 *ptr, madr_next, *madr_next_p;
u32 words, words_left, words_max, words_copy;
- int cycles_sum, cycles_last_cmd = 0, do_walking;
+ s32 cycles_last_cmd = 0;
+ int do_walking;
+ long cycles_sum;
madr &= ~3;
switch (chcr) {
if (HW_DMA2_CHCR == SWAP32(0x01000401) && !(HW_DMA2_MADR & SWAP32(0x800000)))
{
u32 madr_next = 0xffffff, madr = SWAPu32(HW_DMA2_MADR);
- int cycles_sum, cycles_last_cmd = 0;
+ s32 cycles_last_cmd = 0;
+ long cycles_sum;
+
cycles_sum = GPU_dmaChain((u32 *)psxM, madr & 0x1fffff,
&madr_next, &cycles_last_cmd);
HW_DMA2_MADR = SWAPu32(madr_next);
gpu.frameskip.advice = &cbs->fskip_advice;
gpu.frameskip.active = 0;
gpu.frameskip.frame_ready = 1;
- gpu.state.hcnt = cbs->gpu_hcnt;
- gpu.state.frame_count = cbs->gpu_frame_count;
+ gpu.state.hcnt = (uint32_t *)cbs->gpu_hcnt;
+ gpu.state.frame_count = (uint32_t *)cbs->gpu_frame_count;
gpu.state.allow_interlace = cbs->gpu_neon.allow_interlace;
gpu.state.enhancement_enable = cbs->gpu_neon.enhancement_enable;
gpu.state.screen_centering_type_default = cbs->screen_centering_type_default;
////////////////////////////////////////////////////////////////////////\r
-unsigned short CALLBACK SPUreadRegister(unsigned long reg)
+unsigned short CALLBACK SPUreadRegister(unsigned long reg, unsigned int cycles)
{
unsigned long r=reg&0xfff;
// XA AUDIO
////////////////////////////////////////////////////////////////////////
-void CALLBACK SPUplayADPCMchannel(xa_decode_t *xap)
+void CALLBACK SPUplayADPCMchannel(xa_decode_t *xap, unsigned int cycles, int is_start)
{
}
{
}
-int SPUplayCDDAchannel(short *pcm, int nbytes)
+int SPUplayCDDAchannel(short *pcm, int nbytes, unsigned int cycle, int is_start)
{
return -1;
}
{
//SoundOff(16,24,channels);
}
+
+void CALLBACK SPUregisterScheduleCb(void (CALLBACK *callback)(unsigned int))
+{
+}