https://github.com/scarabeeta/dcdump
Dumps a Dreamcast GD-ROM with one command. The reading is done by existing tools: redumper for the low-density (LD) area, dreamdump or redumper for the high-density (HD) area. dcdump is the glue: it picks the drives, works out what the disc is, runs the tools with the right settings, merges the output into redump's GD-ROM layout and compares every track with redump's datfile. A hash that does not match means exit 1.
Redump accepts the LD area only from a drive on its CD drive list and the HD area only from a drive on its GD-ROM list, so a submittable dump takes two drives: dcdump reads the LD area on the CD drive, ejects, waits for the disc to arrive in the GD drive, checks that it is the same disc (LD TOC and IP.BIN), then reads the HD area.
Needs Linux, Go 1.26+, and redumper b767 or later plus dreamdump on PATH.
go install github.com/scarabeeta/dcdump@latest
From a checkout: make builds a static binary, make deploy HOST=... copies it to the
machine with the drive.
dcdump [--manual] [--drive VALUE] [--ld-drive VALUE] [--serial VALUE] [--retries=N]
[--ld-only] [--check] [--force-drive ID] [-- other redumper options...]
dcdump --resume DIR [--drive VALUE] [--serial VALUE]
dcdump --submission DIR
dcdump --native[=HOST] [--keep] [--manual] [--serial VALUE]
dcdump --help
Unknown options are rejected before the drive is touched, so a typo cannot start a dump.
Anything after -- goes to redumper. Output lands in <repo>/work/dc/<name>/, or
$DCDUMP_WORK/<name>/.
- Drives: the LD drive is a drive on redump's CD list (
cddrives.json: new-dump drives first, then verification-only ones; a drive cross-flashed to OmniDrive is recognised by the version in its INQUIRY data, read from sysfs without sending it a command).--ld-drivepicks one,--ld-drive sameuses the GD drive for both areas. Without a listed drive the GD drive reads both and dcdump says the dump is not submittable. - Drive list:
drives.json, built in, overridden by~/.config/dcdump/drives.json. It says which drives read the HD area and how. Anything else is LD only, with--ld-only.--force-drive IDapplies an entry to a drive that does not match it. - Preflight: TOC, a raw READ CD of the first and last LD sector, IP.BIN, one HD sector
(read as CD-DA for drives whose entry says
"hd_read": "cdda", such as Kreon DC02, which serve the HD area only that way). Some drives answer READ(10) but fail every raw LD read; this catches that before a long dump.--checkstops here. - Identification: product number, version and disc number from IP.BIN, looked up in the redump.info datfile, which is refreshed with a conditional GET each run. A disc that is not in it still gets dumped and is named by hash afterwards.
- LD area: redumper. If redumper knows the drive, its own database decides the settings;
otherwise they come from the drive list (read offset, sector order, and
pregap_startwhen the entry has one; the same values go to an HD redumper run). Over USB the sector order is forced toDATA_SUB, because ASM1153 bridges mangle transfers whose length is not a multiple of 4; b767 is the first build that asks for exactly that length, and an older release is refused on that path rather than left to produce a corrupt dump. - HD area: the drive-list entry's
hd_tool: dreamdump (default) with its parameters, in<dir>/dreamdump/, or redumper--ringswithhd_redumperparameters, in<dir>/hd-redumper/(only its HD tracks are used). They are always passed explicitly: dreamdump's own list stops at DH16D2S GD0C, so a newer firmware revision would be refused. Its tracks are moved next to the LD ones, its log is kept, and the two cues become one GD-ROM cue. USB links are pinned to USB 2.0. On SATA a libata fallback to PIO is reported; reboot to get DMA back. - Finish:
<name>_logs.zipfor submission (both logs, plus dreamdump's.subqand section hashes), a CRLF cue, a.gdi, and the redump.info form text:<name>.submission.txt(Dat with every track, offsets, comment) and<name>.dumplog.txt(LD log, then HD log, for the Dump Log field; "Fill from Dump Log" reads redumper logs only).--submission DIRwrites the last two again for an existing dump. Exit 1 if redumper's sector check failed, an HD track is missing, or any hash differs. - Resume: when the HD step fails, the LD area is kept;
dcdump --resume DIRreads only the HD area (or merges a finished HD run already in DIR), checks it is the same disc, then verifies and packs as usual.
Reads the disc in a real Dreamcast instead and compares the tracks with the datfile. Different drive, different read path, no redumper or dreamdump, so a match confirms a dump independently. It cannot produce a submission: that drive has no subchannel or C2.
The console side is not in this repository. It is a Dreamcast running Linux with a gdrom
driver that returns raw 2352-byte sectors, plus a gdserve service on TCP 9200 that answers
info, toc, read FAD COUNT and cooked LBA COUNT. native.go has the replies. Give the
address with --native=HOST, or set DCDUMP_NATIVE_HOST.
Sectors come back descrambled but not error-corrected, so each one is checked against its own
regeneration (sync, header, EDC, ECC), then re-read or rebuilt from the drive's 2048-byte read
if that fails. Audio is read twice. The audio offset is measured on the disc itself. Track
boundaries come from the datfile, or from pregap rules for a disc that is not in it. All of it
is counted in <name>.native.txt. The track files are deleted afterwards unless --keep.
testdata/dc-sample.dat is seven entries from redump's Dreamcast datfile, for the tests.
Run them with make test.
GPL-3.0-or-later, see LICENSE.