示例#1
0
void CDIF_MT::HintReadSector(uint32 lba)
{
 if(UnrecoverableError)
  return;

 ReadThreadQueue.Write(CDIF_Message(CDIF_MSG_READ_SECTOR, lba));
}
示例#2
0
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;
 }
}
示例#3
0
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);
}
示例#4
0
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);
}
示例#5
0
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);
}
示例#7
0
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);
}
示例#8
0
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);
}
示例#9
0
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);
}