2323#include < chrono>
2424#include " crc.h"
2525
26- static void crc_append_u8 (u32 * crc, u8 value)
27- {
28- *crc = CalculateCRC32 (*crc, &value, 1 );
29- }
30-
31- static void crc_append_u32 (u32 * crc, u32 value)
32- {
33- u8 data[4 ];
34- data[0 ] = (u8 )value;
35- data[1 ] = (u8 )(value >> 8 );
36- data[2 ] = (u8 )(value >> 16 );
37- data[3 ] = (u8 )(value >> 24 );
38- *crc = CalculateCRC32 (*crc, data, sizeof (data));
39- }
40-
4126static bool raw_sector_has_mode1_sync (const u8 * raw)
4227{
4328 static const u8 sync[12 ] = { 0x00 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
@@ -286,17 +271,10 @@ bool CdRomPhysicalImage::ReadTOC()
286271 LbaToMsf (track.start_lba , &track.start_msf );
287272 LbaToMsf (track.end_lba , &track.end_msf );
288273
289- if (track.type != GG_CDROM_AUDIO_TRACK )
290- {
291- if (!DetectDataTrackType (track))
292- return false ;
293- }
294-
295274 m_toc.tracks .push_back (track);
296275 }
297276
298277 m_toc.sector_count = lead_out_lba;
299- NormalizeTrackBoundaries ();
300278
301279 LbaToMsf (m_toc.sector_count + 150 , &m_toc.total_length );
302280
@@ -314,194 +292,6 @@ bool CdRomPhysicalImage::ReadTOC()
314292 return true ;
315293}
316294
317- void CdRomPhysicalImage::NormalizeTrackBoundaries ()
318- {
319- if (m_toc.tracks .size () < 2 )
320- return ;
321-
322- for (size_t i = 0 ; (i + 1 ) < m_toc.tracks .size (); i++)
323- {
324- Track& track = m_toc.tracks [i];
325- Track& next_track = m_toc.tracks [i + 1 ];
326-
327- if (track.type == next_track.type )
328- continue ;
329-
330- if (next_track.start_lba == 0 )
331- continue ;
332-
333- static const u32 audio_pregap_lengths[] = { CDROM_PHYSICAL_STANDARD_PREGAP_SECTORS , (2 * 75 ) + 74 , 75 * 3 , 75 * 4 };
334- static const u32 data_pregap_lengths[] = { (2 * 75 ) + 74 , CDROM_PHYSICAL_STANDARD_PREGAP_SECTORS , 75 * 3 , 75 * 4 };
335-
336- const u32 * pregap_lengths = (next_track.type == GG_CDROM_AUDIO_TRACK ) ? audio_pregap_lengths : data_pregap_lengths;
337- u32 pregap_count = (u32 )((next_track.type == GG_CDROM_AUDIO_TRACK ) ?
338- (sizeof (audio_pregap_lengths) / sizeof (audio_pregap_lengths[0 ])) :
339- (sizeof (data_pregap_lengths) / sizeof (data_pregap_lengths[0 ])));
340- u32 lead_in_lba = next_track.start_lba ;
341-
342- for (u32 j = 0 ; j < pregap_count; j++)
343- {
344- u32 pregap_length = pregap_lengths[j];
345- if (next_track.start_lba <= pregap_length)
346- continue ;
347-
348- u32 pregap_lba = next_track.start_lba - pregap_length;
349- if ((pregap_lba <= track.start_lba ) || (pregap_lba > track.end_lba ))
350- continue ;
351-
352- bool pregap_read_ok = false ;
353- if (!SectorMatchesTrackType (pregap_lba, next_track.type , &pregap_read_ok))
354- {
355- if (!pregap_read_ok && ShouldLogReadDiagnostic ())
356- Debug (" Physical CD-ROM boundary probe unreadable at LBA %u before track %u" , pregap_lba, (u32 )(i + 2 ));
357- continue ;
358- }
359-
360- bool previous_read_ok = false ;
361- bool previous_matches = SectorMatchesTrackType (pregap_lba - 1 , next_track.type , &previous_read_ok);
362- if (!previous_read_ok)
363- {
364- if (ShouldLogReadDiagnostic ())
365- Debug (" Physical CD-ROM boundary edge probe unreadable at LBA %u before track %u" , pregap_lba - 1 , (u32 )(i + 2 ));
366- continue ;
367- }
368-
369- if (previous_matches)
370- continue ;
371-
372- lead_in_lba = pregap_lba;
373- break ;
374- }
375-
376- if (lead_in_lba == next_track.start_lba )
377- continue ;
378-
379- if (lead_in_lba <= track.start_lba )
380- continue ;
381-
382- if (lead_in_lba > track.end_lba )
383- continue ;
384-
385- Debug (" Physical CD-ROM detected %u-sector %s lead-in before track %u at LBA %u" ,
386- next_track.start_lba - lead_in_lba, TrackTypeName (next_track.type ), (u32 )(i + 2 ), lead_in_lba);
387-
388- track.end_lba = lead_in_lba - 1 ;
389- track.sector_count = track.end_lba - track.start_lba + 1 ;
390- LbaToMsf (track.end_lba , &track.end_msf );
391- next_track.has_lead_in = true ;
392- next_track.lead_in_lba = lead_in_lba;
393- }
394- }
395-
396- bool CdRomPhysicalImage::IsMode1DataSector (u32 lba, bool * read_ok)
397- {
398- if (IsValidPointer (read_ok))
399- *read_ok = false ;
400-
401- if (lba >= m_toc.sector_count )
402- return false ;
403-
404- u8 raw[CDROM_PHYSICAL_SECTOR_SIZE ];
405- memset (raw, 0 , sizeof (raw));
406-
407- std::lock_guard<std::mutex> lock (m_drive_mutex);
408- if (!m_drive.ReadRawSector2352 (lba, raw, false , false ))
409- return false ;
410-
411- if (IsValidPointer (read_ok))
412- *read_ok = true ;
413-
414- return raw_sector_has_mode1_sync (raw);
415- }
416-
417- bool CdRomPhysicalImage::IsReadableAudioSector (u32 lba)
418- {
419- if (lba >= m_toc.sector_count )
420- return false ;
421-
422- u8 raw[CDROM_PHYSICAL_SECTOR_SIZE ];
423- memset (raw, 0 , sizeof (raw));
424-
425- std::lock_guard<std::mutex> lock (m_drive_mutex);
426- return m_drive.ReadRawSector2352 (lba, raw, true , false );
427- }
428-
429- bool CdRomPhysicalImage::SectorMatchesTrackType (u32 lba, GG_CdRomTrackType type, bool * read_ok)
430- {
431- bool local_read_ok = false ;
432- bool mode1 = IsMode1DataSector (lba, &local_read_ok);
433-
434- if (local_read_ok)
435- {
436- if (IsValidPointer (read_ok))
437- *read_ok = true ;
438-
439- if (type == GG_CDROM_AUDIO_TRACK )
440- return !mode1;
441-
442- return mode1;
443- }
444-
445- bool audio_read_ok = IsReadableAudioSector (lba);
446- if (IsValidPointer (read_ok))
447- *read_ok = audio_read_ok;
448-
449- return audio_read_ok && (type == GG_CDROM_AUDIO_TRACK );
450- }
451-
452- bool CdRomPhysicalImage::DetectDataTrackType (Track& track)
453- {
454- u8 raw[CDROM_PHYSICAL_SECTOR_SIZE ];
455- bool read = false ;
456-
457- for (u32 attempt = 0 ; attempt < CDROM_PHYSICAL_READ_RETRIES ; attempt++)
458- {
459- memset (raw, 0 , sizeof (raw));
460-
461- {
462- std::lock_guard<std::mutex> lock (m_drive_mutex);
463- read = m_drive.ReadRawSector2352 (track.start_lba , raw, false , (attempt + 1 ) >= CDROM_PHYSICAL_READ_RETRIES );
464- }
465-
466- if (read && raw_sector_has_mode1_sync (raw))
467- {
468- if ((attempt > 0 ) && ShouldLogReadDiagnostic ())
469- Debug (" Physical CD-ROM recovered data track mode read at LBA %u after %u retry attempts" , track.start_lba , attempt);
470- break ;
471- }
472-
473- if (read)
474- {
475- if (ShouldLogReadDiagnostic ())
476- Debug (" Physical CD-ROM data track mode sync check failed at LBA %u" , track.start_lba );
477- }
478-
479- if ((attempt + 1 ) < CDROM_PHYSICAL_READ_RETRIES )
480- {
481- Debug (" Physical CD-ROM retrying data track mode detection at LBA %u (attempt %u)" , track.start_lba , attempt + 2 );
482- std::this_thread::sleep_for (std::chrono::milliseconds (CDROM_PHYSICAL_RETRY_DELAY_MS ));
483- }
484- }
485-
486- if (!read || !raw_sector_has_mode1_sync (raw))
487- {
488- Error (" Failed to read physical data track %u for mode detection" , (u32 )(m_toc.tracks .size () + 1 ));
489- return false ;
490- }
491-
492- u8 mode = raw[15 ];
493- Debug (" Physical CD-ROM data track %u mode detection at LBA %u: mode %u" , (u32 )(m_toc.tracks .size () + 1 ), track.start_lba , mode);
494- if (mode == 1 )
495- {
496- track.type = GG_CDROM_DATA_TRACK_MODE1_2352 ;
497- track.sector_size = CDROM_PHYSICAL_SECTOR_SIZE ;
498- return true ;
499- }
500-
501- Error (" Unsupported physical CD-ROM data track mode %u" , mode);
502- return false ;
503- }
504-
505295void CdRomPhysicalImage::CalculateCRC ()
506296{
507297 m_crc = 0 ;
@@ -526,11 +316,9 @@ void CdRomPhysicalImage::CalculateCRC()
526316 for (u32 i = 1 ; i <= sectors; i++)
527317 {
528318 u32 lba = track.start_lba + i;
529- if (!ReadSector (lba, buffer))
319+ if (!ReadDataSector (lba, buffer))
530320 {
531321 Error (" Physical CD-ROM CRC read failed at LBA %u" , lba);
532- m_crc = CalculateTOCFingerprint ();
533- Log (" Physical CD-ROM fallback TOC fingerprint: %08X" , m_crc);
534322 m_current_sector = current_sector;
535323 return ;
536324 }
@@ -543,35 +331,9 @@ void CdRomPhysicalImage::CalculateCRC()
543331 return ;
544332 }
545333
546- m_crc = CalculateTOCFingerprint ();
547- Log (" Physical CD-ROM CRC unavailable, fallback TOC fingerprint: %08X" , m_crc);
548334 m_current_sector = current_sector;
549335}
550336
551- u32 CdRomPhysicalImage::CalculateTOCFingerprint ()
552- {
553- static const u8 tag[] = { ' G' , ' G' , ' P' , ' H' , ' Y' , ' S' , ' T' , ' O' , ' C' };
554- u32 crc = CalculateCRC32 (0 , tag, sizeof (tag));
555-
556- crc_append_u32 (&crc, (u32 )m_toc.tracks .size ());
557- crc_append_u32 (&crc, m_toc.sector_count );
558-
559- for (size_t i = 0 ; i < m_toc.tracks .size (); i++)
560- {
561- Track& track = m_toc.tracks [i];
562- crc_append_u8 (&crc, (u8 )track.type );
563- crc_append_u32 (&crc, track.sector_size );
564- crc_append_u32 (&crc, track.sector_count );
565- crc_append_u32 (&crc, track.start_lba );
566- crc_append_u32 (&crc, track.end_lba );
567- }
568-
569- if (crc == 0 )
570- crc = 0xFFFFFFFF ;
571-
572- return crc;
573- }
574-
575337bool CdRomPhysicalImage::ReadDataSector (u32 lba, u8 * buffer)
576338{
577339 if ((lba >= m_toc.sector_count ) || !IsValidPointer (buffer))
0 commit comments