NETWORK_REPORT: confirmed on real silicon -- lance_fixlen works, loopback completes

Panel read off the VT1200 after loading lance_fixlen.coff (via
dwt/loader/hostload.py): CSR0=0x7B3, TMD1=0x8300, RMD1=0x0300 (OWN clear,
STP|ENP), MCNT=0x001C, ok=1 -- byte-identical to the MAME reference
(0x7B3/0x8300/0x0300/0x1C/1).

So the firmware's init/ring/descriptor/TDMD sequence is confirmed on the
machine, and the earlier failure (CSR0=0x1BB, TMD1=0x8338, no RX) was the
payload's descriptor-length encoding: the field must be -len (0xFFE8/0xFA0A),
which MAME masked via get_buf_length()'s 0xF000 OR.

Also records that the payload kills the network while it runs (results are
panel-only) and that the give-the-chip-back block did not restore it.
This commit is contained in:
arti committed 2026-10-30 15:45:30 +02:00
1 parent a4ed68c0e4
commit 53ff57fe45
1 file changed
+53
+53
View File
@@ -4147,3 +4147,56 @@ is its third instruction. The mapping row should therefore be
The remaining honest caveat: for the fourteen entries marked firmware-specific
in 60.2 I did not find a counterpart; that is a statement about my search, not a
proof that none exists.
## 61. CONFIRMED ON REAL SILICON: the corrected payload works
`harness/udpstream/build/lance_fixlen.coff` was loaded on the VT1200 (via
`dwt/loader/hostload.py` over rdebug) and its panel read off the screen. The
panel encoding is `bits16()`: 16 blocks, left to right = bit 0..15, white = 1.
| panel row | y | white blocks | decoded | meaning |
|---|---|---|---|---|
| 1 | 670 | 1,2,5,6,8,9,10,11 | `0x7B3` | CSR0 after the TDMD kick |
| 2 | 700 | same | `0x7B3` | CSR0 sampled later |
| 3 | 730 | 9,10,16 | `0x8300` | TMD1 (OWN still set at the sample) |
| 4 | 760 | 9,10 | **`0x0300`** | **RMD1: OWN clear, STP\|ENP** |
| 5 | 790 | 3,4,5 | **`0x001C`** | **MCNT = 28 bytes** |
| 6 | 850 | (none) | — | TX-done indicator dark (TMD1.OWN still set) |
| 7 | 850 | 1st | **ok = 1** | payload bytes intact at the RX buffer +12 |
The five boxes down the left edge are `dot(0..4)`, the payload's progress marks;
all five lit means it reached the RX-completion call.
### 61.1 The result equals the MAME reference
```
MAME lance.coff: csr0=0x7B3 ok=1 rmd1=0x0300 mcnt=0x1C txmd1=0x8300
real lance_fixlen: csr0=0x7B3 ok=1 rmd1=0x0300 mcnt=0x1C txmd1=0x8300
```
`ok` is computed only if the received buffer still holds the transmitted pattern
(`0x88 0xB5 0xDE` at offset 12), so this is a **complete loopback through the
chip** on the machine, not merely a descriptor status.
### 61.2 What that settles
* The firmware's hardware-driving sequence is confirmed on real silicon: init
block, CSR1/CSR2/CSR3, `INIT`, `IDON`, `STRT`, ring arming, descriptor format,
`TDMD` — all of it behaves as the model and the disassembly said.
* The earlier on-machine failure (`CSR0 = 0x1BB`, `TMD1 = 0x8338`, no receive)
was **the payload's descriptor-length encoding**, exactly as section 50
diagnosed: the field must be the two's complement (`-len`, i.e. `0xFFE8` /
`0xFA0A`), and MAME hid the bug by ORing `0xF000` in `get_buf_length()`.
* `TMD1 = 0x8300` (OWN set) in both MAME and on the machine is a sampling
artefact of this payload, not a failure: transmit completion is proven by
`RMD1` (OWN clear), `MCNT = 28` and `ok = 1`.
### 61.3 Operational note
The payload re-initialises the LANCE, so the terminal's network stack dies while
it runs — the rdebug connection used to load it is lost, and the results are only
observable on the panel (or in memory if the machine is still up). The
`lance_restore.c` variant adds a "give the chip back to the OS" block (re-program
CSR1/CSR2 from `0x23E7A0`, `INIT`, poll `IDON`, `STRT|INEA`), but on this run it
did not bring the network back; the unit needed a power cycle. Fixing that is
open work, not a blocker for the result above.