Rewrite the README as a description, and strike a unit error it exposed

The README had become a changelog: which session found what, which constant was
retired and by whom, which figure was overturned. That is what STATUS is for,
and it made the front page a poor read for anyone who has not been following.
Rewritten to say what the project is, what it looks like, where it stands and
how to reproduce it, present tense, no session numbers, no em dashes.

Restating the standing facts caught one of my own from this session. FINDINGS
52.5 cited 42.4's W sensitivity table -- W <= 6 fits 0/120 frames, W = 8 misses
47/120 -- as though those were clocks per BYTE. They are per WORD. FINDINGS 43
is the section that caught W being charged per word to a byte-wide port and says
in terms that 42.3's 0/120 was never physically reachable, so quoting it in byte
units re-imported the exact 2x error 43 exists to have corrected, one section
after using that same trap as a warning.

Struck in 52.5 and in ROADMAP P4, and replaced with the ladder buscost.py
already carries, which is in the right unit: 5 clk/B single address with the bus
held, 9 dual address held, 12 single address arbitrated per byte, 16..19 dual
address arbitrated per byte, the last being what the IPL ROM programs. Nothing
else in 52 depended on the struck figures -- 15_bus_occupancy.py's sweep is in
byte units and is unaffected.

The "cross-check" claim goes with it. 52.5 read the agreement between its W = 8
row and 42.4's 47/120 as two independent models landing in the same place. It is
two different units on two different containers at two different rates, and
calling it corroboration was manufacturing agreement out of the unit error.

What replaces "W <= 12 is a requirement on the player's DMAC programming" is the
sharper version: getting the DMAC to HOLD THE BUS is what separates 9 from 19,
and that is the thing P4 has to demonstrate.

Docs only; no code changed and no gate output moves.

Claude-Session: https://claude.ai/code/session_01194oWYW8DQXK1SZ2DnChW6
This commit is contained in:
prosolis
2026-08-24 18:30:42 -07:00
parent e565dfbbab
commit ed172c2da2
3 changed files with 266 additions and 282 deletions
+30 -11
View File
@@ -4407,11 +4407,27 @@ without hold, external request.** Byte by byte, full arbitration each time. ch0
identically, and by 52.2's arithmetic that is **16..19 clocks per delivered
byte**.
FINDINGS 42.442.6 brackets W, the clocks stolen per delivered byte, at **5..12**,
and reports that **W ≤ 6 fits 0/120 frames while W = 8 misses 47/120**. The only
worked example of a disk DMA configuration on this machine sits **above the
entire bracket.** `15_bus_occupancy.py` now sweeps it on the gate container
(37,403 B/frame, measured mean decode 570,958 clocks):
**A CORRECTION TO THIS SECTION AS FIRST WRITTEN, made in the same session.**
It cited 42.4's sensitivity table — `W <= 6` fits 0/120 frames, `W = 8` misses
47/120 — as though those figures were in clocks per BYTE. **They are per WORD,
and FINDINGS 43 voided them**: 43 is the section that caught `W` being charged
per word to a byte-wide port, and it says in terms that 42.3's 0/120 was never
physically reachable. Quoting them here would have re-imported the exact 2x unit
error 43 exists to have corrected, one section after using the same trap as a
warning. They are struck, and nothing below depends on them.
In the corrected unit the ladder is a per-byte cost of the DMAC's own
configuration, and it is the ladder `buscost.py` already carries:
| configuration | clk/byte |
|---|---:|
| single address, bus held | 5 |
| dual address, bus held | 9 |
| single address, arbitrated per byte | 12 |
| **dual address, arbitrated per byte — what the ROM programs** | **16..19** |
`15_bus_occupancy.py` sweeps it on the gate container (37,403 B/frame, measured
mean decode 570,958 clocks):
| W clk/B | video clk/frame | % of frame | CPU + audio + video |
|---:|---:|---:|---:|
@@ -4421,18 +4437,21 @@ entire bracket.** `15_bus_occupancy.py` now sweeps it on the gate container
| **16** | 598,455 | 71.8% | **141.6%** |
| **19** | 710,666 | 85.3% | **155.0%** |
The W = 8 row agreeing with 42.5's "misses 47/120" is a cross-check, not a new
result — two models of the same machine, one built from mode histograms and one
from bus clocks, landing in the same place.
**This table is the statement, and it is not corroborated by 42.4.** The
resemblance between the `W = 8` row here and 42.4's 47/120 is a coincidence of
two different units on two different containers at two different rates, and
calling it a cross-check — as this section did when first written — was
manufacturing agreement out of a unit error.
**This does not close B3.** `scsiexrom.bin` drives an MB89352, not the SASI
port, and a different ROM may configure it differently. What changed is the
prior and the framing: 42.6 says the handshake "is ours to choose, not to
receive", and that is still true — but **nothing in this tree has shown a
cheaper configuration is reachable for an explicitly-addressed 8-bit port, and
the vendor's own answer is the expensive one.** W ≤ 12 is a *requirement on the
player's DMAC programming*, not a range the hardware hands us. It is now the
largest open number in the project, ahead of the rate.
the vendor's own answer is the expensive one.** Holding the bus, which is what
separates 9 from 16..19, is a *requirement on the player's DMAC programming*
rather than a range the hardware hands us. It is now the largest open number in
the project, ahead of the rate.
### 52.6 Audio outranks the disk at the arbiter
CPR: FDC 0, **ADPCM 1**, SASI 2, `_DMAMOVE` 3 — lower is higher priority. With
+11 -5
View File
@@ -27,7 +27,7 @@ these units:
| **68000 clocks** | measured, and the rate controller binds on them. |
| **Delivery rate** | **no working figure, deliberately** (FINDINGS 50, USER DECISION). Every tool REQUIRES an explicit rate. |
| **Seek time** | **no figure at all, and never had one.** 51.3/51.4 made it matter. |
| **W, clocks stolen per delivered byte** | bracketed 5..12 (42.4); the IPL ROM's own disk channel is **16..19** (52.5). **The largest open number in the project.** |
| **W, clocks stolen per delivered byte** | 5 single-address held, 9 dual held, 12 single arbitrated; the IPL ROM's own disk channel is **16..19** (52.5). **The largest open number in the project.** |
---
@@ -122,12 +122,18 @@ receive** (FINDINGS 42.4-42.6). B3 informs it.
**Session 20 promoted this to the project's biggest open number.** FINDINGS 52.5
found the only worked example of a disk DMA configuration on this machine — the
IPL ROM's own — sitting at 16..19 clk/B, outside the bracket entirely, where the
whole design fails at any container size (`15_bus_occupancy.py` sweeps it).
`W <= 12` is now a **requirement on the player's DMAC programming**, not a range
the hardware hands us, and demonstrating a configuration that meets it is P4's
IPL ROM's own — sitting at **16..19 clk/B**, where the whole design fails at any
container size (`15_bus_occupancy.py` sweeps it). The per-byte ladder is 5 clk/B
single-address with the bus held, 9 dual-address held, 12 single-address
arbitrated, 16..19 dual-address arbitrated. **Getting the DMAC to hold the bus
is the difference between 9 and 19**, it is a property of how the player
programs the channel, and demonstrating a configuration that does it is P4's
first job rather than its last.
**Do not quote 42.4's `W <= 6` / `W = 8` sensitivity table for this.** It is in
clocks per WORD and FINDINGS 43 voided it; 52.5 cited it in byte units when
first written and strikes it.
**P5. Seek and branch.** Per-record index (the `aligned` producer needs one
anyway, 49.3), prefill policy, and the accumulated-slack rule from 51.3 made
explicit in the player rather than implied by the rig.