Explorar el Código

docs: root README (method, layout, scores, toolchain rules, reproduce)

Eric Streit hace 3 días
padre
commit
52c3b7575b
Se han modificado 1 ficheros con 73 adiciones y 0 borrados
  1. 73 0
      README.md

+ 73 - 0
README.md

@@ -0,0 +1,73 @@
+# Turbo Modula-2 — Compiler Reverse Engineering
+
+Reverse-engineering the Turbo Modula-2 v1.00 compiler into readable,
+renamed Modula-2 sources, verified by recompiling with the **original
+v1.00 toolchain** and diffing the resulting `.MCD` binaries procedure by
+procedure against the originals.
+
+## Method
+
+1. Disassemble original `.MCD` files (`Reversing-Turbo-Modula2-main/`,
+   git-ignored upstream input) with `unassemble.c`.
+2. Rewrite each module in readable Modula-2 (`src/compiler/`), renaming
+   `globalN`/`procN`/`localN` per `src/compiler/RENAME-MAP.md`.
+3. Recompile with unmodified Turbo Modula-2 v1.00 (`M2.COM` + `m2.ovr`,
+   run under `cpmulator`), driven hands-free by `tools/m2drive.py` +
+   `tools/chain.sh`.
+4. Disassemble our `.MCD`, compare mnemonic streams (absolute jump targets
+   masked, `00` gap bytes stripped, dep-slot renumbering accepted as benign).
+   Score = identical procedures / total.
+
+## Layout
+
+- `src/compiler/` — renamed `*.DEF`/`*.MOD` under verification, plus
+  `RENAME-MAP.md` (canonical names), `FRONTEND.md` (export map with MCode
+  offsets), `GENZ80.md`.
+- `docs/compiler/` — module analyses (`00-overview` … `70-rename-plan`),
+  `disasm/` (backend disassemblies), `TAGGED-SUMMARY.md`.
+- `tools/` — `m2drive.py` (pty driver for the M2 shell), `chain.sh`
+  (fresh-boot-per-file batch compiles), `mcdiff.sh` (stage-1 static checks).
+- `tmp/` — local CP/M working drives and scratch (git-ignored, never commit).
+- `SESSION.md` — running log + next-session plan. `SUMMARY.md` — milestones.
+- Upstream inputs (`Reversing-*/`, `Turbo-*Reloaded*/`, CP/M images) stay
+  git-ignored; only analysis + renamed sources are versioned.
+
+## Verification status (Oct 2026)
+
+| module | result | tag |
+|---|---|---|
+| COMPILER.MOD | 18/19 byte-identical (linkage names only) | stage2-v1 |
+| SCANNER.MOD | 34/41 mnemonic-identical | scanner-verify-01 |
+| ERRORS.MOD | 28/30 mnemonic-identical | errors-verify-01 |
+| CODEGEN.MOD | 34/37 mnemonic-identical | codegen-verify-01 |
+| SYMTAB.MOD | WIP: compiles through GetAttr, wall in EnterIdent | symtab-wip-02 |
+| EXPRESS/STATEMEN/PASS1/GENZ80/NATIVE | drafts, unverified | *-draft-v1 |
+
+Remaining diffs are all accounted for in `SESSION.md` (clean-room Z80
+replacements, forced literal folding, VarAddr shim, gap-filler/FATDIR
+divergences, trailing address tables).
+
+## v1.00 toolchain rules (all proven on hardware via ZZ probes)
+
+- `DEF`-imported names leak into the `MOD` scope; re-listing is a hard error.
+- `DEF`/`MOD` parameter names must match exactly.
+- No `CAST`/`VAL`; no `CARDINAL→BITSET` assignment (use `BITSET{n}` literals).
+- `IN` needs real sets; open-array `VAR` accepts any variable (VarAddr trick).
+- Transfer results can't be indexed/dereferenced (`Words(x)^[i]`,
+  `P(x)^.f`) — retype params to view types, transfer (zero-cost) at call sites.
+- `= 0` emits unary `eq0`; `CHR(ORD())`/`ORD()`/`CHR()` are zero-cost no-ops.
+- `OUT OF MEMORY` often masks type errors — isolate suspects in fresh-heap
+  ZZ probes. Heap budget is per-proc nodes; ELSIF-nesting pins conditions.
+- Retail M2.COM is Version 1.00 (writes SYM v3); shipped originals carry
+  SYM v2 (Borland-internal toolchain) — explains laxer original spellings.
+
+## Reproduce
+
+```sh
+./tools/mcdiff.sh            # stage-1 static checks (no VM needed)
+./tools/chain.sh tmp/stage/drive SCANNER.MOD   # compile under v1.00
+tmp/stage/unassemble tmp/stage/drive/SCANNER.MCD  # then diff vs original
+```
+
+See `SESSION.md` → “Next session plan” for what comes next (currently:
+SYMTAB per-proc loop, then EXPRESS → STATEMEN → PASS1).