Files
tdkpin/original/RECONSTRUCTION_PROGRESS.md
ddidderr 8b99e9607c feat(reconstruction): complete binary-backed C recovery
Replace the partial mechanics transcriptions with a separate, readable C11
reconstruction of the complete Win16 image while preserving the original raw
Ghidra export as immutable evidence. Cover all ordinary and overlapping entry
points, Borland runtime behavior, Win16 imports, segmented data, callbacks,
resources, indirect control flow, physics, rendering, persistence, and
startup/shutdown lifecycles.

Add deterministic extraction and audit tooling plus address-linked ledgers for
functions, imports, DGROUP ranges and objects, relocations, resources, and
callbacks. The final gate records zero raw, partial, restored, unknown,
blocked, or unclassified required units. Keep the semantic-fidelity boundary
explicit: the portable C is not claimed to reproduce a byte-identical Borland
NE build.

Add strict focused harnesses for every reconstructed C unit, exact resource
round-trip checks, and a 16-bit Borland Real48 reference probe. No Rust source
or Cargo metadata is changed in this phase.

Test Plan:
- `bash original/tools/test_reconstructed_c.sh` -- passed
- `bash original/tools/probe_real48_reference.sh` -- passed bit-for-bit
- `python3 original/tools/audit_reconstruction.py --require-complete` -- passed
- `git diff --cached --check` -- passed
- `git diff HEAD -- '*.rs' Cargo.toml Cargo.lock` -- empty
2026-08-23 16:41:17 +02:00

10 KiB

Complete C reconstruction progress

This ledger tracks the full reconstruction of TDKPIN.EXE, not the narrower Rust gameplay replica. The binary is authoritative:

a9022f1894e3e6e21fc42e8f6c932f7c549ca77f63aaa0c488bb9d55d9d0174c  TDKPIN.EXE

The required deliverable is polished, readable C that accounts for every binary-backed function, data object, callback, resource, import interaction, and observable behavior. Raw Ghidra output remains immutable evidence and is not itself accepted as reconstructed source.

Until every completion gate in this file passes, the Rust project is explicitly out of scope and must not be edited. Translation to Rust is a separate future goal that begins only after the C reconstruction has passed its final audit.

The preserved initial raw export is independently sealed as:

987a47580ba5c92fa071c989bdaeddf138e285d2b07106c5909a4acbc3e27088  TDKPIN_GHIDRA_RAW.c

Current measured baseline

Gate Current evidence Status
Known in-image functions 391 ordinary functions plus six separately tracked overlapping/shared entries 0 raw, 0 partial, 0 restored, 391 verified; all six shared entries verified; every code segment is raw-free
Readable function reconstruction 63 separate strict-C11 modules under reconstructed/ complete; every ordinary/shared entry is address-linked and raw evidence is never used as the readable deliverable
Imported Win16 APIs 292 slots / 140 unique declarations 0 partial, 292 verified; 137 called slots have prototype/call-site evidence and 155 data/duplicate/unused slots have an explicit zero-CALL proof
Executable bytes 93,064 total; every byte classified complete structural classification
Non-overlapping Ghidra code/data 93,062 bytes; 92,780 instruction bytes and 282 embedded-data bytes complete within Ghidra's representation
Exceptional executable bytes overlapping opcode at 1020:0666; alignment NOP at 1020:0dea classified with byte-level evidence
Defined data 578 Ghidra-defined units raw inventory only
Referenced DGROUP addresses 455 unique targets reached from 147 functions 0 unknown, 0 restored, 455 verified after semantic projection
Byte-complete DGROUP ranges 744 non-overlapping ranges / 19,770 bytes 0 raw, 0 partial, 0 restored, 744 verified, 0 unknown
Semantic DGROUP objects 219 exact objects 0 raw, 0 partial, 0 restored, 219 verified, 0 unknown
Code-embedded data objects 18 objects / all 282 executable data bytes 0 unknown, 0 restored, 18 verified; exact inventory bijection enforced
Collision/rule records 175 initialized records exact static ledger and live dump available
Resources 63 NE resource blocks 0 raw, 0 partial, 0 restored, 63 verified; 57 directly managed, 2 Windows-resolved, and 4 explicitly linked-unused
Callback sites six registration sites all six verified, including bootstrap and generated bound thunks
Companion MMTIMER.DLL SHA-256 f1d9ac980c7bfba5dc53eaa9e7cb2c3cd9b82f879ee8962ad40bf863d641bb49 ordinal 1 wrapper, internal callback, posted message 0580, timer-id return, and cancellation lifetime mapped
Live runtime Wine 11.15 staging plus trace/dump/injection tooling exact original exercised for startup/input and focused types 1/2/3/4, claw, flipper, multiball, and score transitions
Buildable reconstructed C strict C11 Win16/segmented model and 89 focused harness units complete; every one of 63 reconstructed C units is compiled by test_reconstructed_c.sh, all tests pass, and the Borland Real48 DOS reference probe is bit-exact

The prior 363-function inventory was incomplete. Classifying the executable gaps recovered 28 additional Borland runtime entries and established the current 391-function denominator. It remains subject to later correction only if direct control-flow or runtime evidence proves an overlapping/shared entry that Ghidra cannot represent as an ordinary function.

