Detect and report slow CD reads

When not using async, first try read with a timeout.  If it fails,
display a message suggesting a different CD access method.
This commit is contained in:
Brian Koropoff 2017-10-15 14:39:47 -07:00
parent 0e6c67a736
commit 6e14459d0a
4 changed files with 40 additions and 16 deletions

View File

@ -46,6 +46,8 @@ static bool enable_analog_calibration = false;
static bool enable_variable_serialization_size = false;
unsigned cd_2x_speedup = 1;
bool cd_async = false;
bool cd_warned_slow = false;
int64 cd_slow_timeout = 8000; // microseconds
// Sets how often (in number of output frames/retro_run invocations)
// the internal framerace counter should be updated if
@ -1077,6 +1079,8 @@ static void PSX_Power(void)
PSX_PRNG.c = 6543217;
PSX_PRNG.lcgo = 0xDEADBEEFCAFEBABEULL;
cd_warned_slow = false;
memset(MainRAM.data32, 0, 2048 * 1024);
for(i = 0; i < 9; i++)

View File

@ -95,7 +95,7 @@ class CDIF_MT : public CDIF
virtual ~CDIF_MT();
virtual void HintReadSector(uint32 lba);
virtual bool ReadRawSector(uint8 *buf, uint32 lba, bool async);
virtual bool ReadRawSector(uint8 *buf, uint32 lba, int64 timeout_us);
virtual bool ReadRawSectorPWOnly(uint8 *buf, uint32 lba, bool hint_fullread);
// Return true if operation succeeded or it was a NOP(either due to not being implemented, or the current status matches eject_status).
@ -144,7 +144,7 @@ class CDIF_ST : public CDIF
virtual ~CDIF_ST();
virtual void HintReadSector(uint32 lba);
virtual bool ReadRawSector(uint8 *buf, uint32 lba, bool async);
virtual bool ReadRawSector(uint8 *buf, uint32 lba, int64 timeout_us);
virtual bool ReadRawSectorPWOnly(uint8 *buf, uint32 lba, bool hint_fullread);
virtual bool Eject(bool eject_status);
@ -438,7 +438,7 @@ bool CDIF::ValidateRawSector(uint8 *buf)
return(true);
}
bool CDIF_MT::ReadRawSector(uint8 *buf, uint32 lba, bool async)
bool CDIF_MT::ReadRawSector(uint8 *buf, uint32 lba, int64 timeout_us)
{
bool found = false;
bool error_condition = false;
@ -476,13 +476,17 @@ bool CDIF_MT::ReadRawSector(uint8 *buf, uint32 lba, bool async)
if(!found)
{
if (async)
if (timeout_us >= 0)
{
error_condition = true;
memset(buf, 0, 2352 + 96);
break;
if (!scond_wait_timeout((scond_t*)SBCond, (slock_t*)SBMutex, timeout_us))
{
error_condition = true;
memset(buf, 0, 2352 + 96);
break;
}
}
scond_wait((scond_t*)SBCond, (slock_t*)SBMutex);
else
scond_wait((scond_t*)SBCond, (slock_t*)SBMutex);
}
} while(!found);
@ -612,7 +616,7 @@ void CDIF_ST::HintReadSector(uint32 lba)
/* TODO: disc_cdaccess seek hint? (probably not, would require asynchronousitycamel) */
}
bool CDIF_ST::ReadRawSector(uint8 *buf, uint32 lba, bool async)
bool CDIF_ST::ReadRawSector(uint8 *buf, uint32 lba, int64 timeout_us)
{
if(UnrecoverableError)
{

View File

@ -38,7 +38,7 @@ class CDIF
}
virtual void HintReadSector(uint32_t lba) = 0;
virtual bool ReadRawSector(uint8_t *buf, uint32_t lba, bool async = false) = 0;
virtual bool ReadRawSector(uint8_t *buf, uint32_t lba, int64_t timeout_us = -1) = 0;
virtual bool ReadRawSectorPWOnly(uint8_t *buf, uint32_t lba, bool hint_fullread) = 0;
// Call for mode 1 or mode 2 form 1 only.

View File

@ -69,6 +69,8 @@ PS_CDC::PS_CDC() : DMABuffer(4096)
extern unsigned cd_2x_speedup;
extern bool cd_async;
extern bool cd_warned_slow;
extern int64 cd_slow_timeout;
PS_CDC::~PS_CDC()
{
@ -905,13 +907,27 @@ void PS_CDC::HandlePlayRead(void)
PSX_WARNING("[CDC] In leadout area: %u", CurSector);
}
if(!cd_async || !SeekRetryCounter)
Cur_CDIF->ReadRawSector(read_buf, CurSector, false);
else if (!Cur_CDIF->ReadRawSector(read_buf, CurSector, true))
if (cd_async && SeekRetryCounter)
{
SeekRetryCounter--;
PSRCounter = 33868800 / 75;
return;
if (!Cur_CDIF->ReadRawSector(read_buf, CurSector, 0))
{
SeekRetryCounter--;
PSRCounter = 33868800 / 75;
return;
}
}
else if (cd_warned_slow)
{
Cur_CDIF->ReadRawSector(read_buf, CurSector, -1);
}
else if (!Cur_CDIF->ReadRawSector(read_buf, CurSector, cd_slow_timeout))
{
if (cd_async)
MDFN_DispMessage("*Really* slow CD image read detected -- consider using precache CD Access Method");
else
MDFN_DispMessage("Slow CD image read detected -- consider using async or precache CD Access Method");
cd_warned_slow = true;
Cur_CDIF->ReadRawSector(read_buf, CurSector, -1);
}
DecodeSubQ(read_buf + 2352);