void CDIF_MT::RT_EjectDisc(bool eject_status, bool skip_actual_eject) { if(eject_status != DiscEjected) { if(!skip_actual_eject) disc_cdaccess->Eject(eject_status); // Set after ->Eject(), since it might throw an exception. DiscEjected = -1; // For if TOC reading fails or there's something horribly wrong with the disc. if(!eject_status) // Re-read the TOC { disc_cdaccess->Read_TOC(&disc_toc); if(disc_toc.first_track < 1 || disc_toc.last_track > 99 || disc_toc.first_track > disc_toc.last_track) { throw(MDFN_Error(0, _("TOC first(%d)/last(%d) track numbers bad."), disc_toc.first_track, disc_toc.last_track)); } } DiscEjected = eject_status; SBWritePos = 0; ra_lba = 0; ra_count = 0; last_read_lba = ~0U; memset(SectorBuffers, 0, SBSize * sizeof(CDIF_Sector_Buffer)); } }
bool CDIF_ST::Eject(bool eject_status) { if(UnrecoverableError) return(false); try { if(eject_status != DiscEjected) { disc_cdaccess->Eject(eject_status); // Set after ->Eject(), since it might throw an exception. DiscEjected = -1; // For if TOC reading fails or there's something horribly wrong with the disc. if(!eject_status) // Re-read the TOC { disc_cdaccess->Read_TOC(&disc_toc); if(disc_toc.first_track < 1 || disc_toc.last_track > 99 || disc_toc.first_track > disc_toc.last_track) { throw(MDFN_Error(0, _("TOC first(%d)/last(%d) track numbers bad."), disc_toc.first_track, disc_toc.last_track)); } } DiscEjected = eject_status; } } catch(std::exception &e) { MDFN_PrintError("%s", e.what()); return(false); } return(true); }
bool CDIF_ST::Eject(bool eject_status) { if(UnrecoverableError) return(false); try { int32_t old_de = DiscEjected; DiscEjected = eject_status; if(old_de != DiscEjected) { disc_cdaccess->Eject(eject_status); if(!eject_status) // Re-read the TOC { disc_cdaccess->Read_TOC(&disc_toc); if(disc_toc.first_track < 1 || disc_toc.last_track > 99 || disc_toc.first_track > disc_toc.last_track) throw(MDFN_Error(0, _("TOC first(%d)/last(%d) track numbers bad."), disc_toc.first_track, disc_toc.last_track)); } } } catch(std::exception &e) { log_cb(RETRO_LOG_ERROR, "%s\n", e.what()); return(false); } return(true); }
void CDIF_MT::RT_EjectDisc(bool eject_status, bool skip_actual_eject) { int32_t old_de = DiscEjected; DiscEjected = eject_status; if(old_de != DiscEjected) { if(!skip_actual_eject) disc_cdaccess->Eject(eject_status); if(!eject_status) // Re-read the TOC { disc_cdaccess->Read_TOC(&disc_toc); if(disc_toc.first_track < 1 || disc_toc.last_track > 99 || disc_toc.first_track > disc_toc.last_track) throw(MDFN_Error(0, _("TOC first(%d)/last(%d) track numbers bad."), disc_toc.first_track, disc_toc.last_track)); } SBWritePos = 0; ra_lba = 0; ra_count = 0; last_read_lba = ~0U; memset(SectorBuffers, 0, SBSize * sizeof(CDIF_Sector_Buffer)); } }
bool CDIF_ST::ReadRawSector(uint8 *buf, uint32 lba) { if(UnrecoverableError) { memset(buf, 0, 2352 + 96); return(false); } //try { if(!disc_cdaccess->Read_Raw_Sector(buf, lba)) { MDFN_PrintError(_("Sector %u read error"), lba); memset(buf, 0, 2352 + 96); return(false); } } /*catch(std::exception &e) { MDFN_PrintError(_("Sector %u read error: %s"), lba, e.what()); memset(buf, 0, 2352 + 96); return(false); }*/ static const int max_ra = 16; static const int initial_ra = 1; static const int speedmult_ra = 2; int ra_count = 0; if(last_read_lba != ~0U && lba == (last_read_lba + 1)) { int how_far_ahead = ra_lba - lba; if(how_far_ahead <= max_ra) ra_count = std::min(speedmult_ra, 1 + max_ra - how_far_ahead); else ra_count++; } else if(lba != last_read_lba) { ra_lba = lba; ra_count = initial_ra; } last_read_lba = lba; if(ra_count) { disc_cdaccess->HintReadSector(ra_lba, ra_count); ra_lba += ra_count; } return(true); }
bool CDIF_ST::ReadRawSector(uint8 *buf, uint32 lba) { if(UnrecoverableError) { memset(buf, 0, 2352 + 96); return(false); } try { disc_cdaccess->Read_Raw_Sector(buf, lba); } catch(std::exception &e) { MDFN_PrintError(_("Sector %u read error: %s"), lba, e.what()); memset(buf, 0, 2352 + 96); return(false); } return(true); }
bool CDIF_ST::ReadRawSector(uint8 *buf, uint32 lba) { if(UnrecoverableError) { memset(buf, 0, 2352 + 96); return(false); } try { disc_cdaccess->Read_Raw_Sector(buf, lba); } catch(std::exception &e) { log_cb(RETRO_LOG_ERROR, "Sector %u read error: %s\n", lba, e.what()); memset(buf, 0, 2352 + 96); return(false); } return(true); }
int CDIF_MT::ReadThreadStart() { bool Running = TRUE; DiscEjected = true; SBWritePos = 0; ra_lba = 0; ra_count = 0; last_read_lba = ~0U; try { RT_EjectDisc(false, true); } catch(std::exception &e) { EmuThreadQueue.Write(CDIF_Message(CDIF_MSG_FATAL_ERROR, std::string(e.what()))); return(0); } is_phys_cache = disc_cdaccess->Is_Physical(); EmuThreadQueue.Write(CDIF_Message(CDIF_MSG_DONE)); while(Running) { CDIF_Message msg; // Only do a blocking-wait for a message if we don't have any sectors to read-ahead. // MDFN_DispMessage("%d %d %d\n", last_read_lba, ra_lba, ra_count); if(ReadThreadQueue.Read(&msg, ra_count ? FALSE : TRUE)) { switch(msg.message) { case CDIF_MSG_DIEDIEDIE: Running = FALSE; break; case CDIF_MSG_EJECT: try { RT_EjectDisc(msg.args[0]); EmuThreadQueue.Write(CDIF_Message(CDIF_MSG_DONE)); } catch(std::exception &e) { EmuThreadQueue.Write(CDIF_Message(CDIF_MSG_FATAL_ERROR, std::string(e.what()))); } break; case CDIF_MSG_READ_SECTOR: { static const int max_ra = 16; static const int initial_ra = 1; static const int speedmult_ra = 2; uint32 new_lba = msg.args[0]; assert((unsigned int)max_ra < (SBSize / 4)); if(last_read_lba != ~0U && new_lba == (last_read_lba + 1)) { int how_far_ahead = ra_lba - new_lba; if(how_far_ahead <= max_ra) ra_count = std::min(speedmult_ra, 1 + max_ra - how_far_ahead); else ra_count++; } else if(new_lba != last_read_lba) { ra_lba = new_lba; ra_count = initial_ra; } last_read_lba = new_lba; } break; } } // Don't read >= the "end" of the disc, silly snake. Slither. if(ra_count && ra_lba == disc_toc.tracks[100].lba) { ra_count = 0; //printf("Ephemeral scarabs: %d!\n", ra_lba); } if(ra_count) { uint8 tmpbuf[2352 + 96]; bool error_condition = false; try { disc_cdaccess->Read_Raw_Sector(tmpbuf, ra_lba); } catch(std::exception &e) { MDFN_PrintError(_("Sector %u read error: %s"), ra_lba, e.what()); memset(tmpbuf, 0, sizeof(tmpbuf)); error_condition = true; } MDFND_LockMutex(SBMutex); SectorBuffers[SBWritePos].lba = ra_lba; memcpy(SectorBuffers[SBWritePos].data, tmpbuf, 2352 + 96); SectorBuffers[SBWritePos].valid = TRUE; SectorBuffers[SBWritePos].error = error_condition; SBWritePos = (SBWritePos + 1) % SBSize; MDFND_UnlockMutex(SBMutex); ra_lba++; ra_count--; } } return(1); }
void CDIF_ST::HintReadSector(uint32 lba) { // TODO: disc_cdaccess seek hint? (probably not, would require asynchronousitycamel) disc_cdaccess->HintReadSector(lba, 1); }