From df717ca9bf196fd40134d16f94b7f3c774f2c897 Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 5 Sep 2022 19:41:52 +0300 Subject: [PATCH] cdrom: try to eliminate playback timing drifting --- libpcsxcore/cdrom.c | 28 ++++++++++++++++------------ libpcsxcore/r3000a.h | 14 ++++++++------ 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index fb526b40..184d07ab 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -242,11 +242,15 @@ static void sec2msf(unsigned int s, u8 *msf) { } // cdrPlaySeekReadInterrupt -#define CDRPLAYSEEKREAD_INT(eCycle) { \ +#define CDRPLAYSEEKREAD_INT(eCycle, isFirst) { \ + u32 e_ = eCycle; \ psxRegs.interrupt |= (1 << PSXINT_CDREAD); \ - psxRegs.intCycle[PSXINT_CDREAD].cycle = eCycle; \ - psxRegs.intCycle[PSXINT_CDREAD].sCycle = psxRegs.cycle; \ - new_dyna_set_event(PSXINT_CDREAD, eCycle); \ + if (isFirst) \ + psxRegs.intCycle[PSXINT_CDREAD].sCycle = psxRegs.cycle; \ + else \ + psxRegs.intCycle[PSXINT_CDREAD].sCycle += psxRegs.intCycle[PSXINT_CDREAD].cycle; \ + psxRegs.intCycle[PSXINT_CDREAD].cycle = e_; \ + new_dyna_set_event_abs(PSXINT_CDREAD, psxRegs.intCycle[PSXINT_CDREAD].sCycle + e_); \ } // cdrLidSeekInterrupt @@ -588,7 +592,7 @@ void cdrPlaySeekReadInterrupt(void) if (!cdr.Play && (cdr.StatP & STATUS_SEEK)) { if (cdr.Stat) { CDR_LOG_I("cdrom: seek stat hack\n"); - CDRPLAYSEEKREAD_INT(0x1000); + CDRPLAYSEEKREAD_INT(0x1000, 1); return; } SetResultSize(1); @@ -640,7 +644,7 @@ void cdrPlaySeekReadInterrupt(void) } } - CDRPLAYSEEKREAD_INT(cdReadTime); + CDRPLAYSEEKREAD_INT(cdReadTime, 0); // update for CdlGetlocP/autopause generate_subq(cdr.SetSectorPlay); @@ -766,7 +770,7 @@ void cdrInterrupt(void) { // BIOS player - set flag again cdr.Play = TRUE; - CDRPLAYSEEKREAD_INT(cdReadTime + seekTime); + CDRPLAYSEEKREAD_INT(cdReadTime + seekTime, 1); start_rotating = 1; break; @@ -974,7 +978,7 @@ void cdrInterrupt(void) { Rockman X5 = 0.5-4x - fix capcom logo */ - CDRPLAYSEEKREAD_INT(cdReadTime + seekTime); + CDRPLAYSEEKREAD_INT(cdReadTime + seekTime, 1); start_rotating = 1; break; @@ -1072,7 +1076,7 @@ void cdrInterrupt(void) { // - fixes new game ReadTrack(cdr.SetSectorPlay); - CDRPLAYSEEKREAD_INT(((cdr.Mode & 0x80) ? (cdReadTime) : cdReadTime * 2) + seekTime); + CDRPLAYSEEKREAD_INT(((cdr.Mode & 0x80) ? (cdReadTime) : cdReadTime * 2) + seekTime, 1); SetPlaySeekRead(cdr.StatP, STATUS_SEEK); start_rotating = 1; @@ -1168,7 +1172,7 @@ static void cdrReadInterrupt(void) if (cdr.Irq || cdr.Stat) { CDR_LOG_I("cdrom: read stat hack %02x %x\n", cdr.Irq, cdr.Stat); - CDRPLAYSEEKREAD_INT(2048); + CDRPLAYSEEKREAD_INT(2048, 1); return; } @@ -1235,7 +1239,7 @@ static void cdrReadInterrupt(void) cdr.Readed = 0; - CDRPLAYSEEKREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime); + CDRPLAYSEEKREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime, 0); /* Croc 2: $40 - only FORM1 (*) @@ -1588,7 +1592,7 @@ int cdrFreeze(void *f, int Mode) { if (!Config.Cdda) CDR_play(cdr.SetSectorPlay); if (psxRegs.interrupt & (1 << PSXINT_CDRPLAY_OLD)) - CDRPLAYSEEKREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); + CDRPLAYSEEKREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime, 1); } if ((cdr.freeze_ver & 0xffffff00) != 0x63647200) { diff --git a/libpcsxcore/r3000a.h b/libpcsxcore/r3000a.h index ea6f0e75..49afcb1c 100644 --- a/libpcsxcore/r3000a.h +++ b/libpcsxcore/r3000a.h @@ -206,17 +206,19 @@ void new_dyna_before_save(void); void new_dyna_after_save(void); void new_dyna_freeze(void *f, int mode); -#define new_dyna_set_event(e, c) { \ - s32 c_ = c; \ - u32 abs_ = psxRegs.cycle + c_; \ - s32 odi_ = next_interupt - psxRegs.cycle; \ +#define new_dyna_set_event_abs(e, abs) { \ + u32 abs_ = abs; \ + s32 di_ = next_interupt - abs_; \ event_cycles[e] = abs_; \ - if (c_ < odi_) { \ - /*printf("%u: next_interupt %d -> %d (%u)\n", psxRegs.cycle, odi_, c_, abs_);*/ \ + if (di_ > 0) { \ + /*printf("%u: next_interupt %u -> %u\n", psxRegs.cycle, next_interupt, abs_);*/ \ next_interupt = abs_; \ } \ } +#define new_dyna_set_event(e, c) \ + new_dyna_set_event_abs(e, psxRegs.cycle + (c)) + #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #define _i32(x) *(s32 *)&x -- 2.39.2