Evidence artifacts

  • TDKPIN_GHIDRA_RAW.c: immutable original raw decompiler output; never regenerated.
  • FUNCTIONS.tsv and COVERAGE.tsv: immutable inventories paired with that original export.
  • TDKPIN_GHIDRA_COMPLETE_RAW.c: separate regenerated raw evidence containing every currently recovered entry after missed-code seeding and Win16 import typing.
  • COMPLETE_FUNCTIONS.tsv and COMPLETE_COVERAGE.tsv: inventories paired with the separate complete raw evidence.
  • BINARY_FUNCTIONS.tsv: function bodies, blocks, conventions, and provisional signatures.
  • REFERENCES.tsv: complete Ghidra reference export for calls, jumps, reads, and writes.
  • DEFINED_DATA.tsv: all currently defined data units.
  • SYMBOLS.tsv: all loader/analyzer symbols.
  • UNEXPLAINED.tsv: exact bytes outside ordinary function/code-data coverage; both current rows have explicit overlap/alignment classifications and evidence.
  • SHARED_ENTRY_POINTS.tsv: internal compiler/runtime entry points that begin inside another decoded instruction stream, including the verified C-string versus ShortString TextRec entries at 1020:049f and 1020:04a0.
  • FUNCTION_RECONSTRUCTION.tsv: one semantic-status row per known in-image function.
  • IMPORT_RECONSTRUCTION.tsv: one row per NE import slot, including module, stack-purge size, direct call count, prototype status, and review evidence.
  • DATA_RECONSTRUCTION.tsv: one row per currently referenced DGROUP address, with readers/writers and unresolved semantic object boundaries made explicit.
  • DATA_COVERAGE.tsv: byte-complete non-overlapping coverage of all 19,770 DGROUP bytes, including the 17,906-byte zero-fill tail.
  • DATA_OBJECTS.tsv: reviewed semantic data objects whose exact ranges and types are projected into the byte-complete coverage ledger.
  • CODE_DATA_OBJECTS.tsv: one semantic row for every defined data object embedded in executable segments, including compiler tags, ShortStrings, Real48 tables/constants, and the Borland runtime identification string.
  • ENTRY_POINTS.tsv, NE_SEGMENTS.tsv, MODULE_REFERENCES.tsv, and RELOCATIONS.tsv: direct NE metadata, including all 2,434 expanded relocation sites and their internal/import targets.
  • RESOURCE_RECONSTRUCTION.tsv: one verified row per NE resource with exact extraction provenance, code/system user mapping, lifecycle, and explicit classification of linked-but-unused Borland templates.
  • CALLBACK_RECONSTRUCTION.tsv: every identified callback-registration site, callback target, lifetime, and invocation path, all verified.
  • COVERAGE.tsv: executable-byte coverage and memory-block inventory.
  • OBJECTS.tsv: all initialized collision/rule records.
  • assets/manifest.json: resource offsets, raw hashes, and decoded derivatives.
  • reconstructed/: separate readable C modules and Win16/segmented-memory type model.
  • tools/test_reconstructed_c.sh: strict C11 tests for verified numeric, circular-buffer, key-table, selector, overlap, far-string, heap-ring, Borland object ownership, stack-guard, and SystemTimer behavior.

Run python3 tools/audit_reconstruction.py after every reconstruction batch. It fails if the target hash, function bijection, raw markers, body metadata, coverage totals, or collision-record inventory drift.

Run python3 tools/audit_reconstruction.py --require-complete for the final gate. It intentionally fails until every required function, import, data, resource, and callback row is verified and no unclassified range remains.

Completion gates

The reconstruction is complete only when all of the following are true:

  1. Every executable byte is classified as function code, embedded data, relocation material, alignment, or unreachable padding with recorded evidence; no row remains unclassified.
  2. Every in-image function has exactly one address-linked readable-C implementation and a verified ledger row. Combined or split source helpers retain an explicit mapping to the original function ranges.
  3. Every DGROUP region and code-embedded data object has a named type, extent, initialization source, and complete read/write reference set.
  4. All 292 imports have correct Win16 prototypes and every call site has reviewed argument order, far-pointer handling, and return semantics.
  5. Window procedures, dialog procedures, timer callbacks, multimedia paths, and stored function pointers are separately inventoried and traced to their registration and invocation sites.
  6. All 63 resources and the companion MMTIMER.DLL are mapped to their users; unused resources, if any, are explicitly identified rather than omitted.
  7. Segmented pointers, DGROUP assumptions, 16-bit wrapping, Borland Real48, calling conventions, stack cleanup, and indirect jump tables are represented without silently replacing target behavior with modern equivalents.
  8. The reconstructed sources pass strict syntax/build checks in their declared compatibility model and focused normal/sanitizer harnesses where host execution is meaningful.
  9. Behavioral evidence is proportional and explicitly typed: complete disassembly/data-flow closure for every required unit, strict focused C harnesses for normal/error/ownership/ABI paths, a bit-exact 16-bit Borland Real48 reference probe, and focused Wine comparisons where live state adds evidence (startup/input, claw, flippers, collision types 1..4, multiball, scoring, and timer substeps). Host-only tests are never labeled Wine probes.
  10. The final audit reports zero raw, partial, restored, unknown, unread, unclassified, or behaviorally unverified required units.

Work order

  1. Recover the Borland/Win16 ABI model and correct every imported and internal signature before relying on decompiler parameter lists.
  2. Group DGROUP references into typed data objects and recover initialization, ownership, and lifecycle.
  3. Reconstruct functions by subsystem into separate readable C modules while preserving address-level traceability.
  4. Add subsystem differential probes and promote ledger rows to verified only when static and runtime evidence agree.