6.3 KiB
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= selector0x0007, value0x8000, observed CAM POWER report.00 00 15 80 00 CF= selector0x0015, value0x8000, observed CALL active report.00 00 15 00 00 4F= selector0x0015, value0x0000, observed CALL inactive report.
Shared Button Path
CALL and CAM POWER both use the same general panel edge machinery:
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:
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:
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:
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:
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 immediateRTS, so that matrix position is ignored. - Some handlers only change local menu/page state such as
F731,F732,FB03, orF798. - Some handlers queue reports, but only if session/menu gates like
F731,F730,F791, or selector bits inE000/E400allow 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'6EE4consumesF770.0/F770.1for OTHERS/SHUTTER local actions.H'6FF0consumesF770.2for 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:
.\.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:
.\.venv\Scripts\python.exe h8536_panel_button_trace.py
Outputs:
build/panel_button_trace.mdbuild/panel_button_trace.json