# PT2 Menu State Machine

This is a focused reference for the ROM menu/display selection machinery that drives LCD pages and panel soft-key activity.

## Page Dispatch

Primary display selector:

- `F732` holds the current display/page selector.
- The high byte of `F732` selects a page wrapper through `493E`.
- The low byte is used as a page-local substate/selection, commonly through `F733`.

Important dispatcher:

- `48FA` bridges table/report state into LCD page dispatch.
- `493E[page]` points at a wrapper.
- Wrappers pass a local table pointer to `5FD2`.

For COPY status:

- `F732=H'1903` selects page `0x19`, substate `0x03`, `COPY IN PROGRESS`.
- `F732=H'1904` selects page `0x19`, substate `0x04`, `COPY COMPLETED`.

For OTHERS:

- `493E[0x01] -> H'631C`.
- Local table `H'632E` includes the OTHERS pages.

## Local Entry Selection

`loc_5FD2` is the local menu chooser.

Important RAM:

| RAM | Role |
| --- | --- |
| `F72C` | visible/selectable entry bitmask |
| `F72E` | count of visible/selectable entries |
| `F72F` | cached page high byte |
| `F733` | selected local entry index |
| `FB03.7` | no-entry/error/display suppression flag |
| `FB02` | display/session timer or message timer |

Observed algorithm shape:

1. If the page changed, clear `F72C/F72E` and cache the new page in `F72F`.
2. Walk the page-local handler table from the last entry down.
3. For each handler, read descriptor words immediately before the handler.
4. Compare the entry state descriptor against `F731`.
5. If the entry has required selector descriptors, test `E400 + selector*2`.
6. If requirements pass, set the entry bit in `F72C` and increment `F72E`.
7. Clamp or reset `F733` so it points at a visible entry.
8. If no entries are visible, set `FB03.7`, set `FB02=H'14`, clear `F72F`, and return `R4=H'FFFE`.

Practical meaning:

- A page can exist in ROM but be invisible/inactive until the CCU seeds the right `E400` feature/status selector.
- Command 6 writes the `E400-E7FF` secondary table, but only on the continuation side of the protocol.

## OTHERS / COPY TO SLAVES Gates

OTHERS page map:

| Local entry | Handler | Visible text | Required secondary selector |
| --- | --- | --- | --- |
| 1 | `H'6FF0` | `OTHERS` / `COPY TO SLAVES` | `E400[0x0015] != 0` |
| 2 | `H'70F6` | `OTHERS` / `CAM ID SET` | `E400[0x0043] != 0` |
| 3 | `H'7188` | `OTHERS` / `CAM ID IND` | `E400[0x0037] != 0` |
| 4 | `H'7258` | `OTHERS` / `CAM BARS` | `E400[0x0038] != 0` |
| 5-6 | `H'7328/H'73D8` | marker/percentage pages | `E400[0x0027] != 0` |

COPY TO SLAVES local action gate:

- Handler `H'6FF0` watches `F770.2`.
- If `F770.2` is clear, it only displays the OTHERS/COPY page.
- If `F770.2` is set and `F791.7` is set, it enters the local copy-start branch.
- If `F770.2` is set and `F791.7` is clear, it diverts to `SET RCP` / `MASTER`.

Root OTHERS soft-key bits:

- Root handler `H'6EE4` tests `E000[0x008F]` at `H'E11E`.
- Bit 11 sets `F711.6`.
- Bit 12 sets `F711.4`.

These bits are not only OTHERS soft-key enables. Bench tests show `E000[0x008F]` directly changes the shutter seven-segment display and iris AUTO lamp, so treat it as a packed camera/display status selector that also feeds the OTHERS root handler.

## Button / Lamp Masks

Important RAM:

| RAM | Role |
| --- | --- |
| `F711-F718` | panel output masks used by external panel chips |
| `F711.4-F711.7` | soft-key/menu-related bits seen around OTHERS/COPY |
| `F726` | countdown that temporarily preserves some soft-key bits |
| `F770` | local panel action/change code |

Relevant ROM behavior:

- Init clears `F711-F717` and sets `F718=H'FF`.
- `5A7A` clears `F711.4-F711.7` if `F726 == 0`.
- The FRT timer path decrements `F726`; when it expires, it clears `F713.6` and `F711.4-F711.7`.
- The OTHERS/COPY branch sets `F711.7` and `F726=H'64` to keep the local key/display state alive briefly.

## OTHERS Action Latch Trace

The missing OTHERS mechanism appears to be `F770`, not another simple command-0 selector.

Root OTHERS/SHUTTER handler `H'6EE4`:

- Reads `F770`, clears it, and only keeps low bits `0x01/0x02`.
- If the first action path is present and `E400[0x008F].11` is enabled, writes `E800[0x008F]=0x0800` and queues selector `0x008F`.
- If the second action path is present and `E400[0x008F].12` is enabled, writes `E800[0x008F]=0x1000` and queues selector `0x008F`.

COPY TO SLAVES handler `H'6FF0`:

