Skip to content

Commit

Permalink
rings search initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
superg committed Dec 20, 2023
1 parent a20532c commit 2d55549
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 89 deletions.
137 changes: 84 additions & 53 deletions dump.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,59 @@ export bool profile_is_hddvd(GET_CONFIGURATION_FeatureCode_ProfileList profile)
}


export SPTD::Status read_sector(uint8_t *sector, SPTD &sptd, const DriveConfig &drive_config, int32_t lba)
{
auto layout = sector_order_layout(drive_config.sector_order);

// PLEXTOR: C2 is shifted 294/295 bytes late, read as much sectors as needed to get whole C2
// as a consequence, lead-out overread will fail a few sectors earlier
uint32_t sectors_count = drive_config.c2_shift / CD_C2_SIZE + (drive_config.c2_shift % CD_C2_SIZE ? 1 : 0) + 1;
std::vector<uint8_t> sector_buffer(CD_RAW_DATA_SIZE * sectors_count);

SPTD::Status status;
// D8
if(drive_config.read_method == DriveConfig::ReadMethod::D8)
{
status = cmd_read_cdda(sptd, sector_buffer.data(), lba, sectors_count,
drive_config.sector_order == DriveConfig::SectorOrder::DATA_SUB ? READ_CDDA_SubCode::DATA_SUB : READ_CDDA_SubCode::DATA_C2_SUB);
}
// BE
else
{
status = cmd_read_cd(sptd, sector_buffer.data(), lba, sectors_count,
drive_config.read_method == DriveConfig::ReadMethod::BE_CDDA ? READ_CD_ExpectedSectorType::CD_DA : READ_CD_ExpectedSectorType::ALL_TYPES,
layout.c2_offset == CD_RAW_DATA_SIZE ? READ_CD_ErrorField::NONE : READ_CD_ErrorField::C2,
layout.subcode_offset == CD_RAW_DATA_SIZE ? READ_CD_SubChannel::NONE : READ_CD_SubChannel::RAW);
}

if(!status.status_code)
{
memset(sector, 0x00, CD_RAW_DATA_SIZE);

// copy data
if(layout.data_offset != CD_RAW_DATA_SIZE)
memcpy(sector + 0, sector_buffer.data() + layout.data_offset, CD_DATA_SIZE);

// copy C2
if(layout.c2_offset != CD_RAW_DATA_SIZE)
{
// compensate C2 shift
std::vector<uint8_t> c2_buffer(CD_C2_SIZE * sectors_count);
for(uint32_t i = 0; i < sectors_count; ++i)
memcpy(c2_buffer.data() + CD_C2_SIZE * i, sector_buffer.data() + layout.size * i + layout.c2_offset, CD_C2_SIZE);

memcpy(sector + CD_DATA_SIZE, c2_buffer.data() + drive_config.c2_shift, CD_C2_SIZE);
}

// copy subcode
if(layout.subcode_offset != CD_RAW_DATA_SIZE)
memcpy(sector + CD_DATA_SIZE + CD_C2_SIZE, sector_buffer.data() + layout.subcode_offset, CD_SUBCODE_SIZE);
}

return status;
}


