diff --git a/pcsx2/CDVD/CDVD.cpp b/pcsx2/CDVD/CDVD.cpp index 88e3640a78666..e49ec793e89d5 100644 --- a/pcsx2/CDVD/CDVD.cpp +++ b/pcsx2/CDVD/CDVD.cpp @@ -1148,7 +1148,6 @@ __fi void cdvdActionInterrupt() cdvdUpdateReady(CDVD_DRIVE_READY); cdvd.CurrentSector = cdvd.SeekToSector; cdvdUpdateStatus(CDVD_STATUS_PAUSE); - cdvd.nextSectorsBuffered = 0; CDVDSECTORREADY_INT(cdvd.ReadTime); break; @@ -1190,7 +1189,7 @@ __fi void cdvdSectorReady() if (cdvd.nextSectorsBuffered < 16) CDVDSECTORREADY_INT(cdvd.ReadTime); - else + else if (!cdvd.Reading) cdvdUpdateStatus(CDVD_STATUS_PAUSE); } @@ -1314,7 +1313,7 @@ __fi void cdvdReadInterrupt() // Street Fighter Ex3 (NTSC-J version). cdvdSetIrq(); cdvdUpdateReady(CDVD_DRIVE_READY); - + cdvd.Reading = 0; if (cdvd.nextSectorsBuffered < 16) cdvdUpdateStatus(CDVD_STATUS_READ); else @@ -1340,7 +1339,11 @@ __fi void cdvdReadInterrupt() cdvdUpdateStatus(CDVD_STATUS_PAUSE); return; } - CDVDREAD_INT((cdvd.BlockSize / 4) * 12); + if (cdvd.nextSectorsBuffered) + CDVDREAD_INT((cdvd.BlockSize / 4) * 12); + else + CDVDREAD_INT(psxRemainingCycles(IopEvt_CdvdSectorReady) + ((cdvd.BlockSize / 4) * 12)); + return; } @@ -1350,7 +1353,7 @@ __fi void cdvdReadInterrupt() if (cdvd.nextSectorsBuffered) CDVDREAD_INT((cdvd.BlockSize / 4) * 12); else - CDVDREAD_INT((psxRegs.cycle - psxRegs.sCycle[IopEvt_CdvdSectorReady]) + ((cdvd.BlockSize / 4) * 12)); + CDVDREAD_INT(psxRemainingCycles(IopEvt_CdvdSectorReady) + ((cdvd.BlockSize / 4) * 12)); } // Returns the number of IOP cycles until the event completes. @@ -1421,44 +1424,46 @@ static uint cdvdStartSeek(uint newsector, CDVD_MODE_TYPE mode, bool transition_t isSeeking = false; - if (delta == 0) + if (cdvd.Action != cdvdAction_Seek) { - //cdvd.Status = CDVD_STATUS_PAUSE; - cdvdUpdateStatus(CDVD_STATUS_READ); - cdvd.SeekCompleted = 1; // Note: 1, not 0, as implied by the next comment. Need to look into this. --arcum42 - cdvd.Reading = 1; // We don't need to wait for it to read a sector as it's already queued up, or we adjust for it here. - cdvd.CurrentRetryCnt = 0; - - // setting Readed to 0 skips the seek logic, which means the next call to - // cdvdReadInterrupt will load a block. So make sure it's properly scheduled - // based on sector read speeds: + if (delta == 0) + { + //cdvd.Status = CDVD_STATUS_PAUSE; + cdvdUpdateStatus(CDVD_STATUS_READ); + cdvd.SeekCompleted = 1; // Note: 1, not 0, as implied by the next comment. Need to look into this. --arcum42 + cdvd.Reading = 1; // We don't need to wait for it to read a sector as it's already queued up, or we adjust for it here. + cdvd.CurrentRetryCnt = 0; - //seektime = cdvd.ReadTime; + // setting Readed to 0 skips the seek logic, which means the next call to + // cdvdReadInterrupt will load a block. So make sure it's properly scheduled + // based on sector read speeds: - if (!cdvd.nextSectorsBuffered)//Buffering time hasn't completed yet so cancel it and simulate the remaining time - { - if (psxRegs.interrupt & (1 << IopEvt_CdvdSectorReady)) + //seektime = cdvd.ReadTime; + if (!cdvd.nextSectorsBuffered)//Buffering time hasn't completed yet so cancel it and simulate the remaining time { - //DevCon.Warning("coming back from ready sector early reducing %d cycles by %d cycles", seektime, psxRegs.cycle - psxRegs.sCycle[IopEvt_CdvdSectorReady]); - seektime = (psxRegs.cycle - psxRegs.sCycle[IopEvt_CdvdSectorReady]) + ((cdvd.BlockSize / 4) * 12); + if (psxRegs.interrupt & (1 << IopEvt_CdvdSectorReady)) + { + //DevCon.Warning("coming back from ready sector early reducing %d cycles by %d cycles", seektime, psxRegs.cycle - psxRegs.sCycle[IopEvt_CdvdSectorReady]); + seektime = psxRemainingCycles(IopEvt_CdvdSectorReady) + ((cdvd.BlockSize / 4) * 12); + } + else + { + delta = 1; // Forces it to use the rotational delay since we have no sectors buffered and it isn't buffering any. + } } else - { - delta = 1; // Forces it to use the rotational delay since we have no sectors buffered and it isn't buffering any. - } + return (cdvd.BlockSize / 4) * 12; } else - return (cdvd.BlockSize / 4) * 12; - } - else - { - if (delta >= cdvd.nextSectorsBuffered) { - psxRegs.interrupt &= ~(1 << IopEvt_CdvdSectorReady); - cdvd.nextSectorsBuffered = 0; + if (delta >= cdvd.nextSectorsBuffered) + { + psxRegs.interrupt &= ~(1 << IopEvt_CdvdSectorReady); + cdvd.nextSectorsBuffered = 0; + } + else + cdvd.nextSectorsBuffered -= delta; } - else - cdvd.nextSectorsBuffered -= delta; } } @@ -1883,9 +1888,9 @@ static void cdvdWrite04(u8 rt) case N_CD_SEEK: // CdSeek cdvdUpdateReady(CDVD_DRIVE_BUSY); + cdvd.Action = cdvdAction_Seek; // Have to do this first, the StartSeek relies on it CDVD_INT(cdvdStartSeek(GetBufferU32(&cdvd.NCMDParamBuff[0], 0), static_cast(cdvdIsDVD()), false)); cdvdUpdateStatus(CDVD_STATUS_SEEK); - cdvd.Action = cdvdAction_Seek; break; case N_CD_READ: // CdRead diff --git a/pcsx2/IopHw.h b/pcsx2/IopHw.h index 03d0d6b0b4f75..5135719912e9e 100644 --- a/pcsx2/IopHw.h +++ b/pcsx2/IopHw.h @@ -326,6 +326,7 @@ enum IopEventId }; extern void PSX_INT( IopEventId n, s32 ecycle); +extern int psxRemainingCycles(IopEventId n); extern void psxSetNextBranch( u32 startCycle, s32 delta ); extern void psxSetNextBranchDelta( s32 delta ); diff --git a/pcsx2/R3000A.cpp b/pcsx2/R3000A.cpp index ef95b1456e24e..28fa5bfe3042b 100644 --- a/pcsx2/R3000A.cpp +++ b/pcsx2/R3000A.cpp @@ -129,6 +129,14 @@ __fi int psxTestCycle( u32 startCycle, s32 delta ) return (int)(psxRegs.cycle - startCycle) >= delta; } +__fi int psxRemainingCycles(IopEventId n) +{ + if (psxRegs.interrupt & (1 << n)) + return ((psxRegs.cycle - psxRegs.sCycle[n]) + psxRegs.eCycle[n]); + else + return 0; +} + __fi void PSX_INT( IopEventId n, s32 ecycle ) { // 19 is CDVD read int, it's supposed to be high. @@ -189,8 +197,8 @@ static __fi void _psxTestInterrupts() IopTestEvent(IopEvt_SIF1, sif1Interrupt); // SIF1 IopTestEvent(IopEvt_SIF2, sif2Interrupt); // SIF2 Sio0TestEvent(IopEvt_SIO); - IopTestEvent(IopEvt_CdvdRead, cdvdReadInterrupt); IopTestEvent(IopEvt_CdvdSectorReady, cdvdSectorReady); + IopTestEvent(IopEvt_CdvdRead, cdvdReadInterrupt); // Profile-guided Optimization (sorta) // The following ints are rarely called. Encasing them in a conditional