- Reads `F770`, clears it, and only keeps bit `0x04`.
- If `F770.2` is clear, it only displays the OTHERS/COPY page.
- If `F770.2` is set and `F791.7` is set, it enters the local copy-start branch.
- If `F770.2` is set and `F791.7` is clear, it diverts to `SET RCP` / `MASTER` and stages restore selector `F734=0x0101`.

Static direct writers found so far only write high bits into `F770`:

| Writer family | Value | Meaning candidate |
| --- | --- | --- |
| `H'4394` | `0x80` | value/dial page redraw or change latch |
| `H'4457` | `0x40` | value/dial page redraw or change latch |
| `H'451A` | `0x20` | value/dial page redraw or change latch |

No decoded direct instruction has been found that writes `F770=0x01`, `0x02`, or `0x04`.

Updated interpretation:

- `E000[0x008F]` and `E400[0x0015]` can make OTHERS-adjacent UI state visible, but they do not synthesize the local OTHERS action.
- The physical OTHERS/COPY/menu action likely arrives through a separate local key latch or indirect panel-chip path that produces the low `F770` bits only when the page machinery is in the right context.
- Pressing OTHERS under the generic queued-report gate can therefore legitimately produce no new serial report.

## Adjacent F109 Menu/Shutter Key Trace

A focused trace of the `F109 -> F6D0` local-key handlers found a neighboring menu/shutter cluster. These are useful context because they share the same local-page style, but they do not directly prove the OTHERS low-bit latch.

| Source bit | Handler | Selector/page effect |
| --- | --- | --- |
| `F6D0.7` | `H'24E8` | Writes `E800[0x008F]=0x8000` or `0x0000`; if `E000[0x0088].14` is set, diverts to timed page `F732=0x1C01` |
| `F6D0.6` | `H'252E` | Writes `E800[0x008F]=0x2000` or `0x0000`; if `E000[0x0088].14` is set, diverts to timed page `F732=0x1C01` |
| `F6D0.4/F6D0.5` | `H'2574/H'25D4` | Uses selectors `0x0091/0x0092` and modal byte `F6F6`; if `E000[0x0088].14` is set, diverts to timed page `F732=0x1C01` |
| `F6D0.1/F6D0.2/F6D0.3` | `H'2390/H'2408/H'24A9` | Uses selector `0x0083`; if `E000[0x0088].15` is set, diverts to timed page `F732=0x1C01` |

`F732=0x1C01` is in the DETAIL/KNEE neighborhood seen in earlier traces, not the OTHERS page `0x01`. This suggests selector `0x0088` can retarget adjacent local keys into a timed menu overlay, while OTHERS itself still depends on the page-1 wrapper and the `F770` low-bit action latch.

## Bench Implications

To make the local COPY path available from the panel, the fake CCU probably needs to:

1. Recover to a live `CONNECT: OK` style session.
2. Seed root OTHERS soft-key bits:

```text
00 01 0F 18 00 4C  ; E000[0x008F] bits 11+12
```

3. During a live continuation/report window, seed the COPY page visibility bit:

```text
06 00 15 00 01 48  ; E400[0x0015] nonzero
```

4. Still satisfy the `F791.7` local copy-start gate.

The current hardest unknown is step 4: the ROM uses `F791.7` in several places, but the source that sets it has not yet been identified.

## Bench Observation: OTHERS Gate Probe

Run:

```text
00 00 00 80 00 DA  ; recover/seed CONNECT OK
00 01 0F 18 00 4C  ; E000[0x008F] = 0x1800
06 00 15 00 01 48  ; E400[0x0015] = 0x0001, sent in active window
```

Observed on the real panel without touching the controls:

- LCD stayed at `CONNECT: OK`.
- SHUTTER seven-segment display changed to something like `EUS`; manuals make this likely `EVS` rendered on a seven-segment display.
- Iris AUTO lamp illuminated.
- OTHERS menu did not appear by itself.

Interpretation:

- The sequence reached real UI state, not only serial parser state.
- `E000[0x008F]=0x1800` is now a candidate shutter/mode-status value as well as an OTHERS soft-key source. Treat the earlier "soft-key bits" interpretation as incomplete.
- `E400[0x0015]=0x0001` may be the OTHERS/COPY visibility bit, but it may also affect an iris/auto feature path. Isolate before assigning a final meaning.

Recommended isolation probes:

```text
00 01 0F 08 00 5C  ; E000[0x008F] bit 11 only
00 01 0F 10 00 44  ; E000[0x008F] bit 12 only
00 01 0F 18 00 4C  ; E000[0x008F] bits 11+12
06 00 15 00 00 49  ; E400[0x0015] clear/zero
06 00 15 00 01 48  ; E400[0x0015] low nonzero
06 00 15 80 00 C9  ; E400[0x0015] high nonzero
```

Scenario files:

- `scenarios/others-isolate-008f-bit11.json`
- `scenarios/others-isolate-008f-bit12.json`
- `scenarios/others-isolate-008f-bits11-12.json`
- `scenarios/others-isolate-e400-0015-low.json`
- `scenarios/others-isolate-e400-0015-high.json`
- `scenarios/others-isolate-008f-then-e400-clear.json`

