forked from arti/vt1200
plan: task 4 verified by host unit tests (the driver has no network interface)
This commit is contained in:
1 parent
18b496146b
commit
213083f2e0
1 file changed
+43
-15
@@ -215,38 +215,66 @@ git commit -m "feat(stream): payload skeleton with one startup malloc"
|
||||
|
||||
---
|
||||
|
||||
### Task 4: Two-slot ring with header validation
|
||||
### Task 4: Frame parser and two-slot handling
|
||||
|
||||
**Files:**
|
||||
- Modify: `harness/udpstream/vidstream.c`
|
||||
- Test: `harness/mame/vidstream.lua` (mode `rx`)
|
||||
- Create: `harness/udpstream/frame_parse.c`, `harness/udpstream/frame_parse.h`
|
||||
- Create: `harness/udpstream/tests/test_frame_parse.c`
|
||||
- Modify: `harness/udpstream/vidstream.c`, `harness/mame/vidstream.lua`
|
||||
|
||||
**Interfaces:**
|
||||
- Produces: in-guest counters `RX_OK` (`0x01810030`), `RX_BAD` (`0x01810034`), `RX_LAST_LEN` (`0x01810038`), `RX_SLOT` (`0x0181003C`).
|
||||
- `int fp_parse(const unsigned char *buf, unsigned int len, fp_header *out)` — returns 1 for a
|
||||
valid frame, 0 otherwise; fills `kind, frame_no, rows, stretch, payload_len, payload_off`.
|
||||
- In-guest counters `RX_OK`, `RX_BAD`, `RX_LAST_LEN`, `RX_SLOT` at the byte-aligned marker page.
|
||||
|
||||
- [ ] **Step 1: Write the failing test**
|
||||
**Note (plan amendment, ruling R11):** the MAME driver does **not** attach the LANCE to a host
|
||||
network interface, so no test can hand it Ethernet frames in the emulator. Verification is
|
||||
therefore two-part: (1) `fp_parse` is a plain C function compiled and unit-tested on the host
|
||||
(`gcc -std=c89`), which pins the length/CRC rules; (2) the Lua harness injects a frame directly
|
||||
into a slot and asserts the payload's counters. The real DMA path is proven in Task 7, on the unit.
|
||||
|
||||
In `harness/mame/vidstream.lua` mode `rx`: send one valid frame (80 rows, `S=12`) and one frame whose CRC byte is flipped, via `vidsend.py --fake`. Assert `RX_OK == 1` and `RX_BAD == 1`.
|
||||
- [ ] **Step 1: Write the failing host test**
|
||||
|
||||
- [ ] **Step 2: Run to verify it fails**
|
||||
`tests/test_frame_parse.c`: build a 16-byte header + payload with the same layout `frame.py`
|
||||
writes (magic 'V','S', version 1, kind 1, frame_no, payload_len, rows, stretch, CRC16 at offset
|
||||
12 over bytes 0..11 + payload). Assert `fp_parse` accepts it; flip one payload byte and assert it
|
||||
is rejected; truncate it below `16 + payload_len` and assert rejection; corrupt the magic and the
|
||||
version and assert rejection.
|
||||
|
||||
Run: `VT1200_MODE=rx harness/mame/run-vidstream.sh`
|
||||
Expected: `RX_OK=0 RX_BAD=0 -> FAIL` (nothing parses yet)
|
||||
- [ ] **Step 2: Run it to verify it fails**
|
||||
|
||||
- [ ] **Step 3: Implement slot receive + validation**
|
||||
Run: `cc -std=c89 -Wall -o /tmp/tfp harness/udpstream/tests/test_frame_parse.c harness/udpstream/frame_parse.c`
|
||||
Expected: link error, `fp_parse` undefined.
|
||||
|
||||
Ring of 16 descriptors, two slots of 24 KB at `POOL_PTR` and `POOL_PTR + 24576`; arm 16 descriptors per slot on entry to that slot; on completion compute `bytes = SUM(len)`; accept only if `bytes >= 16`, `magic == 'VS'`, `payload_len + 16 <= bytes`, and `crc16(header[0:12] + payload) == header_crc`. Reject → `RX_BAD++`, re-arm the same slot, no blit.
|
||||
- [ ] **Step 3: Implement `frame_parse.c` / `.h`**
|
||||
|
||||
- [ ] **Step 4: Run to verify it passes**
|
||||
K&R-compatible C89 that also compiles with the 1987 compiler: no `//`, no declarations after
|
||||
statements, CRC16 CCITT-FALSE as in `frame.py`. `fp_parse` checks length first, then magic and
|
||||
version, then CRC over `buf[0..11] + payload`.
|
||||
|
||||
- [ ] **Step 4: Run the host test to verify it passes**
|
||||
|
||||
Run: `cc -std=c89 -Wall -o /tmp/tfp harness/udpstream/tests/test_frame_parse.c harness/udpstream/frame_parse.c && /tmp/tfp`
|
||||
Expected: `frame_parse: N/N ok`.
|
||||
|
||||
- [ ] **Step 5: Wire it into the payload and the MAME harness**
|
||||
|
||||
`vidstream.c` calls `fp_parse` on each completed slot, increments `RX_OK`/`RX_BAD`, and does not
|
||||
blit on rejection. `vidstream.lua` mode `rx` writes a valid frame into slot A and a corrupted one
|
||||
into slot B, sets the payload's "frame ready" word for each, and asserts `RX_OK == 1 && RX_BAD == 1`.
|
||||
|
||||
- [ ] **Step 6: Run the MAME check**
|
||||
|
||||
Run: `VT1200_MODE=rx harness/mame/run-vidstream.sh`
|
||||
Expected: `RX_OK=1 RX_BAD=1 -> PASS`
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
- [ ] **Step 7: Commit**
|
||||
|
||||
```bash
|
||||
git add harness/udpstream/vidstream.c harness/mame/vidstream.lua
|
||||
git commit -m "feat(stream): two-slot rx ring with header and crc validation"
|
||||
git add harness/udpstream/frame_parse.c harness/udpstream/frame_parse.h \
|
||||
harness/udpstream/tests/test_frame_parse.c \
|
||||
harness/udpstream/vidstream.c harness/mame/vidstream.lua
|
||||
git commit -m "feat(stream): frame parser shared by host tests and payload"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Reference in new issue
Block a user