void CDIF_MT::HintReadSector(uint32 lba) { if(UnrecoverableError) return; ReadThreadQueue.Write(CDIF_Message(CDIF_MSG_READ_SECTOR, lba)); }
bool CDIF_MT::ReadRawSectorPWOnly(uint8* pwbuf, int32 lba, bool hint_fullread) { if(UnrecoverableError) { memset(pwbuf, 0, 96); return(false); } if(lba < LBA_Read_Minimum || lba > LBA_Read_Maximum) { MDFN_printf("Attempt to read sector out of bounds; LBA=%d\n", lba); memset(pwbuf, 0, 96); return(false); } if(disc_cdaccess->Fast_Read_Raw_PW_TSRE(pwbuf, lba)) { if(hint_fullread) ReadThreadQueue.Write(CDIF_Message(CDIF_MSG_READ_SECTOR, lba)); return(true); } else { uint8 tmpbuf[2352 + 96]; bool ret; ret = ReadRawSector(tmpbuf, lba); memcpy(pwbuf, tmpbuf + 2352, 96); return ret; } }
bool CDIF_MT::Eject(bool eject_status) { if(UnrecoverableError) return(false); CDIF_Message msg; ReadThreadQueue.Write(CDIF_Message(CDIF_MSG_EJECT, eject_status)); EmuThreadQueue.Read(&msg); if(msg.message == CDIF_MSG_FATAL_ERROR) { MDFN_PrintError(_("Error on eject/insert attempt: %s"), msg.str_message.c_str()); return(false); } return(true); }
bool CDIF_MT::Eject(bool eject_status) { if(UnrecoverableError) return(false); try { CDIF_Message msg; ReadThreadQueue.Write(CDIF_Message(CDIF_MSG_EJECT, eject_status)); EmuThreadQueue.Read(&msg); } catch(std::exception &e) { MDFN_PrintError(_("Error on eject/insert attempt: %s"), e.what()); return(false); } return(true); }
bool CDIF_MT::ReadRawSector(uint8 *buf, int32 lba) { bool found = false; bool error_condition = false; if(UnrecoverableError) { memset(buf, 0, 2352 + 96); return(false); } if(lba < LBA_Read_Minimum || lba > LBA_Read_Maximum) { MDFN_printf("Attempt to read sector out of bounds; LBA=%d\n", lba); memset(buf, 0, 2352 + 96); return(false); } //fprintf(stderr, "%d\n", ra_lba - lba); ReadThreadQueue.Write(CDIF_Message(CDIF_MSG_READ_SECTOR, lba)); // // // MDFND_LockMutex(SBMutex); do { for(int i = 0; i < SBSize; i++) { if(SectorBuffers[i].valid && SectorBuffers[i].lba == lba) { error_condition = SectorBuffers[i].error; memcpy(buf, SectorBuffers[i].data, 2352 + 96); found = true; } } if(!found) { //int32 swt = MDFND_GetTime(); MDFND_WaitCond(SBCond, SBMutex); //printf("SB Waited: %d\n", MDFND_GetTime() - swt); } } while(!found); MDFND_UnlockMutex(SBMutex); // // // return(!error_condition); }
bool CDIF_MT::Eject(bool eject_status) { if(UnrecoverableError) return(false); try { CDIF_Message msg; ReadThreadQueue.Write(CDIF_Message(CDIF_MSG_EJECT, eject_status)); EmuThreadQueue.Read(&msg); } catch(std::exception &e) { log_cb(RETRO_LOG_ERROR, "Error on eject/insert attempt: %s\n", e.what()); return(false); } return(true); }
bool CDIF_MT::ReadRawSector(uint8 *buf, uint32 lba) { bool found = FALSE; bool error_condition = false; if(UnrecoverableError) { memset(buf, 0, 2352 + 96); return(false); } // This shouldn't happen, the emulated-system-specific CDROM emulation code should make sure the emulated program doesn't try // to read past the last "real" sector of the disc. if(lba >= disc_toc.tracks[100].lba) { printf("Attempt to read LBA %d, >= LBA %d\n", lba, disc_toc.tracks[100].lba); return(FALSE); } ReadThreadQueue.Write(CDIF_Message(CDIF_MSG_READ_SECTOR, lba)); // // // MDFND_LockMutex(SBMutex); do { for(int i = 0; i < SBSize; i++) { if(SectorBuffers[i].valid && SectorBuffers[i].lba == lba) { error_condition = SectorBuffers[i].error; memcpy(buf, SectorBuffers[i].data, 2352 + 96); found = TRUE; } } if(!found) { //int32 swt = MDFND_GetTime(); MDFND_WaitCond(SBCond, SBMutex); //printf("SB Waited: %d\n", MDFND_GetTime() - swt); } } while(!found); MDFND_UnlockMutex(SBMutex); // // // return(!error_condition); }
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); }
int CDIF_MT::ReadThreadStart() { bool Running = true; SBWritePos = 0; ra_lba = 0; ra_count = 0; last_read_lba = LBA_Read_Maximum + 1; try { 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 = LBA_Read_Maximum + 1; std::fill(SectorBuffers, SectorBuffers + SBSize, CDIF_Sector_Buffer()); } catch(std::exception &e) { EmuThreadQueue.Write(CDIF_Message(CDIF_MSG_FATAL_ERROR, std::string(e.what()))); return(0); } 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_READ_SECTOR: { static const int max_ra = 16; static const int initial_ra = 1; static const int speedmult_ra = 2; int32 new_lba = msg.args[0]; assert((unsigned int)max_ra < (SBSize / 4)); if(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 beyond what the disc (image) readers can handle sanely. // if(ra_count && ra_lba == LBA_Read_Maximum) { ra_count = 0; //printf("Ephemeral scarabs: %d!\n", ra_lba); } if(ra_count) { uint8 tmpbuf[2352 + 96]; bool error_condition = false; //try { if(disc_cdaccess->Read_Raw_Sector(tmpbuf, ra_lba) == -1) { MDFN_Notify(MDFN_NOTICE_ERROR, _("Sector %u read error"), ra_lba); memset(tmpbuf, 0, sizeof(tmpbuf)); error_condition = true; } } /*catch(std::exception &e) { MDFN_Notify(MDFN_NOTICE_ERROR, _("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_SignalCond(SBCond); MDFND_UnlockMutex(SBMutex); // // ra_lba++; ra_count--; } } return(1); }