Isolation results:

| Scenario | Visible panel result | Serial result |
| --- | --- | --- |
| `others-isolate-008f-bit11` | Iris AUTO lamp on, SHUTTER seven-segment shows observed `EUS`, likely manual `EVS` | `04 01 0F 08 00 58`, then repeated `02 00 02 00 00 5A` |
| `others-isolate-008f-bit12` | Iris AUTO lamp on, SHUTTER seven-segment shows literal letters `OFF` | `04 01 0F 10 00 40`, then repeated `02 00 02 00 00 5A` |
| `others-isolate-008f-bits11-12` | Iris AUTO lamp on, SHUTTER seven-segment shows observed `EUS`, likely manual `EVS` | `04 01 0F 18 00 48`, then repeated `02 00 02 00 00 5A` |
| `others-isolate-e400-0015-low` | LCD stays `CONNECT: OK` only | repeated `01 00 02 00 00 59` after command 6 |
| `others-isolate-e400-0015-high` | LCD stays `CONNECT: OK` only | repeated `01 00 02 00 00 59` after command 6 |
| `others-isolate-008f-then-e400-clear` | Iris AUTO lamp on, SHUTTER seven-segment shows observed `EUS`, likely manual `EVS` | repeated `01 00 02 00 00 59` after command 6 |

Updated interpretation:

- `E000[0x008F]` directly affects visible shutter/iris UI state.
- Bit 11 selects the observed `EUS` shutter display, probably manual `EVS`; bit 12 selects literal shutter-display text `OFF`; when both are present, the likely `EVS` display appears to win.
- The iris AUTO lamp turns on for either bit 11 or bit 12, so it may be tied to the same status selector or to the resulting display mode.
- `E400[0x0015]` does not visibly change the panel by itself, even though command 6 does alter the report stream from `02 00 02 00 00 5A` to `01 00 02 00 00 59`.
- Keep `E400[0x0015]` as a probable OTHERS/COPY visibility/report-gate candidate, but do not assign the shutter/iris effect to it.

Manual correlation:

- The RCP-TX7 operating instructions list `OTHERS (1/6: SHUTTER)` with an `EVS` button, and say to use the shutter block `C.SCAN` or `SHUTTER ON/OFF` buttons when not using EVS.
- The same RCP-TX7 manual lists `EVS/ECS` under OTHERS for DXC-D30/D30P normal settings.
- A later CCU/RCP manual states that when EVS is on, `EVS` is displayed; when the shutter switch is off, `OFF` is displayed.
- Therefore `E000[0x008F].11` is best labeled `shutter_evs_display_or_mode`, and `E000[0x008F].12` is best labeled `shutter_off_display_or_mode` until ROM traces split display-only status from actual camera setting.

## Bench Observation: OTHERS Common-Gate Button Press

After the queued-report button tests found BARS and IRIS AUTO reports, the physical OTHERS button was tested with the same common queue-service gate.

Result:

- `button-common-OTHERS-result.json` matched `button-common-baseline-result.json`.
- No extra ACK-target frames appeared.
- The queued selector stream still included baseline selector `0x0015 = 0x0000`, but OTHERS did not turn that into a visible/new report.

Interpretation:

- OTHERS does not behave like BARS or IRIS AUTO under the simple common queue-service gate.
- This supports the ROM model that OTHERS is a local menu/display key whose useful effect depends on additional page/menu state, not just the generic report queue being serviced.
- The next fair comparison needs an OTHERS-specific no-button baseline because the OTHERS seeds themselves alter display/report state.

New focused scenarios:

```powershell
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\others-menu-gated-baseline.json --parity E --quiet-console --log captures\others-menu-gated-baseline.txt --result-json captures\others-menu-gated-baseline-result.json
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\others-menu-gated-press.json --parity E --quiet-console --log captures\others-menu-gated-press.txt --result-json captures\others-menu-gated-press-result.json
.\.venv\Scripts\python.exe scripts\serial_scenario_compare.py captures\others-menu-gated-baseline-result.json captures\others-menu-gated-press-result.json --show-labels
```

Result of the first OTHERS-gated comparison:

- The current baseline rerun overwrote the accidental first baseline capture; `serial_scenario.py` writes logs/results fresh when explicit paths are reused.
- `others-menu-gated-baseline-result.json` and `others-menu-gated-press-result.json` were identical at the ACK-target level.
- Both had `rx_frames=153`, `ack_sent=64`, and no label-count increase in the press run.
- The seeded state was visible in the queued stream as `0x008F = 0x1800`, but pressing OTHERS still did not create an extra serial report.

Updated interpretation:

- The simple common queue gate is not enough for OTHERS.
- The current OTHERS-adjacent seeds are also not enough for OTHERS to emit a report.
- OTHERS is increasingly likely to be a local menu/page navigation key whose effect is visible only if the ROM has selected the right page/context (`F732/F733/F72C/F731/F770`), rather than a host-visible selector-report button like BARS or IRIS AUTO.
