mirror of https://github.com/PCSX2/pcsx2.git
CDVD: Fix seek times, improve read flow
This commit is contained in:
parent
493e95d9d6
commit
aa77d156a9
|
@ -1148,7 +1148,6 @@ __fi void cdvdActionInterrupt()
|
||||||
cdvdUpdateReady(CDVD_DRIVE_READY);
|
cdvdUpdateReady(CDVD_DRIVE_READY);
|
||||||
cdvd.CurrentSector = cdvd.SeekToSector;
|
cdvd.CurrentSector = cdvd.SeekToSector;
|
||||||
cdvdUpdateStatus(CDVD_STATUS_PAUSE);
|
cdvdUpdateStatus(CDVD_STATUS_PAUSE);
|
||||||
cdvd.nextSectorsBuffered = 0;
|
|
||||||
CDVDSECTORREADY_INT(cdvd.ReadTime);
|
CDVDSECTORREADY_INT(cdvd.ReadTime);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1190,7 +1189,7 @@ __fi void cdvdSectorReady()
|
||||||
|
|
||||||
if (cdvd.nextSectorsBuffered < 16)
|
if (cdvd.nextSectorsBuffered < 16)
|
||||||
CDVDSECTORREADY_INT(cdvd.ReadTime);
|
CDVDSECTORREADY_INT(cdvd.ReadTime);
|
||||||
else
|
else if (!cdvd.Reading)
|
||||||
cdvdUpdateStatus(CDVD_STATUS_PAUSE);
|
cdvdUpdateStatus(CDVD_STATUS_PAUSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1314,7 +1313,7 @@ __fi void cdvdReadInterrupt()
|
||||||
// Street Fighter Ex3 (NTSC-J version).
|
// Street Fighter Ex3 (NTSC-J version).
|
||||||
cdvdSetIrq();
|
cdvdSetIrq();
|
||||||
cdvdUpdateReady(CDVD_DRIVE_READY);
|
cdvdUpdateReady(CDVD_DRIVE_READY);
|
||||||
|
cdvd.Reading = 0;
|
||||||
if (cdvd.nextSectorsBuffered < 16)
|
if (cdvd.nextSectorsBuffered < 16)
|
||||||
cdvdUpdateStatus(CDVD_STATUS_READ);
|
cdvdUpdateStatus(CDVD_STATUS_READ);
|
||||||
else
|
else
|
||||||
|
@ -1340,7 +1339,11 @@ __fi void cdvdReadInterrupt()
|
||||||
cdvdUpdateStatus(CDVD_STATUS_PAUSE);
|
cdvdUpdateStatus(CDVD_STATUS_PAUSE);
|
||||||
return;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1350,7 +1353,7 @@ __fi void cdvdReadInterrupt()
|
||||||
if (cdvd.nextSectorsBuffered)
|
if (cdvd.nextSectorsBuffered)
|
||||||
CDVDREAD_INT((cdvd.BlockSize / 4) * 12);
|
CDVDREAD_INT((cdvd.BlockSize / 4) * 12);
|
||||||
else
|
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.
|
// 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;
|
isSeeking = false;
|
||||||
|
|
||||||
if (delta == 0)
|
if (cdvd.Action != cdvdAction_Seek)
|
||||||
{
|
{
|
||||||
//cdvd.Status = CDVD_STATUS_PAUSE;
|
if (delta == 0)
|
||||||
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:
|
|
||||||
|
|
||||||
//seektime = cdvd.ReadTime;
|
|
||||||
|
|
||||||
if (!cdvd.nextSectorsBuffered)//Buffering time hasn't completed yet so cancel it and simulate the remaining time
|
|
||||||
{
|
{
|
||||||
if (psxRegs.interrupt & (1 << IopEvt_CdvdSectorReady))
|
//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:
|
||||||
|
|
||||||
|
//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]);
|
if (psxRegs.interrupt & (1 << IopEvt_CdvdSectorReady))
|
||||||
seektime = (psxRegs.cycle - psxRegs.sCycle[IopEvt_CdvdSectorReady]) + ((cdvd.BlockSize / 4) * 12);
|
{
|
||||||
|
//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
|
else
|
||||||
{
|
return (cdvd.BlockSize / 4) * 12;
|
||||||
delta = 1; // Forces it to use the rotational delay since we have no sectors buffered and it isn't buffering any.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return (cdvd.BlockSize / 4) * 12;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (delta >= cdvd.nextSectorsBuffered)
|
|
||||||
{
|
{
|
||||||
psxRegs.interrupt &= ~(1 << IopEvt_CdvdSectorReady);
|
if (delta >= cdvd.nextSectorsBuffered)
|
||||||
cdvd.nextSectorsBuffered = 0;
|
{
|
||||||
|
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
|
case N_CD_SEEK: // CdSeek
|
||||||
cdvdUpdateReady(CDVD_DRIVE_BUSY);
|
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<CDVD_MODE_TYPE>(cdvdIsDVD()), false));
|
CDVD_INT(cdvdStartSeek(GetBufferU32(&cdvd.NCMDParamBuff[0], 0), static_cast<CDVD_MODE_TYPE>(cdvdIsDVD()), false));
|
||||||
cdvdUpdateStatus(CDVD_STATUS_SEEK);
|
cdvdUpdateStatus(CDVD_STATUS_SEEK);
|
||||||
cdvd.Action = cdvdAction_Seek;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case N_CD_READ: // CdRead
|
case N_CD_READ: // CdRead
|
||||||
|
|
|
@ -326,6 +326,7 @@ enum IopEventId
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void PSX_INT( IopEventId n, s32 ecycle);
|
extern void PSX_INT( IopEventId n, s32 ecycle);
|
||||||
|
extern int psxRemainingCycles(IopEventId n);
|
||||||
|
|
||||||
extern void psxSetNextBranch( u32 startCycle, s32 delta );
|
extern void psxSetNextBranch( u32 startCycle, s32 delta );
|
||||||
extern void psxSetNextBranchDelta( s32 delta );
|
extern void psxSetNextBranchDelta( s32 delta );
|
||||||
|
|
|
@ -129,6 +129,14 @@ __fi int psxTestCycle( u32 startCycle, s32 delta )
|
||||||
return (int)(psxRegs.cycle - startCycle) >= 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 )
|
__fi void PSX_INT( IopEventId n, s32 ecycle )
|
||||||
{
|
{
|
||||||
// 19 is CDVD read int, it's supposed to be high.
|
// 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_SIF1, sif1Interrupt); // SIF1
|
||||||
IopTestEvent(IopEvt_SIF2, sif2Interrupt); // SIF2
|
IopTestEvent(IopEvt_SIF2, sif2Interrupt); // SIF2
|
||||||
Sio0TestEvent(IopEvt_SIO);
|
Sio0TestEvent(IopEvt_SIO);
|
||||||
IopTestEvent(IopEvt_CdvdRead, cdvdReadInterrupt);
|
|
||||||
IopTestEvent(IopEvt_CdvdSectorReady, cdvdSectorReady);
|
IopTestEvent(IopEvt_CdvdSectorReady, cdvdSectorReady);
|
||||||
|
IopTestEvent(IopEvt_CdvdRead, cdvdReadInterrupt);
|
||||||
|
|
||||||
// Profile-guided Optimization (sorta)
|
// Profile-guided Optimization (sorta)
|
||||||
// The following ints are rarely called. Encasing them in a conditional
|
// The following ints are rarely called. Encasing them in a conditional
|
||||||
|
|
Loading…
Reference in New Issue