# 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`