Skip to content

Commit 439e0e4

Browse files
committed
Improve physical disc track boundary handling
1 parent 221ac8d commit 439e0e4

2 files changed

Lines changed: 71 additions & 0 deletions

File tree

src/cdrom_physical_image.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,20 @@ static void crc_append_u32(u32* crc, u32 value)
4040
*crc = CalculateCRC32(*crc, data, sizeof(data));
4141
}
4242

43+
static bool raw_sector_has_mode1_sync(const u8* raw)
44+
{
45+
static const u8 sync[12] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
46+
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
47+
48+
for (int i = 0; i < 12; i++)
49+
{
50+
if (raw[i] != sync[i])
51+
return false;
52+
}
53+
54+
return raw[15] == 1;
55+
}
56+
4357
CdRomPhysicalImage::CdRomPhysicalImage()
4458
{
4559
m_worker_running.store(false);
@@ -253,6 +267,8 @@ bool CdRomPhysicalImage::ReadTOC()
253267
}
254268

255269
m_toc.sector_count = lead_out_lba;
270+
NormalizeTrackBoundaries();
271+
256272
LbaToMsf(m_toc.sector_count + 150, &m_toc.total_length);
257273

258274
for (size_t i = 0; i < m_toc.tracks.size(); i++)
@@ -269,6 +285,58 @@ bool CdRomPhysicalImage::ReadTOC()
269285
return true;
270286
}
271287

288+
void CdRomPhysicalImage::NormalizeTrackBoundaries()
289+
{
290+
if (m_toc.tracks.size() < 2)
291+
return;
292+
293+
for (size_t i = 0; (i + 1) < m_toc.tracks.size(); i++)
294+
{
295+
Track& track = m_toc.tracks[i];
296+
Track& next_track = m_toc.tracks[i + 1];
297+
298+
if ((track.type == GG_CDROM_AUDIO_TRACK) || (next_track.type != GG_CDROM_AUDIO_TRACK))
299+
continue;
300+
301+
if (next_track.start_lba < CDROM_PHYSICAL_STANDARD_PREGAP_SECTORS)
302+
continue;
303+
304+
u32 pregap_lba = next_track.start_lba - CDROM_PHYSICAL_STANDARD_PREGAP_SECTORS;
305+
if ((pregap_lba <= track.start_lba) || (pregap_lba > track.end_lba))
306+
continue;
307+
308+
if (IsMode1DataSector(pregap_lba))
309+
continue;
310+
311+
if (!IsMode1DataSector(pregap_lba - 1))
312+
continue;
313+
314+
Debug("Physical CD-ROM trimming %u-sector pregap before audio track %u at LBA %u",
315+
(u32)CDROM_PHYSICAL_STANDARD_PREGAP_SECTORS, (u32)(i + 2), pregap_lba);
316+
317+
track.end_lba = pregap_lba - 1;
318+
track.sector_count = track.end_lba - track.start_lba + 1;
319+
LbaToMsf(track.end_lba, &track.end_msf);
320+
next_track.has_lead_in = true;
321+
next_track.lead_in_lba = pregap_lba;
322+
}
323+
}
324+
325+
bool CdRomPhysicalImage::IsMode1DataSector(u32 lba)
326+
{
327+
if (lba >= m_toc.sector_count)
328+
return false;
329+
330+
u8 raw[CDROM_PHYSICAL_SECTOR_SIZE];
331+
memset(raw, 0, sizeof(raw));
332+
333+
std::lock_guard<std::mutex> lock(m_drive_mutex);
334+
if (!m_drive.ReadRawSector2352(lba, raw, false))
335+
return false;
336+
337+
return raw_sector_has_mode1_sync(raw);
338+
}
339+
272340
bool CdRomPhysicalImage::DetectDataTrackType(Track& track)
273341
{
274342
u8 raw[CDROM_PHYSICAL_SECTOR_SIZE];

src/cdrom_physical_image.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#define CDROM_PHYSICAL_CACHE_BLOCKS (1 << CDROM_PHYSICAL_CACHE_BITS)
3838
#define CDROM_PHYSICAL_REQUEST_QUEUE_SIZE 64
3939
#define CDROM_PHYSICAL_PREFETCH_BLOCKS 16
40+
#define CDROM_PHYSICAL_STANDARD_PREGAP_SECTORS 150
4041

4142
class CdRomPhysicalImage : public CdRomImage
4243
{
@@ -64,6 +65,8 @@ class CdRomPhysicalImage : public CdRomImage
6465
private:
6566
bool ReadTOC();
6667
bool DetectDataTrackType(Track& track);
68+
void NormalizeTrackBoundaries();
69+
bool IsMode1DataSector(u32 lba);
6770
void CalculateCRC();
6871
u32 CalculateTOCFingerprint();
6972
bool ReadCachedRange(u32 lba, u32 offset, u8* buffer, u32 size);

0 commit comments

Comments
 (0)