At a glance

Magic
none - a 12-byte sync pattern opens every sector; files are found through ISO9660
Where on disc
the whole .bin image; the Primary Volume Descriptor sits at LBA 16
Stride
2352 bytes per sector, 2048 of them file content at byte 24
Parser
crates/iso (raw.rs sector reader, iso9660.rs walker, write.rs EDC/ECC re-encode, relayout.rs)
Confidence
Confirmed - textbook CD-ROM XA / ECMA-130 geometry; every disc read in the workspace goes through it
Used by
extraction pipeline, disc patcher, in-browser ROM patcher

Overview

A CD image (.bin) is a flat run of sectors addressed by LBA - the logical block address, a sector number counting from the start of the disc. "Mode2/2352" names the sector flavour PlayStation discs use: mode 2 of the CD-ROM XA standard, stored as full 2352-byte raw sectors rather than pre-stripped 2048-byte ones. Reading a file means knowing its start LBA and peeling the 2048 user-data bytes out of each sector.

From raw sector to named file: a 2352-byte sector yields 2048 bytes of user data, ISO9660 turns runs of user data into 45 named files, and PROT.DAT is the one that holds the game's assets Raw sector 2352 bytes, by LBA User data 2048 bytes at +24 ISO9660 descriptor at LBA 16 45 files found by name files on the disc (plus SYSTEM.CNF) SCUS_942.54 executable PROT.DAT asset archive CDNAME.TXT entry names DMY.DAT dev fixtures MOV/MV*.STR 6 movies XA/XA*.XA 34 streams 1233 numbered entries: textures, models, scripts, sound banks, code
The three layers every tool in the workspace peels in order. Sector numbers (LBAs) only matter up to the ISO9660 step; past it everything is a named file, and almost everything interesting is inside PROT.DAT.

Two things live on top of that geometry:

  • ISO9660 - the standard CD filesystem that turns sector numbers into the 45 named files on the disc.
  • Relayout - growing a file by whole sectors, which the official PAL discs did to fit longer translated dialogue and which a community language pack needs when its text does not fit in place.

Sector layout

Each sector is 2352 bytes. Only the 2048-byte slice in the middle is file content; the rest is the sync mark and address the drive uses to find the sector, a subheader (meaningful for streamed XA audio and video), and the error-detection and error-correction codes that let a scratched disc still read.

Widths not to scale - the user-data slice is 87% of the sector. RawDisc::read_sector(lba) returns only that slice.

BytesSizeFieldMeaning
0..1212syncSync pattern 00 FF FF FF FF FF FF FF FF FF FF 00
12..164headerM:S:F address (BCD minutes:seconds:frames, lba + 150) + mode byte
16..248subheaderfile / channel / submode / coding (the XA streaming fields)
24..20722048user datathe file content ISO9660 and every game format see
2072..2352280EDC + ECCerror detection + correction (Form 1 only; Form 2 XA audio sectors carry no ECC)

read_user_data(lba, count, buf) reads a contiguous run of sectors the same way.

const SECTOR_SIZE: usize = 2352;
const USER_DATA_OFFSET: usize = 24;
const USER_DATA_SIZE: usize = 2048;

ISO9660 walk

On top of the sector layer sits ISO9660, the standard CD filesystem - it turns "sector 16" into named files and directories. The layout is textbook:

  • Primary Volume Descriptor at LBA 16.
  • Root directory record at PVD offset 156.
  • Each directory record begins with a length byte; records pad to even lengths.

The walker (crates/iso/src/iso9660.rs) is iterative and yields stable-sorted file paths. The Legend of Legaia (USA) disc produces 45 files: five at the root (CDNAME.TXT, DMY.DAT, PROT.DAT, SCUS_942.54, SYSTEM.CNF), six movies MOV/MV1..MV6.STR and 34 audio streams XA/XA1..XA34.XA.

