Skip to content

Commit

Permalink
TOC choice common code, disc reader offset, iso9660: removed ;, end m…
Browse files Browse the repository at this point in the history
…arker, skeleton corrections
  • Loading branch information
superg committed Dec 11, 2023
1 parent 5e2549f commit 85e8162
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 71 deletions.
18 changes: 1 addition & 17 deletions cd/cd_dump.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -410,25 +410,9 @@ export bool redumper_dump_cd(Context &ctx, const Options &options, bool refine)
int32_t lba_start = ctx.drive_config.pregap_start;
int32_t lba_end = MSF_to_LBA(MSF{74, 0, 0}); // default: 74min / 650Mb

// TOC
std::vector<uint8_t> toc_buffer = cmd_read_toc(*ctx.sptd);
TOC toc(toc_buffer, false);

// FULL TOC
std::vector<uint8_t> full_toc_buffer = cmd_read_full_toc(*ctx.sptd);
if(!full_toc_buffer.empty())
{
TOC toc_full(full_toc_buffer, true);

// [PSX] Motocross Mania
// [ENHANCED-CD] Vanishing Point
// PX-W5224TA: incorrect FULL TOC data in some cases
toc_full.deriveINDEX(toc);

// prefer TOC for single session discs and FULL TOC for multisession discs
if(toc_full.sessions.size() > 1)
toc = toc_full;
}
auto toc = choose_toc(toc_buffer, full_toc_buffer);

if(!refine)
{
Expand Down
18 changes: 4 additions & 14 deletions cd/split.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -882,23 +882,13 @@ export void redumper_split(Context &ctx, Options &options)
if(!state_fs.is_open())
throw_line("unable to open file ({})", state_path.filename().string());

// TOC
std::vector<uint8_t> toc_buffer = read_vector(toc_path);
TOC toc(toc_buffer, false);

// FULL TOC
std::vector<uint8_t> full_toc_buffer;
if(std::filesystem::exists(fulltoc_path))
{
std::vector<uint8_t> full_toc_buffer = read_vector(fulltoc_path);
TOC toc_full(full_toc_buffer, true);

// PX-W5224TA: incorrect FULL TOC data in some cases
toc_full.deriveINDEX(toc);

if(toc_full.sessions.size() > 1)
toc = toc_full;
}
full_toc_buffer = read_vector(fulltoc_path);

auto toc = choose_toc(toc_buffer, full_toc_buffer);

// preload subchannel Q
std::vector<ChannelQ> subq;
if(std::filesystem::exists(sub_path))
Expand Down
22 changes: 22 additions & 0 deletions dump.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,28 @@ export uint32_t sample_offset_r2a(int32_t relative)
}


export TOC choose_toc(const std::vector<uint8_t> &toc_buffer, const std::vector<uint8_t> &full_toc_buffer)
{
TOC toc(toc_buffer, false);

if(!full_toc_buffer.empty())
{
TOC toc_full(full_toc_buffer, true);

// [PSX] Motocross Mania
// [ENHANCED-CD] Vanishing Point
// PX-W5224TA: incorrect FULL TOC data in some cases
toc_full.deriveINDEX(toc);

// prefer TOC for single session discs and FULL TOC for multisession discs
if(toc_full.sessions.size() > 1)
toc = toc_full;
}

return toc;
}