export std::optional<int32_t> sector_offset_by_sync(std::span<uint8_t> data, int32_t lba)
{
std::optional<int32_t> offset;
Expand Down Expand Up @@ -374,6 +427,37 @@ export std::optional<int32_t> track_offset_by_sync(int32_t lba_start, int32_t lb
}


export std::optional<int32_t> track_offset_by_sync(Context &ctx, uint32_t lba, uint32_t count)
{
std::optional<int32_t> offset;

const uint32_t sectors_to_check = 2;
std::vector<uint8_t> data(sectors_to_check * CD_DATA_SIZE);
std::vector<uint8_t> sector_buffer(CD_RAW_DATA_SIZE);

for(uint32_t i = 0; i < round_down(count, sectors_to_check); i += sectors_to_check)
{
for(uint32_t j = 0; j < sectors_to_check; ++j)
{
auto status = read_sector(sector_buffer.data(), *ctx.sptd, ctx.drive_config, lba + i + j);
if(status.status_code)
throw_line("failed to read sector");

std::copy(&sector_buffer[0], &sector_buffer[CD_DATA_SIZE], &data[j * CD_DATA_SIZE]);
}

auto o = sector_offset_by_sync(data, lba + i);
if(o)
{
offset = *o - ctx.drive_config.read_offset;
break;
}
}

return offset;
}


export std::list<std::pair<std::string, bool>> cue_get_entries(const std::filesystem::path &cue_path)
{
std::list<std::pair<std::string, bool>> entries;
Expand Down Expand Up @@ -427,59 +511,6 @@ export std::string track_extract_basename(std::string str)
}


export SPTD::Status read_sector(uint8_t *sector, SPTD &sptd, const DriveConfig &drive_config, int32_t lba)
{
auto layout = sector_order_layout(drive_config.sector_order);

// PLEXTOR: C2 is shifted 294/295 bytes late, read as much sectors as needed to get whole C2
// as a consequence, lead-out overread will fail a few sectors earlier
uint32_t sectors_count = drive_config.c2_shift / CD_C2_SIZE + (drive_config.c2_shift % CD_C2_SIZE ? 1 : 0) + 1;
std::vector<uint8_t> sector_buffer(CD_RAW_DATA_SIZE * sectors_count);

SPTD::Status status;
// D8
if(drive_config.read_method == DriveConfig::ReadMethod::D8)
{
status = cmd_read_cdda(sptd, sector_buffer.data(), lba, sectors_count,
drive_config.sector_order == DriveConfig::SectorOrder::DATA_SUB ? READ_CDDA_SubCode::DATA_SUB : READ_CDDA_SubCode::DATA_C2_SUB);
}
// BE
else
{
status = cmd_read_cd(sptd, sector_buffer.data(), lba, sectors_count,
drive_config.read_method == DriveConfig::ReadMethod::BE_CDDA ? READ_CD_ExpectedSectorType::CD_DA : READ_CD_ExpectedSectorType::ALL_TYPES,
layout.c2_offset == CD_RAW_DATA_SIZE ? READ_CD_ErrorField::NONE : READ_CD_ErrorField::C2,
layout.subcode_offset == CD_RAW_DATA_SIZE ? READ_CD_SubChannel::NONE : READ_CD_SubChannel::RAW);
}

if(!status.status_code)
{
memset(sector, 0x00, CD_RAW_DATA_SIZE);

// copy data
if(layout.data_offset != CD_RAW_DATA_SIZE)
memcpy(sector + 0, sector_buffer.data() + layout.data_offset, CD_DATA_SIZE);

// copy C2
if(layout.c2_offset != CD_RAW_DATA_SIZE)
{
// compensate C2 shift
std::vector<uint8_t> c2_buffer(CD_C2_SIZE * sectors_count);
for(uint32_t i = 0; i < sectors_count; ++i)
memcpy(c2_buffer.data() + CD_C2_SIZE * i, sector_buffer.data() + layout.size * i + layout.c2_offset, CD_C2_SIZE);

memcpy(sector + CD_DATA_SIZE, c2_buffer.data() + drive_config.c2_shift, CD_C2_SIZE);
}

// copy subcode
if(layout.subcode_offset != CD_RAW_DATA_SIZE)
memcpy(sector + CD_DATA_SIZE + CD_C2_SIZE, sector_buffer.data() + layout.subcode_offset, CD_SUBCODE_SIZE);
}

return status;
}


export void debug_print_c2_scm_offsets(const uint8_t *c2_data, uint32_t lba_index, int32_t lba_start, int32_t drive_read_offset)
{
uint32_t scm_offset = lba_index * CD_DATA_SIZE - drive_read_offset * CD_SAMPLE_SIZE;
Expand Down
45 changes: 9 additions & 36 deletions rings.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -26,37 +26,6 @@ namespace gpsxre
{


std::optional<int32_t> find_offset(Context &ctx, uint32_t lba, uint32_t count)
{
std::optional<int32_t> offset;

const uint32_t sectors_to_check = 2;
std::vector<uint8_t> data(sectors_to_check * CD_DATA_SIZE);
std::vector<uint8_t> sector_buffer(CD_RAW_DATA_SIZE);

for(uint32_t i = 0; i < round_down(count, sectors_to_check); i += sectors_to_check)
{
for(uint32_t j = 0; j < sectors_to_check; ++j)
{
auto status = read_sector(sector_buffer.data(), *ctx.sptd, ctx.drive_config, lba + i + j);
if(status.status_code)
throw_line("failed to read sector");

std::copy(&sector_buffer[0], &sector_buffer[CD_DATA_SIZE], &data[j * CD_DATA_SIZE]);
}

auto o = sector_offset_by_sync(data, lba + i);
if(o)
{
offset = *o - ctx.drive_config.read_offset;
break;
}
}

return offset;
}


export void redumper_rings(Context &ctx, Options &options)
{
if(!profile_is_cd(ctx.current_profile))
Expand All @@ -82,7 +51,7 @@ export void redumper_rings(Context &ctx, Options &options)
uint32_t sectors_count = s.tracks[i + 1].lba_start - track_start;

if(!write_offset)
write_offset = find_offset(ctx, track_start, std::min(iso9660::SYSTEM_AREA_SIZE, sectors_count));
write_offset = track_offset_by_sync(ctx, track_start, std::min(iso9660::SYSTEM_AREA_SIZE, sectors_count));

std::unique_ptr<SectorReader> sector_reader = std::make_unique<Disc_READ_Reader>(*ctx.sptd, track_start);

Expand All @@ -103,24 +72,28 @@ export void redumper_rings(Context &ctx, Options &options)
});
LOG("");

std::vector<std::pair<int32_t, int32_t>> rings;
std::vector<std::pair<int32_t, int32_t>> sector_rings;
for(uint32_t i = 0; i + 1 < area_map.size(); ++i)
{
auto &a = area_map[i];

uint32_t gap_start = a.offset + scale_up(a.size, FORM1_DATA_SIZE);
if(gap_start < area_map[i + 1].offset)
rings.emplace_back(gap_start, area_map[i + 1].offset);
sector_rings.emplace_back(gap_start, area_map[i + 1].offset);
}

if(!rings.empty())
if(!sector_rings.empty())
{
LOG("ISO9660 rings: ");
for(auto r : rings)
for(auto r : sector_rings)
LOG(" [{:6}, {:6})", r.first, r.second);
LOG("");
}

std::vector<std::pair<int32_t, int32_t>> rings;
for(auto r : sector_rings)
rings.emplace_back(lba_to_sample(r.first, *write_offset), lba_to_sample(r.second, *write_offset));

ctx.rings = rings;
}

Expand Down

0 comments on commit 2d55549

Please sign in to comment.