diff --git a/harness/mame/DUART_REPORT.md b/harness/mame/DUART_REPORT.md index 23a2a63..379a320 100644 --- a/harness/mame/DUART_REPORT.md +++ b/harness/mame/DUART_REPORT.md @@ -896,3 +896,72 @@ status — minor, not biting; (4) `COUNTER_READY` set at the Start-Counter read **Acceptance:** `HOST PORT - 15` still present. **Regression:** holds (`PC=3FDCE400 samples=199`). + +--- + +# WHO WRITES +0x3c0 / +0x3d0, AND WHAT L3FA71BC0 ACTUALLY CHECKS + +Direct writer evidence from the transparent descriptor-area proxy +(`VT1200_STRUCTLOG`, `hp_struct.log`), not inference: + +``` +W 270C50 pc=3FA79E50 val=0004 / 0005 <- test +0x3c0 = ISR struct[idx4].0x3b0 (SRA snapshot) +W 270C60 pc=3FA7A3C0 val=0004 / 0007 <- test +0x3d0 = ISR index5 SRA snapshot +W 2708F0 pc=3FA796D0 val=0001 / 0021 <- test struct[i].0x60 = ISR struct[i].0x90 (SRA snapshot) +``` + +All three are written by the **DUART ISR `L3FA78D90`**, and only there: + +* `3FA79E30`/`3FA7A3A0` are its **TxRDYA** path (`*a7(0x3b0) = window reg1`) — the + per-index SRA snapshot. So test `+0x3c0` = the snapshot at **index 4** and `+0x3d0` = + the snapshot at **index 5** (the test's descriptor is the ISR's descriptor **+0x30**, so + test `+0x3cN` == ISR `struct[idxN].0x3b0`). Bit 1 = FFULL, bit 4 = OVR. +* `3FA79690` is its **RxRDYA** path (`*a11(0x90) = window reg1`) — the received status for + each character. Test `struct[i].0x60` is exactly that field, which is why the `c6` + comparison sees `0x0001` / `0x0021`. + +**So both sub-tests' failures are the ISR's *SRA snapshots*, and nothing else.** + +## What `L3FA71BC0` checks (my own evidence) + +Broken on all 18 of its flag-set sites (`hp_flags.lua`): **exactly one fires** — `c6`. +The comparison is `3FA73970 btst 5, a9` with `a9 = struct[i].0x60` (the ISR's received +status for character *i*), and `jreq` skips the set — so `c6` is set when **bit 5 is SET**. +SRA bit 5 is **PARITY ERROR**. Observed: `a9 = 0x0001` (no error) in most combinations, +and **`a9 = 0x0021` (= RxRDY | parity error) in 3 combinations**, which are the 3 times +`c6` fires. + +So: + +* `L3FA71BC0`'s remaining failure = a **PARITY ERROR in the received status**, in 3 of its + combinations (the parity-enabled `MR1` settings) — a *status* mismatch, not a timing one. + Its `c5` check (bit 6 = framing error) does **not** fire. +* `L3FA753D0`'s remaining failure = the ISR's index4/index5 snapshots lack **FFULL / OVR** + — a *receive-count* lag. + +These are two different mismatches (one status, one count), both read from SRA by the ISR. +The single mechanism that could produce both is a receive-side mis-sampling/offset: a +sub-bit offset shifts character completion (-> FFULL/OVR missing) and can flip the parity +bit (-> parity error) while leaving the data bits correct (-> the RHRA compares still +pass). That keeps the measured ~1-bit write->receive offset (§ earlier) as the leading +candidate, but the parity error is a new, *testable* consequence of it and should be +checked directly before attributing. + +## Owner's static reading of `L3FA753D0` — verified, with corrections + +Correct on all substantive points (the four checks, the 144 = 4x3x3x4 nested sweep, the +CRA sequence, the per-check flags, and the index record at `+0xc4/c8/ca/cc` on failure). +Two corrections: + +1. The PCs quoted are the **loads** (`3FA76030`, `3FA760C0`, `3FA76190`, `3FA76340`); the + actual comparisons are `3FA76050` (btst 4), `3FA760E0` (btst 1), `3FA761E0` + (andi 0xf0 / subk 16) and `3FA76390` (cmp). +2. Flag bit encoding confirmed: each flag is a **1-bit** field at bit address + `a13 + 0xc0 + N`, so the 32-bit return read gives **bit N = flag `+0xcN`**. Proof: the + `+0xc6` store shows up in the proxy as `W 001E30 pc=3FA739D0 val=0040` — bit 6 of the + word at `a13(0xc0)`. + *Caveat:* the 32-bit read also spans the word at `a13+0xd0` (bits 16-31). For + `L3FA71BC0` the return `0x00900040` has bits 20/23 set from *that* word, i.e. the return + carries adjacent frame data as well as flags — so "return == 0" is stricter than "all + checks pass" unless that word is zero. Worth confirming before treating `L3FA71BC0`'s + return as a pure flag word.