export std::vector<ChannelQ> load_subq(const std::filesystem::path &sub_path)
{
std::vector<ChannelQ> subq(std::filesystem::file_size(sub_path) / CD_SUBCODE_SIZE);
Expand Down
2 changes: 1 addition & 1 deletion dvd/dvd_key.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export void dvd_key(Context &ctx, const Options &options)

if(cpst == READ_DVD_STRUCTURE_CopyrightInformation_CPST::CSS_CPPM)
{
Disc_READ_Reader reader(*ctx.sptd);
Disc_READ_Reader reader(*ctx.sptd, 0);
auto vobs = extract_vob_list(&reader);

bool cppm = false;
Expand Down
11 changes: 11 additions & 0 deletions filesystem/iso9660/iso9660_defs.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import cd.cdrom;
import readers.sector_reader;
import utils.endian;
import utils.misc;
import utils.strings;



Expand Down Expand Up @@ -294,4 +295,14 @@ uint32_t directory_extent_get_length(SectorReader *sector_reader, uint32_t offse
return 0;
}


std::string split_identifier(uint32_t &version, std::string identifier)
{
auto s = identifier.find((char)iso9660::Characters::SEPARATOR2);

version = (s == std::string::npos ? 0 : str_to_int(identifier.substr(s + 1)));

return identifier.substr(0, s);
}

}
14 changes: 2 additions & 12 deletions filesystem/iso9660/iso9660_entry.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public:
continue;

uint32_t version;
std::string name = splitIdentifier(version, dr.first);
std::string name = split_identifier(version, dr.first);

entries.push_back(std::make_shared<Entry>(_sectorReader, name, version, dr.second));
}
Expand All @@ -111,7 +111,7 @@ public:
for(auto const &c : components)
{
uint32_t version;
std::string name = str_uppercase(splitIdentifier(version, c));
std::string name = str_uppercase(split_identifier(version, c));

bool found = false;

Expand Down Expand Up @@ -163,16 +163,6 @@ private:
std::string _name;
uint32_t _version;
iso9660::DirectoryRecord _directoryRecord;


std::string splitIdentifier(uint32_t &version, std::string identifier)
{
auto s = identifier.find((char)iso9660::Characters::SEPARATOR2);

version = (s == std::string::npos ? 0 : str_to_int(identifier.substr(s + 1)));

return identifier.substr(0, s);
}
};

}
69 changes: 47 additions & 22 deletions filesystem/iso9660/iso9660_map.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ struct Area
PATH_TABLE_M,
PATH_TABLE_M_OPT,
DIRECTORY_EXTENT,
FILE_EXTENT
FILE_EXTENT,
END_MARKER
};

uint32_t offset;
Expand All @@ -48,11 +49,12 @@ std::map<Area::Type, std::string> AREA_TYPE_STRING =
{Area::Type::PATH_TABLE_M, "PATH_TABLE_M"},
{Area::Type::PATH_TABLE_M_OPT, "PATH_TABLE_M_OPT"},
{Area::Type::DIRECTORY_EXTENT, "DIRECTORY_EXTENT"},
{Area::Type::FILE_EXTENT, "FILE_EXTENT"}
{Area::Type::FILE_EXTENT, "FILE_EXTENT"},
{Area::Type::END_MARKER, "END_MARKER"}
};


