mirror of
https://git.k-space.ee/arti/vt1200.git
synced 2026-10-30 12:03:54 +02:00
docs: plan-1 outcome, rulings, and triaged findings (durable record before workspace cleanup)
This commit is contained in:
1 parent
66784de1aa
commit
170d07f0a2
1 file changed
+85
@@ -0,0 +1,85 @@
|
||||
# Plan 1 outcome — VT1200 board register model
|
||||
|
||||
Plan: `docs/superpowers/plans/2026-10-16-vt1200-board-model.md`
|
||||
Spec: `docs/superpowers/specs/2026-10-16-vt1200-board-model-design.md`
|
||||
Commits: `acb92d3e44ec..e23dadcfd4de` (7 commits)
|
||||
Status: **all 4 tasks complete, final whole-branch review clean after one documentation-only fix wave.**
|
||||
|
||||
This file is the durable record; the SDD workspace was deleted after review, as the process
|
||||
requires, with git history as the record.
|
||||
|
||||
## What was delivered
|
||||
|
||||
| Commit | What |
|
||||
|---|---|
|
||||
| `43f69738f405` | board register model extracted into a **MAME-free, unit-tested** class (`vt1200_board.h/.cpp`, `test_vt1200_board.cpp`); driver forwards to it |
|
||||
| `db2caa555803` | fix round 1: switch knob made unambiguous (`0x70` raw bits vs position) and non-silent |
|
||||
| `66fe15367b90` | per-window busy state machines |
|
||||
| `a2f19b2d29a4` | the `0x5800000`/`0x5900000` DMA command/data pair |
|
||||
| `2d7747a20d48` | configurable timings + the timing sweep and its honest findings |
|
||||
| `8e18d81cef07` | fix round 1: verbatim sweep/differential/INTENB evidence into the tracked log |
|
||||
| `e23dadcfd4de` | fix wave: documentation corrections (four windows, real callback trap, guessed DMA timing) |
|
||||
|
||||
Guarantees that hold: **no regression** — with no `VT1200_*` env vars set the driver still
|
||||
reproduces the original wedge `PC=3FDCE400 samples=199`, argued structurally as well as
|
||||
measured; 9 unit tests pass and the model compiles standalone with plain `g++`.
|
||||
|
||||
## The experiment's real result (negative, and valuable)
|
||||
|
||||
* The timing sweep is **flat**: `BUSY_W2` in `{1,2,4,8}` all give `total_distinct=59`. The
|
||||
reason is structural — `tick()` advances **once per emulated frame**, so busy durations of
|
||||
1/2/4/8 ticks are indistinguishable. Duration is the wrong axis.
|
||||
* **The critical handshake is isolated to `0x06200000` (WIN2):**
|
||||
`BUSY_TICKS=0` -> stuck `PC=3FDCE400` (5 PCs); `BUSY_TICKS=0 BUSY_W2=1` -> 56 PCs at
|
||||
`PC=3F208950`; `BUSY_TICKS=0 BUSY_W3=1` -> still stuck.
|
||||
* **`INTENB` never becomes non-zero** across 900 frames (`INTPEND=0400` throughout), so the
|
||||
level-0 interrupt boundary is still not crossed.
|
||||
|
||||
## Rulings I made (all of them, in order)
|
||||
|
||||
1. **Initialised a git repository in the project.** The directory was not under version
|
||||
control and the process needs an isolated tree plus per-task commits. A strict
|
||||
`.gitignore` excludes generated artifacts (160 MB AVI, RAM dumps, traces, core files,
|
||||
nested clones). *Cost if wrong:* a `.git` the user does not want; reversible with
|
||||
`rm -rf .git`.
|
||||
2. **Pinned the `tick()` call site to the scanline callback**, guarded on
|
||||
`scanline == screen.visible_area().max_y`. The plan left it ambiguous and the
|
||||
`screen_update` alternative is wrong (it fires in small clip regions). *Cost if wrong:*
|
||||
busy machines advance at the wrong rate; one call site.
|
||||
3. **Model policy: DeepSeek V4.1 (`deepseek/deepseek-flash`) preferred over V4**, per user
|
||||
guidance; `high` variant for implementers/reviewers, `max` for the final review. *Cost if
|
||||
wrong:* a task or two on a weaker model, with review coverage.
|
||||
4. **Ran the memory-space investigation as a spike, not a plan**, with full Ghidra access —
|
||||
output is an answer plus durable artefacts, not product code. *Cost if wrong:* one
|
||||
worker's time; deliverables additive and write-isolated.
|
||||
5. **Resumed Task 1's implementer on a different model for its fix round** (V4.1 vs its
|
||||
V4 Pro dispatch), keeping session context. *Cost if wrong:* none observed — the
|
||||
re-review found no new breakage.
|
||||
6. **Treated the spike's VRAM finding as inference, not proof**, so the video plan's first
|
||||
task is an *empirical* determination (watchpoint `DPYADR`), not a static one. *Cost if
|
||||
wrong:* one wasted probe.
|
||||
7. **Task 4's flat sweep stands as a successful outcome.** No improvement was claimed and
|
||||
none was fabricated; the negative result is the deliverable.
|
||||
|
||||
## Reviewer findings triaged as acceptable (not fixed, deliberately)
|
||||
|
||||
Thirteen minors were raised across the four tasks; the final review triaged them and
|
||||
required only the three documentation corrections (now fixed). The rest were judged
|
||||
acceptable: write-back latches on non-handshake reads; the handshake matching only the low
|
||||
16 bits; `m_busy_ticks` default 2 -> 0; assorted test-coverage gaps; the unmasked key in
|
||||
`set_window_busy_ticks`; the DMA defaults-off gate being untested; a WIN1 read ignoring the
|
||||
register offset (inert while DMA defaults off); and cosmetic diagnostic wording.
|
||||
|
||||
**Two worth acting on before the next modelling round** (the reviewer's words): mask the
|
||||
key in `set_window_busy_ticks`, and offset-gate the WIN1 DMA read so a WIN1 status bit is
|
||||
not shadowed.
|
||||
|
||||
## Where the goal stands
|
||||
|
||||
This plan deliberately delivered only its slice. `INTENB` still never leaves zero and no
|
||||
frame has been rendered — the spec's success criteria 2 and 3 remain open, to be met by the
|
||||
two named follow-on plans: **video RAM + scanline renderer**, and **DUART / NVRAM / MAC ROM**.
|
||||
|
||||
The spike (`reference/memory-space-map.md`) plus this plan's findings tell the video plan
|
||||
where to start: the framebuffer is not in main RAM, it is set at runtime via `DPYADR`, and
|
||||
the most-touched unmodelled region is `0x5600000` (~110 accesses on the display/X-init path).
|
||||
Reference in new issue
Block a user