158 lines
6.3 KiB
Markdown
158 lines
6.3 KiB
Markdown
# PT2 Known Button ROM Trace
|
|
|
|
This trace starts from known serial-visible button reports and walks backward into the panel input scanner.
|
|
|
|
Known reports:
|
|
|
|
- `00 00 07 80 00 DD` = selector `0x0007`, value `0x8000`, observed CAM POWER report.
|
|
- `00 00 15 80 00 CF` = selector `0x0015`, value `0x8000`, observed CALL active report.
|
|
- `00 00 15 00 00 4F` = selector `0x0015`, value `0x0000`, observed CALL inactive report.
|
|
|
|
## Shared Button Path
|
|
|
|
CALL and CAM POWER both use the same general panel edge machinery:
|
|
|
|
```text
|
|
external panel byte snapshot
|
|
-> shadow byte F6D*
|
|
-> dirty byte F6F2/F6F3
|
|
-> main scanner loc_15E0
|
|
-> bit dispatcher loc_1C0E
|
|
-> table H'2706
|
|
-> per-button handler
|
|
-> loc_3E54 serial report queue
|
|
```
|
|
|
|
That means the lamps and buttons are not just conceptually related. The ROM reads panel byte shadows and drives panel output masks through the same external panel-chip area, then uses per-button handlers to decide whether a press should become a serial report, a local menu action, or nothing.
|
|
|
|
## CAM POWER
|
|
|
|
Trace:
|
|
|
|
```text
|
|
F105 external/panel byte changes
|
|
-> F6D4 shadow changes
|
|
-> F6F2.4 dirty
|
|
-> loc_1BA0
|
|
-> loc_1C0E table slot H'274C
|
|
-> handler H'1F40
|
|
-> writes E80E
|
|
-> queues selector 0x0007 through loc_3E54
|
|
```
|
|
|
|
Important handler behavior:
|
|
|
|
```text
|
|
1F40: tests F6D4.3
|
|
1F4C: tests E000[0x0007] / E00E bit 15
|
|
1F52: writes E800[0x0007] / E80E = 0x8000
|
|
1F61: can write E80E = 0x0000 when already set and page gate allows
|
|
1F68: R3 = 0x0007
|
|
1F6B: BSR loc_3E54
|
|
```
|
|
|
|
So CAM POWER is a real local button path, not a host-only selector. The handler checks the current button level and local/session gates before emitting.
|
|
|
|
## CALL
|
|
|
|
Trace:
|
|
|
|
```text
|
|
F006 external/panel byte changes
|
|
-> F6DB shadow changes
|
|
-> F6F3.3 dirty
|
|
-> loc_1BF8
|
|
-> loc_1C0E table slot H'27C0
|
|
-> handler H'20A1
|
|
-> writes E82A
|
|
-> queues selector 0x0015 through loc_3E54
|
|
```
|
|
|
|
Important handler behavior:
|
|
|
|
```text
|
|
20A1: reads E000[0x0015] / E02A
|
|
20A5: tests F6DB.5
|
|
20AB: if pressed, sets bit 15
|
|
20AF: if released, clears bit 15
|
|
20B1: writes E800[0x0015] / E82A
|
|
20B7: R3 = 0x0015
|
|
20BA: BSR loc_3E54
|
|
```
|
|
|
|
This cleanly matches the bench readings: CALL has both active and inactive reports because the handler explicitly sets or clears bit 15 from the current button level.
|
|
|
|
## Divergence
|
|
|
|
Other buttons do follow the same input edge path, but many diverge after `loc_1C0E`:
|
|
|
|
- Some handlers are `H'1C25`, an immediate `RTS`, so that matrix position is ignored.
|
|
- Some handlers only change local menu/page state such as `F731`, `F732`, `FB03`, or `F798`.
|
|
- Some handlers queue reports, but only if session/menu gates like `F731`, `F730`, `F791`, or selector bits in `E000/E400` allow it.
|
|
- Several handlers queue different selectors such as `0x0083`, `0x008F`, `0x0093`, `0x009A`, `0x00B9`, `0x00F8`, etc.
|
|
|
|
The generated report `build/panel_button_trace.md` lists the current table-derived map.
|
|
|
|
## Bench Correlation: Common Queue Gate
|
|
|
|
The first common-gate button-report bench set used the queued-report ACK stream that exposed SHUTTER ON/OFF.
|
|
|
|
Confirmed positives:
|
|
|
|
| Physical button | Report selectors/value | ROM match |
|
|
| --- | --- | --- |
|
|
| BARS | `0x0017 = 0x8000`, `0x0018 = 0x8000` | `F105/F6D4.2 -> H'1EDE -> 0x0017/0x0018` |
|
|
| IRIS AUTO | `0x009A = 0x0800` | `F006/F6DB.3 -> H'20BE -> 0x009A` |
|
|
|
|
Common-gate runs for STANDARD, MASTER, SLAVE, KNEE AUTO, and BLACK/FLARE FLARE did not differ from the no-button baseline. That is evidence against one universal "all buttons emit now" gate. Some controls likely need additional menu/session/secondary-table state, or are not represented as simple edge reports in this mode.
|
|
|
|
## F109 Shutter/Menu Cluster
|
|
|
|
A focused trace of the `F109 -> F6D0` input byte found local-key handlers that are close to the OTHERS/shutter/menu machinery:
|
|
|
|
| Source bit | Handler | Behavior |
|
|
| --- | --- | --- |
|
|
| `F6D0.1` | `H'2390` | Queues selector `0x0083`, unless `E000[0x0088].15` diverts to timed page `F732=0x1C01` |
|
|
| `F6D0.2` | `H'2408` | Queues selector `0x0083`, unless `E000[0x0088].15` diverts to timed page `F732=0x1C01` |
|
|
| `F6D0.3` | `H'24A9` | Queues selector `0x0083`, unless `E000[0x0088].15` diverts to timed page `F732=0x1C01` |
|
|
| `F6D0.7` | `H'24E8` | Queues selector `0x008F` with local mask `0x8000` or `0x0000`; `E000[0x0088].14` diverts to timed page `F732=0x1C01` |
|
|
| `F6D0.6` | `H'252E` | Queues selector `0x008F` with local mask `0x2000` or `0x0000`; `E000[0x0088].14` diverts to timed page `F732=0x1C01` |
|
|
| `F6D0.4/F6D0.5` | `H'2574/H'25D4` | Uses selectors `0x0091/0x0092` and modal byte `F6F6`; `E000[0x0088].14` can divert to timed page `F732=0x1C01` |
|
|
|
|
This cluster explains why some adjacent controls may look like menu/display keys rather than ordinary reports. A CCU-side bit in selector `0x0088` can retarget them into a timed local page overlay, currently matching the DETAIL/KNEE neighborhood rather than the OTHERS page.
|
|
|
|
## OTHERS Difference
|
|
|
|
OTHERS page `0x01` is not driven by one of the simple confirmed report handlers above. The page-1 handlers consume low action bits in `F770`:
|
|
|
|
- `H'6EE4` consumes `F770.0/F770.1` for OTHERS/SHUTTER local actions.
|
|
- `H'6FF0` consumes `F770.2` for COPY TO SLAVES.
|
|
- No decoded direct writer for these low bits has been found yet.
|
|
|
|
That is the current best explanation for the bench result where the OTHERS physical press matched the no-button baseline: the shared scanner may see the key, but the useful OTHERS action is gated behind a separate local page/action latch.
|
|
|
|
## Emulator Probe
|
|
|
|
The emulator can inject these as ROM-level panel edges:
|
|
|
|
```powershell
|
|
.\.venv\Scripts\python.exe h8536_emulator_rx_probe.py --wait-heartbeats 1 --panel-press cam-power
|
|
.\.venv\Scripts\python.exe h8536_emulator_rx_probe.py --panel call=press --panel call=release --keep-listening
|
|
.\.venv\Scripts\python.exe h8536_emulator_rx_probe.py --panel F6D4.6=press
|
|
```
|
|
|
|
This is a post-scan injection model. It sets the external source byte, the `F6D*` shadow byte, the matching `F6E*` previous-shadow byte to the opposite bit level, and the `F6F2/F6F3` dirty bit. The ROM then runs its normal `loc_15E0 -> loc_1C0E -> H'2706` dispatch path, so gates and no-op handlers still behave like firmware rather than like forced serial output.
|
|
|
|
## Tooling
|
|
|
|
Regenerate the map with:
|
|
|
|
```powershell
|
|
.\.venv\Scripts\python.exe h8536_panel_button_trace.py
|
|
```
|
|
|
|
Outputs:
|
|
|
|
- `build/panel_button_trace.md`
|
|
- `build/panel_button_trace.json`
|