std::vector<Area> area_map(SectorReader *sector_reader)
std::vector<Area> area_map(SectorReader *sector_reader, uint32_t base_offset, uint32_t sectors_count)
{
std::vector<Area> area_vector;

Expand Down Expand Up @@ -84,31 +86,44 @@ std::vector<Area> area_map(SectorReader *sector_reader)
if(!pvd_found)
return area_vector;

if(pvd.logical_block_size.lsb != sector_reader->sectorSize())
uint32_t sector_size = sector_reader->sectorSize();
if(pvd.logical_block_size.lsb != sector_size)
throw_line("unsupported logical block size (block size: {})", pvd.logical_block_size.lsb);

std::map<uint32_t, Area> area_map;
uint32_t o;

// system area
area_map.emplace(0, Area{ 0, Area::Type::SYSTEM_AREA, SYSTEM_AREA_SIZE * sector_reader->sectorSize(), "" });
o = base_offset + 0;
area_map.emplace(o, Area{ o, Area::Type::SYSTEM_AREA, SYSTEM_AREA_SIZE * sector_size, "" });

// descriptors
area_map.emplace(SYSTEM_AREA_SIZE, Area{ SYSTEM_AREA_SIZE, Area::Type::DESCRIPTORS, descriptors_count * sector_reader->sectorSize(), "" });
o = base_offset + SYSTEM_AREA_SIZE;
area_map.emplace(o, Area{ o, Area::Type::DESCRIPTORS, descriptors_count * sector_size, "" });

// L-type path tables
auto path_table_size = scale_up(pvd.path_table_size.lsb, sector_reader->sectorSize());
area_map.emplace(pvd.path_table_l_offset, Area{ pvd.path_table_l_offset, Area::Type::PATH_TABLE_L, pvd.path_table_size.lsb, "" });
area_map.emplace(pvd.path_table_l_offset_opt, Area{ pvd.path_table_l_offset_opt, Area::Type::PATH_TABLE_L_OPT, pvd.path_table_size.lsb, "" });
uint32_t path_table_offset = pvd.path_table_l_offset - sector_reader->sectorsBase();
o = base_offset + path_table_offset;
area_map.emplace(o, Area{ o, Area::Type::PATH_TABLE_L, pvd.path_table_size.lsb, "" });
if(pvd.path_table_l_offset_opt)
{
o = base_offset + pvd.path_table_l_offset_opt - sector_reader->sectorsBase();
area_map.emplace(o, Area{ o, Area::Type::PATH_TABLE_L_OPT, pvd.path_table_size.lsb, "" });
}

// M-type path tables
auto path_table_m_offset = endian_swap(pvd.path_table_m_offset);
auto path_table_m_offset_opt = endian_swap(pvd.path_table_m_offset_opt);
area_map.emplace(path_table_m_offset, Area{ path_table_m_offset, Area::Type::PATH_TABLE_M, pvd.path_table_size.lsb, "" });
area_map.emplace(path_table_m_offset_opt, Area{ path_table_m_offset_opt, Area::Type::PATH_TABLE_M_OPT, pvd.path_table_size.lsb, "" });
o = base_offset + endian_swap(pvd.path_table_m_offset) - sector_reader->sectorsBase();
area_map.emplace(o, Area{ o, Area::Type::PATH_TABLE_M, pvd.path_table_size.lsb, "" });
if(pvd.path_table_m_offset_opt)
{
o = base_offset + endian_swap(pvd.path_table_m_offset_opt) - sector_reader->sectorsBase();
area_map.emplace(o, Area{ o, Area::Type::PATH_TABLE_M_OPT, pvd.path_table_size.lsb, "" });
}

// directories & files (path table)
std::vector<uint8_t> path_table(sector_reader->sectorSize() * path_table_size);
if(sector_reader->read(path_table.data(), pvd.path_table_l_offset, path_table_size) == path_table_size)
auto path_table_size = scale_up(pvd.path_table_size.lsb, sector_size);
std::vector<uint8_t> path_table(sector_size * path_table_size);
if(sector_reader->read(path_table.data(), path_table_offset, path_table_size) == path_table_size)
{
path_table.resize(pvd.path_table_size.lsb);

Expand All @@ -126,12 +141,14 @@ std::vector<Area> area_map(SectorReader *sector_reader)

i += round_up(pr.length, (uint8_t)2) + pr.xa_length;

auto dr_extent_length = directory_extent_get_length(sector_reader, pr.offset);
area_map.emplace(pr.offset, Area{ pr.offset, Area::Type::DIRECTORY_EXTENT, dr_extent_length, name });
auto pr_offset = pr.offset - sector_reader->sectorsBase();
auto dr_extent_length = directory_extent_get_length(sector_reader, pr_offset);
o = base_offset + pr_offset;
area_map.emplace(o, Area{ o, Area::Type::DIRECTORY_EXTENT, dr_extent_length, name });

auto dr_sectors_count = scale_up(dr_extent_length, sector_reader->sectorSize());
std::vector<uint8_t> directory_extent(dr_sectors_count * sector_reader->sectorSize());
if(sector_reader->read(directory_extent.data(), pr.offset, dr_sectors_count) == dr_sectors_count)
auto dr_sectors_count = scale_up(dr_extent_length, sector_size);
std::vector<uint8_t> directory_extent(dr_sectors_count * sector_size);
if(sector_reader->read(directory_extent.data(), pr_offset, dr_sectors_count) == dr_sectors_count)
{
auto directory_records = directory_extent_get_records(directory_extent);
for(auto const &dr : directory_records)
Expand All @@ -144,8 +161,11 @@ std::vector<Area> area_map(SectorReader *sector_reader)
if(dr.second.file_flags & (uint8_t)iso9660::DirectoryRecord::FileFlags::DIRECTORY)
continue;

uint32_t offset = dr.second.offset.lsb - sector_reader->sectorsBase();
area_map.emplace(offset, Area{ offset, Area::Type::FILE_EXTENT, dr.second.data_length.lsb, (name == "/" ? "" : name) + "/" + dr.first });
uint32_t dr_version;
std::string dr_name = split_identifier(dr_version, dr.first);

o = base_offset + dr.second.offset.lsb - sector_reader->sectorsBase();
area_map.emplace(o, Area{ o, Area::Type::FILE_EXTENT, dr.second.data_length.lsb, (name == "/" ? "" : name) + "/" + dr_name });
}
}
}
Expand All @@ -155,6 +175,11 @@ std::vector<Area> area_map(SectorReader *sector_reader)
//TODO: needed to overcome 16-bit path table parent limit
;

