Skip to content

CDs and DVDs ​

A game on a CD is more than the files a file manager shows. The disc can hold audio tracks, sectors of a second kind for video and sound, more than one file system, and data that only a raw copy keeps. This page describes what to look for on a game disc, which image to work from, and what the port must take from it. tools/disc/discinfo.py reads the images and reports each part. The standards behind it are ECMA-119 (ISO 9660), ECMA-130 (the CD sector) and the CD-ROM XA and El Torito specifications.

Sectors and tracks ​

A CD sector of 2352 bytes in four kinds, drawn to scale

A CD is a list of sectors of 2352 bytes. 75 sectors play in one second, so positions are written as minutes, seconds and sectors (MM:SS:FF). The table of contents lists the tracks. Each track is audio or data.

Sector kindUser bytesWhere the data starts in the 2352Used for
Audio (Red Book)23520Music: 588 stereo samples of 16 bits at 44,100 Hz
Mode 1204816Files on most PC discs
Mode 2 Form 1 (CD-ROM XA)204824Files on PlayStation, CD-i and some PC discs
Mode 2 Form 2 (CD-ROM XA)232424Streamed video and sound, with no error correction

A data sector starts with 12 bytes of sync pattern and 4 bytes of header, which give its address and its mode. A Mode 2 sector adds an 8-byte subheader, which says whether the sector is Form 1 or Form 2. The PlayStation's CD-ROM documentation describes how that console reads XA audio and STR video from Form 2 sectors.

The disc's first sector is at 00:02:00, after a two-second pregap that images do not store. Sector numbers inside the file systems (LBAs) start at that point. The start column in discinfo.py counts from the start of the image, so it does not add these two seconds.

Kinds of disc ​

The layout of each kind of disc, from data only to bootable

KindLayoutWhat it means for the port
Data onlyOne data trackAll the game is in the files
Mixed modeData in track 1, audio in tracks 2 onwardsThe music is CD audio. The port must play the tracks
Enhanced CD (CD Extra)Audio in the first session, data in a second sessionThe data's sector numbers start after the audio session
Multi-sessionSeveral sessions, each with its own file systemRead the last session's file system. Earlier ones can hold older files
HybridISO 9660 and HFS on the same data trackThe Mac files can differ from the PC files
BootableAn El Torito boot recordThe disc starts its own program without an installed system

A game that plays CD audio does it through the system. A DOS game sends play requests through MSCDEX (interrupt 2Fh, function 1510h, with device request 132 for play audio). A Windows game uses MCI, such as mciSendCommand with the cdaudio device. Find those calls to find the game's table of track numbers, which says which music plays where.

File systems ​

Where ISO 9660 keeps its system area, volume descriptor, tables and files

File systemNamesNotes
High Sierra8.3The format before ISO 9660. Early CD-ROMs only
ISO 96608.3 at level 1, with a version suffix ;1Every data CD has it. Numbers are stored twice, little-endian then big-endian
JolietUp to 64 UCS-2 charactersA second directory tree for Windows, added with Windows 95
Rock RidgeLong POSIX names and permissionsUnix discs. Stored inside each ISO 9660 record
HFS and HFS+Mac names, resource forksHybrid Mac and PC discs. Read them with hfsutils or HFSExplorer
UDFLong names, large filesDVDs. A DVD usually carries ISO 9660 as well

The ISO 9660 primary volume descriptor at sector 16 names the system, the volume, the publisher, the data preparer and the application that mastered the disc. It also holds four dates: created, modified, expires and effective. Each file record has its own date. These dates help to date a release and to tell two pressings apart.

A file record can be marked hidden. Some discs also list files whose sectors lie outside the volume's stated size, or give two files the same sectors. Some copy protections use these tricks. discinfo.py reports hidden files and files outside the volume.

