From 93b36fe071a685cf5c7efb95bd83af6a9d2f7938 Mon Sep 17 00:00:00 2001 From: Petteri Aimonen Date: Thu, 26 Sep 2024 12:10:39 +0300 Subject: [PATCH 1/2] ImageBackingStore: Fix wrong image size for files not multiple of 512 bytes CD images in bin/cue format can have sector size that is not divisible by 512. That's why the real file size must be reported and not rounded to sector boundary. Only use sector-aligned size for RAW mapping. --- src/ImageBackingStore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ImageBackingStore.cpp b/src/ImageBackingStore.cpp index d6b8ed79..a29cdf08 100644 --- a/src/ImageBackingStore.cpp +++ b/src/ImageBackingStore.cpp @@ -183,7 +183,7 @@ bool ImageBackingStore::close() uint64_t ImageBackingStore::size() { - if (m_iscontiguous && m_blockdev) + if (m_iscontiguous && m_blockdev && m_israw) { return (uint64_t)(m_endsector - m_bgnsector + 1) * SD_SECTOR_SIZE; } From e274c17cf69016de2fd9677d9b6b4acff00e3d6b Mon Sep 17 00:00:00 2001 From: Petteri Aimonen Date: Thu, 26 Sep 2024 12:11:46 +0300 Subject: [PATCH 2/2] CD-ROM: Support PREGAP in .cue files (#422) When CD-ROM image has PREGAP specified, that is included in TOC timestamps but not actually present in the image file. Adjust data_start and track_start accordingly. --- lib/CUEParser/src/CUEParser.cpp | 7 +++- lib/CUEParser/src/CUEParser.h | 3 +- lib/CUEParser/test/CUEParser_test.cpp | 57 ++++++++++++++++++++++++++- lib/CUEParser/test/Makefile | 2 +- src/ZuluSCSI_cdrom.cpp | 4 +- 5 files changed, 66 insertions(+), 7 deletions(-) diff --git a/lib/CUEParser/src/CUEParser.cpp b/lib/CUEParser/src/CUEParser.cpp index a22c02fd..9c689c96 100644 --- a/lib/CUEParser/src/CUEParser.cpp +++ b/lib/CUEParser/src/CUEParser.cpp @@ -90,6 +90,8 @@ const CUETrackInfo *CUEParser::next_track() } else if (strncasecmp(m_parse_pos, "PREGAP ", 7) == 0) { + // Unstored pregap, which offsets the data start on CD but does not + // affect the offset in data file. const char *time_str = skip_space(m_parse_pos + 7); m_track_info.unstored_pregap_length = parse_time(time_str); } @@ -104,11 +106,13 @@ const CUETrackInfo *CUEParser::next_track() if (index == 0) { + // Stored pregap that is present both on CD and in data file m_track_info.track_start = time; got_pause = true; } else if (index == 1) { + // Data content of the track m_track_info.data_start = time; got_data = true; } @@ -120,6 +124,7 @@ const CUETrackInfo *CUEParser::next_track() if (got_data && !got_pause) { m_track_info.track_start = m_track_info.data_start; + m_track_info.data_start += m_track_info.unstored_pregap_length; } if (got_track && got_data) @@ -279,4 +284,4 @@ uint32_t CUEParser::get_sector_length(CUEFileMode filemode, CUETrackMode trackmo { return 0; } -} \ No newline at end of file +} diff --git a/lib/CUEParser/src/CUEParser.h b/lib/CUEParser/src/CUEParser.h index 5b9f5cb1..46d96d96 100644 --- a/lib/CUEParser/src/CUEParser.h +++ b/lib/CUEParser/src/CUEParser.h @@ -53,7 +53,7 @@ struct CUETrackInfo // Source file name and file type, and offset to start of track data in bytes. char filename[CUE_MAX_FILENAME+1]; CUEFileMode file_mode; - uint64_t file_offset; // corresponds to track_start below + uint64_t file_offset; // corresponds to data_start below // Track number and mode in CD format int track_number; @@ -70,6 +70,7 @@ struct CUETrackInfo uint32_t data_start; // LBA for the beginning of the track, which will be INDEX 00 if that is present. + // If there is unstored PREGAP, it's added between track_start and data_start. // Otherwise this will be INDEX 01 matching data_start above. uint32_t track_start; }; diff --git a/lib/CUEParser/test/CUEParser_test.cpp b/lib/CUEParser/test/CUEParser_test.cpp index 7edd8bcd..5babb81d 100644 --- a/lib/CUEParser/test/CUEParser_test.cpp +++ b/lib/CUEParser/test/CUEParser_test.cpp @@ -62,7 +62,7 @@ FILE "Sound.wav" WAVE TEST(track->track_mode == CUETrack_AUDIO); TEST(track->sector_length == 2352); TEST(track->unstored_pregap_length == 2 * 75); - TEST(track->data_start == start2); + TEST(track->data_start == start2 + 2 * 75); } COMMENT("Test TRACK 03 (audio with index 0)"); @@ -177,10 +177,63 @@ TRACK 03 MODE1/2352 return status; } +bool test_datatrackpregap() +{ + bool status = true; + const char *cue_sheet = R"( +FILE "issue422.bin" BINARY + TRACK 01 AUDIO + INDEX 01 00:00:00 + TRACK 02 MODE1/2352 + PREGAP 00:02:00 + INDEX 01 01:06:19 + )"; + + CUEParser parser(cue_sheet); + + COMMENT("test_datatrackpregap()"); + COMMENT("Test TRACK 01 (audio)"); + const CUETrackInfo *track = parser.next_track(); + TEST(track != NULL); + if (track) + { + TEST(strcmp(track->filename, "issue422.bin") == 0); + TEST(track->file_mode == CUEFile_BINARY); + TEST(track->file_offset == 0); + TEST(track->track_number == 1); + TEST(track->track_mode == CUETrack_AUDIO); + TEST(track->sector_length == 2352); + TEST(track->unstored_pregap_length == 0); + TEST(track->data_start == 0); + TEST(track->track_start == 0); + } + + COMMENT("Test TRACK 02 (data)"); + track = parser.next_track(); + TEST(track != NULL); + if (track) + { + TEST(strcmp(track->filename, "issue422.bin") == 0); + TEST(track->file_mode == CUEFile_BINARY); + TEST(track->file_offset == 0xB254B0); + TEST(track->track_number == 2); + TEST(track->track_mode == CUETrack_MODE1_2352); + TEST(track->sector_length == 2352); + TEST(track->unstored_pregap_length == 75 * 2); + TEST(track->data_start == (60 + 6 + 2) * 75 + 19); + TEST(track->track_start == (60 + 6) * 75 + 19); + } + + track = parser.next_track(); + TEST(track == NULL); + + return status; +} + int main() { - if (test_basics() && test_datatracks()) + if (test_basics() && test_datatracks() && test_datatrackpregap()) { return 0; } diff --git a/lib/CUEParser/test/Makefile b/lib/CUEParser/test/Makefile index 68743a34..d79e062e 100644 --- a/lib/CUEParser/test/Makefile +++ b/lib/CUEParser/test/Makefile @@ -4,4 +4,4 @@ all: CUEParser_test ./CUEParser_test CUEParser_test: CUEParser_test.cpp ../src/CUEParser.cpp - g++ -Wall -Wextra -o $@ -I ../src $^ + g++ -Wall -Wextra -g -ggdb -o $@ -I ../src $^ diff --git a/src/ZuluSCSI_cdrom.cpp b/src/ZuluSCSI_cdrom.cpp index 8982c0ec..58750118 100644 --- a/src/ZuluSCSI_cdrom.cpp +++ b/src/ZuluSCSI_cdrom.cpp @@ -271,7 +271,7 @@ static uint32_t getLeadOutLBA(const CUETrackInfo* lasttrack) image_config_t &img = *(image_config_t*)scsiDev.target->cfg; uint32_t lastTrackBlocks = (img.file.size() - lasttrack->file_offset) / lasttrack->sector_length; - return lasttrack->track_start + lastTrackBlocks; + return lasttrack->data_start + lastTrackBlocks; } else { @@ -1500,7 +1500,7 @@ static void doReadCD(uint32_t lba, uint32_t length, uint8_t sector_type, } else { - offset = trackinfo.file_offset + trackinfo.sector_length * (lba - trackinfo.track_start); + offset = trackinfo.file_offset + trackinfo.sector_length * (lba - trackinfo.data_start); dbgmsg("------ Read CD: ", (int)length, " sectors starting at ", (int)lba, ", track number ", trackinfo.track_number, ", sector size ", (int)trackinfo.sector_length, ", main channel ", main_channel, ", sub channel ", sub_channel,