FileWhat it isPage
PROT.DATthe main asset archive - nearly every texture, model, script, sound bank and code overlay is one of its 1233 numbered entriesPROT.DAT TOC
SCUS_942.54the game's main executable (the resident half of the engine; the rest lives in overlays inside PROT.DAT)Ghidra tooling
CDNAME.TXTa developer-left name map for the archive's entriesCDNAME map
DMY.DATa sibling archive of developer test fixtures, no game contentDMY.DAT
MOV/MV*.STRthe pre-rendered movies - PSX MDEC video in the Iki bitstream, not the common STRv2 layout; decoder crates/mdecFMV table, cutscenes
XA/XA*.XAstreamed voice and audio in standard CD-XA Mode 2 Form 2; crates/xa demuxes per (file_no, ch_no) straight off the raw sectorsXA audio

Full-ISO relayout

Growing a file by whole sectors - PROT.DAT, which the official PAL discs grew at mastering to fit longer localized dialogue - moves every file after it, so every on-disc reference to those files has to be rewritten. Legaia's disc makes this a small, well-bounded edit. Implementation: legaia_iso::relayout (generic ISO9660 + ECMA-130; embeds no game bytes).

The LBA reference graph

Two facts make the relayout safe (how we know):

  1. PROT.DAT's internal TOC is PROT.DAT-relative, not absolute disc LBAs. Entry 0's TOC start LBA is identical on every region's disc even though PROT.DAT sits at a different disc LBA per region. Growing an interior entry needs only an internal-TOC shift (PROT.DAT TOC), not a disc-wide cascade.
  2. No file is located by a hardcoded absolute LBA in the executable. Every file is found by ISO9660 name lookup; no post-PROT.DAT file's disc LBA appears as a literal in any USA or PAL executable.

When PROT.DAT grows by G sectors the cascade reduces to one rule: every ISO9660 LBA value > prot_lba gains +G; PROT.DAT's directory-record size gains +G*2048; the PVD volume-space size gains +G.

StructureLocationEdit
PVD volume spaceLBA 16, off 80 (LE) + 84 (BE)+= G
Path table (LE @18 + BE @20, incl. optional copies @19/@21)dir extentsextents > prot_lba += G
Directory records (root + every subdirectory extent)rec off +2 LBA / +10 sizeLBA > prot_lba += G; PROT.DAT size += G*2048
PROT internal TOCPROT.DAT byte 8+(j+2)*4entries after a grown one += cumulative G (PROT-relative); every non-zero word past the last entry's start (its end bound + the monotone tail) += total G - the reader sizes an entry by the gap to the next word, so an unshifted bound would drop the last entry

Subdirectory extents that live after PROT.DAT (MOV and XA on the retail disc) relocate too, so their self . record and file records are patched at the extent's new position.

Per-sector mechanics of a relocation
  • Every sector after PROT.DAT moves +G: its 12-byte sync + 4-byte header are rewritten so the stored MSF address is BCD(lba+150) for the new position.
  • Form 1 EDC/ECC are computed with the header treated as zero (crates/iso/src/write.rs), so a pure relocation needs no EDC/ECC recompute - only the MSF header changes. Form 2 (XA) sectors carry no ECC.
  • EDC/ECC are recomputed only for sectors whose user data changes: the rebuilt PROT.DAT payload, the PVD, path tables and the directory extents.
  • The PROT entry index space is preserved (no entries added or removed), so index-keyed same-size edits still resolve after a relayout.

Consumers: DiscPatcher::grow_prot_entries and the translate import --allow-relayout localization path (translation tooling).

How we know

Evidence behind the geometry and the relayout rule
EvidenceAddress / sourceWhat it proves
ECMA-130 / CD-ROM XApublic standardSector geometry, EDC/ECC polynomial, MSF encoding
PROT.DAT openerFUN_8003E4E8The archive is found by ISO9660 name lookup, not by a hardcoded LBA
STR / XA path openerSCUS path-open helperMovies and audio are opened by path; no absolute LBA literal in any USA or PAL executable
USA vs PAL diffSCES_019.44/.45/.46The PAL discs are a per-entry +1-sector relayout of the same structure; PROT TOC entry 0 is identical across regions (PROT-relative)
Round trips on the real disccrates/iso, crates/patcherEvery rewritten sector stays EDC/ECC-valid; relayout preserves the entry index space

Full page: docs/formats/disc.md.

See also