Four more checks show what a file list alone misses:

  • Sectors no file uses. A mastered disc accounts for nearly every sector. --map reads every sector of the data track and lists the runs that hold data but belong to no descriptor, path table, directory or file, with a guess at what each run holds. A file left over from development, a second copy of a file, or data the game reads by sector number can sit there.
  • The system area. Sectors 0 to 15 are empty on a PC disc. On a console disc they hold the licence text and the boot code: the PlayStation, the Saturn, the Mega-CD and the Dreamcast each use them. discinfo.py names what it finds.
  • Two trees that differ. The ISO 9660 and Joliet trees usually list the same files. A file missing from the Joliet tree is hidden from Windows. A mastering tool can leave files out on purpose. discinfo.py lists each file that only one tree has, and copies it with the rest.
  • Files dated after the volume. The volume descriptor is written last when a disc is mastered. A file dated later suggests changed dates or a wrong clock.

Images ​

What each disc image format keeps and loses

ImageWhat it keepsWhat it loses
.iso2048 bytes of each data sectorAudio tracks, Form 2 sectors, sector headers, subchannels
.cue and .bin (raw)All 2352 bytes of every sector, every trackSubchannel data
.ccd, .img, .sub (CloneCD)Raw sectors and subchannelsLittle
.mds and .mdf (Alcohol 120%)Raw sectors, often subchannels and timingLittle
.chd (MAME)Raw sectors, compressedNothing. chdman extractcd writes CUE and BIN

Work from a raw image when the disc has audio or Mode 2 data. A .iso of such a disc lacks the music and the video. A file of Mode 2 Form 2 sectors, such as a PlayStation STR video or XA sound file, is marked in its directory record. discinfo.py --extract copies such a file as whole 2352-byte sectors, the form the tools for those formats read. A copy of 2048 bytes per sector would lose part of every sector. Some protections read the subchannel. One example is LibCrypt on PAL PlayStation discs. For those, keep the .sub file or the SBI data that Redump publishes for each disc.

Redump also lists the hashes of every track of verified dumps. Compare the hashes of your image with Redump's entry to learn which pressing you have.

In a few rips, the audio is stored big-endian. If an extracted track sounds like loud noise, extract it again with --swap.

Using discinfo ​

bash
python3 tools/disc/discinfo.py target/cd/GAME.CUE                 # tracks, file systems, dates
python3 tools/disc/discinfo.py target/cd/GAME.CUE --files          # every file with its sector and date
python3 tools/disc/discinfo.py target/cd/GAME.CUE --extract target/cd/files --audio target/cd/audio
python3 tools/disc/discinfo.py target/cd/GAME.CUE --map            # data in sectors no file uses
python3 tools/disc/discinfo.py target/cd/GAME.CUE --json > derived/disc.json

scripts/extract-installer.sh recognises CD images and calls discinfo.py with --extract and --audio. The files and the audio are game material. Keep them in target/ or derived/. The report itself (track lengths, dates, identifiers) can go in docs/FINDINGS.md.

What to record ​

  • Each track: data or audio, the mode, the length, and the session.
  • The volume identifiers and dates, and the hashes of each track or of the image.
  • Which tracks the game plays, and from which function. Then the port's music table can cite it.
  • Any Form 2 data, hidden file, file outside the volume or second file system.
  • The image format you worked from, and what it would have lost.

Ask your agent ​

text
In my GameFrame project, look at the game's CD image in target/cd/.

1. Run tools/disc/discinfo.py on it, with --files, and read docs/media/discs.md.
2. Record in docs/FINDINGS.md the tracks, the file systems, the volume identifiers and dates,
   and anything unusual: audio tracks, Form 2 sectors, hidden files, a Mac volume.
3. If there are audio tracks, find the code that plays them (MSCDEX or MCI calls) and list the
   game's track table with its address.
4. Extract the files into target/cd/files and the audio into target/cd/audio. Commit nothing
   from target/.

Code: Apache 2.0. Content: CC0 1.0. No game material: bring your own copy.