// filesystem end marker
// for multisession discs sometimes it's an absolute sector value
o = base_offset + pvd.volume_space_size.lsb - (pvd.volume_space_size.lsb > sectors_count ? sector_reader->sectorsBase() : 0);
area_map.emplace(o, Area{ o, Area::Type::END_MARKER, 0, "" });

area_vector.reserve(area_map.size());
for(auto const &a : area_map)
area_vector.push_back(a.second);
Expand Down
12 changes: 10 additions & 2 deletions readers/disc_read_form1_reader.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ namespace gpsxre
export class Disc_READ_Reader : public SectorReader
{
public:
Disc_READ_Reader(SPTD &sptd)
Disc_READ_Reader(SPTD &sptd, uint32_t base_lba)
: _sptd(sptd)
, _baseLBA(base_lba)
{
;
}
Expand All @@ -30,7 +31,7 @@ public:

if(!form2)
{
auto status = cmd_read(_sptd, sectors, FORM1_DATA_SIZE, index, count, false);
auto status = cmd_read(_sptd, sectors, FORM1_DATA_SIZE, _baseLBA + index, count, false);
if(!status.status_code)
sectors_read = count;
}
Expand All @@ -47,8 +48,15 @@ public:
return FORM1_DATA_SIZE;
}


uint32_t sectorsBase() override
{
return _baseLBA;
}

private:
SPTD &_sptd;
uint32_t _baseLBA;
};

}
2 changes: 2 additions & 0 deletions redumper.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import dvd.key;
import hash;
import info;
import options;
import rings;
import scsi.cmd;
import scsi.mmc;
import scsi.sptd;
Expand Down Expand Up @@ -121,6 +122,7 @@ void redumper_dvdkey(Context &ctx, Options &options)
const std::map<std::string, std::pair<bool, void (*)(Context &, Options &)>> COMMAND_HANDLERS
{
//COMMAND DRIVE HANDLER
{ "rings" , { true , redumper_rings }},
{ "dump" , { true , redumper_dump }},
{ "refine" , { true , redumper_refine }},
{ "verify" , { true , redumper_verify }},
Expand Down
49 changes: 47 additions & 2 deletions rings.ixx
Original file line number Diff line number Diff line change
@@ -1,19 +1,64 @@
module;
#include <algorithm>
#include <memory>
#include <vector>
#include "throw_line.hh"

export module rings;

import cd.cdrom;
import dump;
import filesystem.iso9660;
import options;
import readers.disc_read_form1_reader;
import readers.sector_reader;
import scsi.cmd;
import utils.logger;
import utils.misc;



namespace gpsxre
{

export void redumper_rings(Context &ctx, const Options &options)
export void redumper_rings(Context &ctx, Options &options)
{
;
std::vector<uint8_t> toc_buffer = cmd_read_toc(*ctx.sptd);
std::vector<uint8_t> full_toc_buffer = cmd_read_full_toc(*ctx.sptd);
auto toc = choose_toc(toc_buffer, full_toc_buffer);

// uint32_t sectors_count = std::filesystem::file_size(image_path) / (iso ? FORM1_DATA_SIZE : CD_DATA_SIZE);

std::vector<iso9660::Area> area_map;

for(auto &s : toc.sessions)
{
for(uint32_t i = 0; i + 1 < s.tracks.size(); ++i)
{
auto &t = s.tracks[i];

if(!(t.control & (uint8_t)ChannelQ::Control::DATA) || t.track_number == bcd_decode(CD_LEADOUT_TRACK_NUMBER) || t.indices.empty())
continue;

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

auto am = iso9660::area_map(sector_reader.get(), t.indices.front(), s.tracks[i + 1].lba_start - t.indices.front());
area_map.insert(area_map.end(), am.begin(), am.end());
}
}

if(area_map.empty())
return;

std::for_each(area_map.cbegin(), area_map.cend(), [](const iso9660::Area &area)
{
auto sectors_count = scale_up(area.size, FORM1_DATA_SIZE);
LOG("LBA: [{:6} .. {:6}], count: {:6}, type: {}{}",
area.offset, area.offset + sectors_count - 1, sectors_count, enum_to_string(area.type, iso9660::AREA_TYPE_STRING),
area.name.empty() ? "" : std::format(", name: {}", area.name));
});

LOG("");
}

}
Loading

0 comments on commit 85e8162

Please sign in to comment.