Age of Wonders II: The Wizard's Throne, PC CD-ROM, June 2002. Volume AOW2,
335,261 sectors, 686,614,528 bytes, 36 files in 13 folders. Borland Delphi 5.
SafeDisc 2.60.052. 23.91 % of the disc belongs to no file, and this
repository reproduces 143,595,520 bytes of it from two integers.
The material is the retail disc itself, in a drive, at E:\ — not an image
and not a copy. Every number below has a command behind it and the output of that
command is in notes/. Where a measurement was taken from the verified
byte-identical copy in _work/iso instead of the drive,
02 — The spec sheet says so in the row.
The full one, with a command in every cell, is 02 — The spec sheet.
| medium | CD-ROM, one track, profile 0x0008, 335,411 sectors to the lead-out; lead-out − declared volume = +150, which is two seconds of Red Book pre-gap and not a property of this disc |
| filesystems | ISO 9660 + Joliet (escape %/@), no UDF. Both namespaces describe the same 36 files, 13 folders and 522,377,850 bytes — but the ISO root directory is at LBA 335,260, the last sector of the volume, and the Joliet root is at LBA 37 |
| descriptors | two primary volume descriptors, at LBA 16 and 17, identical in every field ISO 9660 defines and differing in 305 bytes the standard requires to be zero |
| the payload | 351 bytes at +1139..1489, crossing the boundary between application use and reserved. Four integers in it are boundaries of this disc, and two of them are the first (807) and the last (10,265) physically unreadable sector on the medium |
| damage | isolated single unreadable sectors, key 3 MEDIUM ERROR asc 11, first 807, last 10,265, sampled at 6.17 % of the region (23 of 373 sectors, 3.9 % sampled). Not a contiguous region: every failing run measured is one sector wide |
| the 24 % | 80,163 unallocated sectors in four gaps. The largest, 70,125 sectors, is a generated pattern with a closed form: byte[i] = ((LBA + 82) × (i + 77)) mod 256, verified against all 2,048 bytes of 70,115 of 70,125 sectors; the other ten are zeros before the root directory |
| engine | Borland Delphi 5 — MZP stub, CODE/DATA/BSS sections, no Rich header, imports Vcl50.bpl and Vclx50.bpl, and the only surviving build paths are d:\aow2\engine\ek\HashTab.pas and d:\aow2\engine\gfxe\GFXE.pas |
| middleware | Miles Sound System (Mss32.dll, Mp3dec.asi) and Bink Video (binkw32.dll), each confirmed three ways — runtime file, data format (32 .bik, 13 .mp3) and the licensor's own notice text |
| containers | eleven ZIP archives named for content, 92.07 % of the tree, 1,494 members, 639,899,342 bytes uncompressed. Read from the outside only; 1,387 members deflated and 107 stored |
| protection | SafeDisc 2.60.052, BoG_ at 0x3D4 in AoW2.~ex — a wrapped PE32, not an encrypted blob, whose CODE section is at entropy 7.961 and whose .rsrc is in plaintext. Corpus: 5 files, 529,276 bytes, 0.10 % of the disc, of which 87.29 % is one dialog bitmap shipped at 16 and at 256 colours |
| languages | seven folders, four of them empty; two game archives (en, it); three licences (en, it, es); Dict/Install.mld names six languages and three code pages, and Spanish is not one of them |
| toolchain | Microsoft linker 3.10 / 5.10 / 6.00 / 7.00 on seven third-party binaries; Borland's fixed constant 0x2A425E19 — not a date — on the two the developer built. 0 of 9 signed |
| provenance | the disc names Triumph Studios, Gathering of Developers, PopTop Software, Take Two (five offices), Miles, Bink and Cidiverte, all with offsets — every claim on the case lid, confirmed from the software |
| against the collection | 2 of 36 files byte-identical to the 2001 Philosopher's Stone CD — cfgmgr32.dll and setupapi.dll, both linked in 1997 — and 0 against 19,314 other file records. The first crossing between two different publishers in this collection |
| access path | \\.\E: accepts a 707-sector read and fails larger ones after 8.7 s; SPTI accepts 32 and refuses larger ones in 1 ms. The two agree about which sectors are readable: 14 comparisons, both orders, 0 disagreements |
| 00 — Predictions | 83 clauses written before a sector was read, never edited |
| 01 — What this disc is | the provenance, and the four things it is not |
| 02 — The spec sheet | every figure with the command that reproduces it |
| 03 — Two ways to read a sector | why sweep.py would take ten hours, what a failed read means, and a hypothesis of mine that a tool disproved |
| 04 — 807 and 10,265 | the disc writes down its own damage, in a field the standard requires to be zero |
| 05 — Two primaries and a root at the end | 305 bytes, one payload not two, and a root directory on the last sector |
| 06 — A closed form for a quarter of the disc | 143,595,520 bytes reproduced from two integers, checked byte by byte |
| 07 — Thirty-six files | the census, and the two files whose names are their colour count |
| 08 — Eleven archives | read from the outside, and why they stay shut |
| 09 — SafeDisc 2.60.052 | an offset that moved, and a protection that names itself nowhere |
| 10 — Object Pascal, Miles, Bink | five independent proofs of Delphi, an unregistered ZIP component, and everyone the disc names |
| 11 — Seven folders, six languages | four empty directories, one undocumented dictionary format, and a Spanish contract for a product that is not here |
| 12 — The clocks | six of them, one that is not a clock, and a filesystem that disagrees with itself 98 times |
| 13 — Two files, two publishers | the first crossing in this collection, and both files are from 1997 |
| 14 — Four discs | 24 axes, 72 citations checked, and the sentence the tool refuses to let anyone write |
| 15 — Open questions | eleven, each with what was tried and what would close it |
| 16 — Prediction scoring | 83 clauses scored: 54 hit, 17 half, 10 miss, 2 unresolved |
| 17 — The tools | 113 inherited, 57 that do not apply, 18 that lie, 7 written here |
| 18 — Leftovers | the briefing's four errors, three of mine, and what is still on the table |
Everything needs Python 3 and nothing else — no third-party module is used
anywhere in tools/. E is the drive letter; _work/iso is a copy of the
disc's 36 files, which this repository does not contain.
# the medium
python tools/spti.py E # profile, capacity, drive identity
python tools/toc.py E # lead-out, and the +150
python tools/xfermax.py E --at 100 # the transfer ceiling of each path
# the filesystem
python tools/vds.py E # four descriptors, two of them primary
python tools/vds.py E 16 17 # the 305 bytes
python tools/vdpayload.py E # what those bytes look like
python tools/isodev.py E --extents # the extent map and the four gaps
python tools/isodev.py E --compare # ISO against Joliet
python tools/isodev.py E --tz # 49 records, one offset
# the two integers
python tools/holepat.py E 780 960 --block 1 --max-failures 14
python tools/pathdiff.py E 806 807 808
python tools/vdmatch3.py E --span 1139 1490 \
--extents notes/isodev-extents.txt \
--boundary "first unreadable sector (holepat.py)=807" \
--boundary "last unreadable sector (holepat.py)=10265"
# the 24 %
python tools/holepat.py E 265135 335259 --model "(lba+82)%256"
python tools/padform.py E 265135 335259 \
--formula "((lba+82)*(i+77))%256" --cache-mod 256
# the files
python tools/hashall.py E:/ # notes/sha1-all.txt
python tools/census.py _work/iso --magic
python tools/pe.py "_work/iso/AoW2.~ex"
python tools/bog.py "_work/iso/AoW2.~ex"
python tools/mld.py _work/iso/Dict/Install.mld
python tools/zipdir.py _work/iso/Data/System.zip --list
# against the rest of the collection
python tools/listdiff.py notes/sha1-all.txt \
../pc-harrypotter5-doc/notes/hp1-sha1-all.txt
python tools/fourdisc.py
# before committing
python tools/checklinks.py
python tools/checkscore.py
A note on cost, because on a physical disc the cost is part of the measurement:
a failed read on this drive takes about seven seconds, and roughly sixty
consecutive failures put the drive into a state where good sectors fail too,
cleared only by opening the tray. holepat.py --max-failures exists for that
reason and prints its budget beside its result.
No file from the disc. .gitignore excludes _work/ by name and 21 extension
patterns besides, and git ls-files is checked against that list before the
first commit — the check is in 17 — The tools.
notes/ holds the saved output of every run the documents cite, including
notes/sha1-all.txt: the SHA-1, size and path of all 36 files, published so
that the next disc in this collection can be compared with this one in thirty
seconds and without a drive.