docs: plan to retire the settled VT1200_* env gates (promote working config to default, delete finished experiments)

This commit is contained in:
SDD committed 2026-10-16 13:02:20 +03:00
1 parent 6cbb362bb9
commit ac60ad2f89
1 file changed
+98
@@ -0,0 +1,98 @@
# Plan: retire the settled `VT1200_*` env gates
Status: **planned, not started.** Execute after the current `vt1200.cpp` worker
lands its interrupt-line / palette / test-map work.
## Why
The driver grew **33** `VT1200_*` environment gates. They were added deliberately —
one per experiment — so that the no-env baseline stayed byte-identical and a change
could not silently alter behaviour. That discipline paid for itself repeatedly.
But most of those experiments are now **settled**, and the consequence is that the
*working* configuration is a six-variable incantation:
```sh
VT1200_VRAM=1 VT1200_BOARD_MODEL=handshake VT1200_BOARD_BUSY_TICKS=2 \
VT1200_BOARD_SWITCH="0640000D:70:70" VT1200_DUART=1 VT1200_DUART_SEL=1
```
Running `vt1200 vt1200` with no env silently gives a machine that doesn't work — which
is misleading, and already caused one wrong conclusion in this project (a stale
"256 KiB RAM" note led to an incorrect instruction being sent to a worker). **The
correct configuration should be the default.**
## Triage
### A. Promote to the default (remove the gate)
| Gate | Why |
|---|---|
| `VT1200_VRAM` | maps video RAM at bit `0x04000000`; required for the VIDEO MEMORY test to pass |
| `VT1200_DUART` | maps MAME's `SCN2681`s; required — the host-port transmit is ISR-driven and only works with a real DUART |
| `VT1200_DUART_SEL` | fold to **DUART1 always**; expose DUART2 as its own opt-in. `SEL=1` is the working config (mapping both diverts level 0) |
| `VT1200_BOARD_MODEL` | default → `handshake` |
| `VT1200_BOARD_BUSY_TICKS` | default → `2` |
### B. Delete (completed experiments / superseded probes)
| Gate | Why |
|---|---|
| `VT1200_CAL`, `VT1200_CAL_VID4M`, `VT1200_CAL_W8` | the memory-space calibration spike — **finished**; its results are in `reference/memory-space-map.md` |
| `VT1200_BOARD_RAM`, `VT1200_BOARD_DEFAULT` | probe variants of the window model |
| `VT1200_BOARD_BUSY_W2`, `VT1200_BOARD_BUSY_W3` | per-window variants of `BUSY_TICKS` — fold into the default |
| `VT1200_BOARD_DMA_TICKS` | probe; not in the working configuration |
| `VT1200_BOARD_SWITCH` | **verify first** — the monitor switch is now served by the DUART's IP4–IP6, so this may be entirely superseded |
| `VT1200_DUART_LB1`, `VT1200_DUART_LB2` | external TX→RX loopback wiring — proven unnecessary: the firmware sets MR2 local loopback itself, and the datasheet holds TxD **high** in local loopback (SCN2681 local-loopback item 3) |
| `VT1200_LOWLOG` | low-RAM logging proxy — a one-off probe, and a confusing extra mapping |
| `VT1200_VRAMLOG` | VRAM access log — one-off |
| `VT1200_STRUCTLOG` | structure dump probe — one-off |
### C. Keep
**Instrumentation that earns its place:** `VT1200_DUARTLOG`, `VT1200_BOARD_LOG`,
`VT1200_IRQLOG`, `VT1200_LOG_UNMAPPED` (the catch-all that closed the instrument
cross-check), `VT1200_DPYLOG` + `VT1200_DPYLOG_FRAMES` (pinned the render geometry),
`VT1200_DUMP_FRAME` / `DUMP_RAM` / `DUMP_VRAM` / `DUMP_DIR`, `VT1200_NO_RENDER`.
**Deliberate behaviour switch:** `VT1200_DUART_IP3` — it changes the *boot path*
(skips level 1). Keep, and **rename** to something self-describing
(e.g. `VT1200_SKIP_LEVEL1`), because `IP3` names a pin rather than an effect.
**Pending:** `VT1200_DUART1_INT2` — kept until the interrupt-line question is settled,
then deleted or folded.
Net: **~5 promoted out of existence, ~13 deleted**, leaving roughly 15.
## The one hard constraint
**The no-env baseline (`PC=3FDCE400 samples=199`) will legitimately change.** That is
the point — but it must change *deliberately*, never silently, and the project has
been burned twice by a claim that turned out to be a mask. So:
1. **Equivalence proof per promoted gate.** For each: capture the observable *with the
env set* (frame-dump md5, `progress.lua` sample, console capture via `cap.lua`),
then capture again *after* promotion with **no env at all**. The two must be
**identical**. That demonstrates we changed the *default*, not the *behaviour*.
2. **Deletion proof.** For each deleted gate, show the code it guards is reachable
**only** under that env var — i.e. no default path touches it. Deleting a live path
would be the same class of error as promoting a dead one.
3. **Re-baseline explicitly**, recording the old and new values and why — the baseline
is a change detector, not a specification.
## The trap to respect while promoting
`map()` entries are built at **configuration** time. A mapping gated on a pointer set
in `machine_start()` silently registers **nothing**. Promotion means making the
mapping **unconditional** — *not* moving the `getenv()` somewhere it will not be
consulted.
## Acceptance
* `vt1200 vt1200` with **no env** boots as far as the env-set configuration did
(frame dumps identical, same self-test progression).
* The promoted set produces byte-identical observables to the old incantation.
* Every deleted gate's code path is gone and nothing references it.
* Regression re-baselined and documented, with the reason.
* `README`/header comment block updated — it currently documents many of these knobs
and would otherwise become a liar.