traces
This commit is contained in:
215
docs/pt2-report-aftermath-trace.md
Normal file
215
docs/pt2-report-aftermath-trace.md
Normal file
@@ -0,0 +1,215 @@
|
||||
# PT2 Report Aftermath ROM Trace
|
||||
|
||||
This note tracks what the ROM does after the RCP emits an autonomous serial report from the `F870` report queue.
|
||||
|
||||
## Core Model
|
||||
|
||||
The RCP report path is:
|
||||
|
||||
```text
|
||||
3E54 / 4046 enqueue selector into F870
|
||||
3FD3 checks send gates
|
||||
BAF2 dequeues/stages a report from F870 and E800
|
||||
BA26 sends the six-byte SCI1 frame
|
||||
BB46-BB51 arms the continuation/resend aftermath
|
||||
```
|
||||
|
||||
The important consequence is that `BAF2` does not advance the report consumer cursor. The emitted report remains outstanding until the host sends a valid continuation command.
|
||||
|
||||
## Report Queue
|
||||
|
||||
| RAM | Role |
|
||||
| --- | --- |
|
||||
| `F870` | autonomous serial-report word ring |
|
||||
| `F9B0` | producer cursor |
|
||||
| `F9B5` | consumer/outstanding cursor |
|
||||
|
||||
Producer paths:
|
||||
|
||||
- `H'3E54`: when `R2.7` is set, deduplicates and appends `R3` to `F870`, then advances `F9B0`.
|
||||
- `H'4046-H'4070`: when heartbeat/report cadence expires and the report queue is empty, appends selector `0x0000` to `F870`.
|
||||
|
||||
Consumer path:
|
||||
|
||||
- `H'BAF2` compares `F9B5` against `F9B0`.
|
||||
- If equal, no report is pending.
|
||||
- If different, it reads selector `F870[ F9B5 ]`, reads the report value from `E800[selector]`, stages the outgoing frame, and calls `BA26`.
|
||||
- `BAF2` leaves `F9B5` unchanged.
|
||||
|
||||
Only continuation command `4`, `5`, or `6` advances `F9B5`, and only when `FAA2.3` is still set.
|
||||
|
||||
## Report Send Gates
|
||||
|
||||
`H'3FD3` allows `BAF2` only when:
|
||||
|
||||
- `FAA2 == 0`.
|
||||
- `F9C0 == 0`.
|
||||
- If `FAA5.7` is set, `F9C3 == 0`, meaning no partial RX frame is currently being assembled.
|
||||
|
||||
This means host RX traffic can block report sending while a session is active.
|
||||
|
||||
## Aftermath Window
|
||||
|
||||
After `BA26` sends the report frame, `H'BB46-H'BB51` arms the report aftermath:
|
||||
|
||||
| Address | Write | Meaning |
|
||||
| --- | --- | --- |
|
||||
| `H'BB00` | set `FAA2.3` | queued report needs continuation |
|
||||
| `H'BB46` | `F9C6 = 0x01F4` | resend spacing countdown |
|
||||
| `H'BB4C` | `F9C8 = 0x14` | resend/retry budget |
|
||||
| `H'BB51` | `FAA3 = 0x80` | live resend/window marker |
|
||||
|
||||
While this is live, valid RX frames enter the continuation dispatcher because `FAA2 != 0`.
|
||||
|
||||
## Clean Continuation Consume
|
||||
|
||||
Commands `4`, `5`, and `6` all share the same report-consume pattern:
|
||||
|
||||
```text
|
||||
if FAA2.3 set:
|
||||
F9B5 += 1
|
||||
clear F9B5.7
|
||||
clear FAA3
|
||||
clear FAA2
|
||||
```
|
||||
|
||||
Handler addresses:
|
||||
|
||||
| Command | Handler | Consume block |
|
||||
| --- | --- | --- |
|
||||
| `4` | `H'BD0E` | `H'BD67-H'BD79` |
|
||||
| `5` | `H'BD80` | `H'BDC2-H'BDD4` |
|
||||
| `6` | `H'BDDB` | `H'BDED-H'BDFF` |
|
||||
|
||||
The ROM does not appear to require the continuation ACK selector to match the emitted report selector. The consume test is `FAA2.3`, not selector equality.
|
||||
|
||||
## Non-Clean Paths
|
||||
|
||||
Low commands `0/1/2/3` while `FAA2.3` is live:
|
||||
|
||||
- `H'BC5C` clears `FAA2.3`.
|
||||
- If the bit was set, `H'BC63` clears `FAA3`.
|
||||
- `H'BC67` re-enters initial dispatch.
|
||||
- This does not advance `F9B5`.
|
||||
|
||||
Command `7`:
|
||||
|
||||
- Retransmits the previous finalized TX frame through `H'BE05-H'BE25`.
|
||||
- Does not clear `FAA2/FAA3`.
|
||||
- Does not advance `F9B5`.
|
||||
|
||||
TX/RX overlap interlock:
|
||||
|
||||
- At `H'BA84-H'BAA7`, TXI checks `FAA2.3 && FAA5.7 && F9C3 != 0`.
|
||||
- If true, it clears `FAA2.3`, clears `FAA3`, disables TXI, and loads `F9C0=0x1F`.
|
||||
- This collapses the report window without consuming `F9B5`.
|
||||
- Bench implication: starting a host frame before the RCP has finished TX can destroy the very continuation window being targeted.
|
||||
|
||||
## Resend And Expiry
|
||||
|
||||
`H'BE9E-H'BEE8` manages the unconsumed report aftermath:
|
||||
|
||||
- Masks `FAA3` with `FAA5.7`.
|
||||
- If the session gate is gone, `FAA3` becomes zero and `FAA2` is cleared.
|
||||
- If `FAA3.7` is live and `F9C6 != 0`, it waits.
|
||||
- If `F9C6 == 0` and `F9C8 != 0`, it decrements `F9C8`, reloads `F9C6=0x01F4`, clears `F9C3`, and calls `BA26` to resend the same finalized frame.
|
||||
- If `F9C8 == 0`, it clears `F9C5`, forcing the broader session timeout path.
|
||||
|
||||
So an unconsumed report can be resent repeatedly, then eventually force the session watchdog to expire.
|
||||
|
||||
## Session Timeout
|
||||
|
||||
`F9C5` is the broad active-session watchdog:
|
||||
|
||||
- A complete six-byte RX frame reloads `F9C5=0x14` at `H'BB9E`.
|
||||
- FRT2 decrements `F9C5` at `H'BF31-H'BF37`.
|
||||
- `H'3FEF` observes expiry, clears `F9B5/F9B0`, clears `FAA5.7`, and if the gate was previously live calls `H'400C`.
|
||||
- `H'400C -> H'4075 -> H'4217` clears broad session/display state and redraws `CONNECT:NOT ACT`.
|
||||
|
||||
Related timers:
|
||||
|
||||
| RAM | Role |
|
||||
| --- | --- |
|
||||
| `F9C0` | post-TX/report-send gate; decremented by FRT1 |
|
||||
| `F9C1` | RX inter-byte timer; partial-frame timeout |
|
||||
| `F9C4` | heartbeat/report enqueue cadence |
|
||||
| `F9C5` | active serial-session watchdog |
|
||||
| `F9C6/F9C8` | unconsumed report resend spacing/budget |
|
||||
|
||||
## Fake-CCU Implications
|
||||
|
||||
Best pure report ACK:
|
||||
|
||||
```text
|
||||
05 00 40 00 00 1F
|
||||
```
|
||||
|
||||
Rationale:
|
||||
|
||||
- Command `5` consumes the report cursor when `FAA2.3` is live.
|
||||
- Selector `0x0040` is not one of the known command-5 special side-effect selectors.
|
||||
- Value bytes are ignored by the generic command-5 consume path.
|
||||
|
||||
Same-selector command-5 ACKs are plausible for human readability, but not ROM-required:
|
||||
|
||||
```text
|
||||
05 00 00 00 00 5F ; ACK selector 0x0000
|
||||
05 00 02 00 00 5D ; ACK selector 0x0002
|
||||
05 00 07 00 00 58 ; ACK selector 0x0007
|
||||
05 00 15 00 00 4A ; ACK selector 0x0015
|
||||
05 01 0F 00 00 51 ; ACK selector 0x008F
|
||||
```
|
||||
|
||||
Use command `4` only when the host intentionally wants to refresh primary/current state while consuming:
|
||||
|
||||
```text
|
||||
04 00 00 80 00 DE ; selector-zero active refresh
|
||||
```
|
||||
|
||||
Use command `6` only when the host intentionally wants to refresh secondary feature gates while consuming:
|
||||
|
||||
```text
|
||||
06 00 15 00 01 48 ; E400[0x0015] = 1
|
||||
06 01 0F 18 00 4A ; E400[0x008F] = 0x1800
|
||||
```
|
||||
|
||||
Avoid command-5 special selectors as generic ACKs unless the side effect is desired:
|
||||
|
||||
```text
|
||||
05 00 6C 00 00 33 ; COPY completion/exit sibling
|
||||
05 00 6D 00 00 32 ; COPY IN PROGRESS/start
|
||||
05 00 6E 00 00 31 ; special accepted, later handler is cleanup/no-op-like
|
||||
```
|
||||
|
||||
## Proposed Normal Loop
|
||||
|
||||
A plausible fake-CCU report loop is:
|
||||
|
||||
1. Keep the serial format at `38400 8E1`.
|
||||
2. Seed active state, especially selector zero.
|
||||
3. Listen for a complete RCP TX frame.
|
||||
4. Wait until the RCP frame is fully transmitted.
|
||||
5. Quickly send a command-5 generic ACK before `F9C6/F9C8` resend handling starts.
|
||||
6. Continue sending enough valid six-byte frames to reload `F9C5` before session expiry.
|
||||
7. Add command-4/command-6 state refreshes only when we intentionally want to update lamps, displays, or menu gates.
|
||||
|
||||
This is the current best ROM-supported path for maintaining `CONNECT: OK` without accidentally consuming the report incorrectly or triggering COPY/menu side effects.
|
||||
|
||||
## Emulator Check
|
||||
|
||||
Reactive emulator testing supports this model:
|
||||
|
||||
- Seeded active state with command `0`, selector zero value `0x8080`.
|
||||
- Waited for a report window where `FAA2.3` and `FAA3.7` were set and SCI1 TXI was idle.
|
||||
- Sent `05 00 40 00 00 1F`.
|
||||
- The ACK path reached the command-5 consume block and advanced `F9B5`, then cleared `FAA3` and `FAA2`.
|
||||
- Repeating that reactive loop 12 times kept the emulated LCD at `CONNECT: OK`.
|
||||
|
||||
Observed clean consume shape after each ACK:
|
||||
|
||||
```text
|
||||
before: FAA2=08 FAA3=80 F9B5=N
|
||||
after: FAA2=00 FAA3=00 F9B5=N+1
|
||||
```
|
||||
|
||||
A fixed-delay or extra-guard strategy was less reliable. In one run, waiting an additional 1 ms after TX idle before sending the ACK only consumed two reports before falling back to `CONNECT:NOT ACT`. That result should not be overfit as an exact real-device limit, but it reinforces the ROM timing lesson: ACK as a reaction to a finished frame, not as a loose periodic delay.
|
||||
Reference in New Issue
Block a user