from __future__ import annotations from copy import deepcopy from typing import Any JsonObject = dict[str, Any] CURRENT_TABLE_BASE = 0xE800 PRIMARY_TABLE_BASE = 0xE000 SECONDARY_TABLE_BASE = 0xE400 PANEL_SELECTOR_SEMANTICS: tuple[JsonObject, ...] = ( { "selector": 0x0013, "selector_hex": "0x0013", "name": "slave_and_iris_mblack_link_lamps", "summary": ( "Selector 0x0013 is a two-bit lamp/status word. ROM dispatch H'2E06 " "reads current table word H'E826 and fans bit 15 and bit 14 into panel latch RAM." ), "state_machine": { "name_candidate": "iris_mblack_link_closed_loop_state_candidate", "summary": ( "Bench-proven closed loop: the RCP reports local IRIS/M.BLACK LINK intent, " "the CCU ACKs selector 0x0013, then the CCU mirrors the accepted selector " "state back with command 0. The mirrored state controls the next toggle direction." ), "active_report_frame": "00 00 13 40 00 09", "clear_report_frame": "00 00 13 00 00 49", "ack_frame": "05 00 13 00 00 4C", "active_mirror_frame": "00 00 13 40 00 09", "clear_mirror_frame": "00 00 13 00 00 49", "confidence": "bench-high", }, "primary_word_address": PRIMARY_TABLE_BASE + 0x0013 * 2, "primary_word_address_hex": "H'E026", "current_word_address": CURRENT_TABLE_BASE + 0x0013 * 2, "current_word_address_hex": "H'E826", "dispatch_handler": "H'2E06", "confidence": "high", "evidence": [ "bench: 00 00 13 80 00 C9 lights far-right SLAVE lamp", "bench: 00 00 13 40 00 09 lights IRIS/M.BLACK LINK lamp", "ROM: H'2E06-H'2E32 tests H'E826 bits 15/14 and sets/clears F791/F713/F716 latch bits", ], "effects": [ { "bit": 15, "mask": 0x8000, "mask_hex": "0x8000", "name": "SLAVE lamp", "when_set": "sets F791.6 and F713.4", "when_clear": "clears F791.6 and F713.4", "ram_bits": ["F791.6", "F713.4"], "handler_range": "H'2E06-H'2E1A", "confidence": "high", }, { "bit": 14, "mask": 0x4000, "mask_hex": "0x4000", "name": "IRIS/M.BLACK LINK lamp", "when_set": "sets F791.5 and F716.7", "when_clear": "clears F791.5 and F716.7", "ram_bits": ["F791.5", "F716.7"], "handler_range": "H'2E1E-H'2E32", "confidence": "high", }, ], "local_triggers": [ { "kind": "panel_input_toggle", "source": "F006.7 / F6DB.7", "handler": "H'200E", "name_candidate": "provisional_iris_mblack_link_button_toggle_report", "summary": ( "When F6DB.7 is asserted and F731 <= 3, the ROM toggles current-table " "bit 14 at H'E826 based on F791.5, then queues selector 0x0013 through loc_3E54." ), "gate": "F731 <= 3", "current_state_bit": "F791.5", "active_value": 0x4000, "active_value_hex": "0x4000", "clear_value": 0x0000, "clear_value_hex": "0x0000", "writes": ["H'E826 bit14"], "queue_call": "loc_3E54", "confidence": "medium-high", }, { "kind": "local_helper_set_clear", "source": "H'1FE8/H'1FFB", "handler": "H'1FE8-H'200D", "summary": "Adjacent local helpers set or clear current-table bit 15 at H'E826 and queue selector 0x0013.", "writes": ["H'E826 bit15"], "queue_call": "loc_3E54", "confidence": "medium", }, ], "value_meanings": [ {"value": 0x8000, "value_hex": "0x8000", "meaning": "SLAVE lamp on", "confidence": "high"}, {"value": 0x4000, "value_hex": "0x4000", "meaning": "IRIS/M.BLACK LINK lamp on", "confidence": "high"}, {"value": 0x0000, "value_hex": "0x0000", "meaning": "SLAVE and IRIS/M.BLACK LINK latch bits clear through H'2E06", "confidence": "high"}, ], }, { "selector": 0x0015, "selector_hex": "0x0015", "name": "call_and_red_tally_lamp_lane", "summary": "Bench-visible CALL lamp and red tally lane; local CALL handler mirrors F6DB.5 into E800[0x0015].15.", "primary_word_address": PRIMARY_TABLE_BASE + 0x0015 * 2, "primary_word_address_hex": "H'E02A", "current_word_address": CURRENT_TABLE_BASE + 0x0015 * 2, "current_word_address_hex": "H'E82A", "dispatch_handler": "handler unknown", "confidence": "bench-high", "evidence": [ "bench: 00 00 15 80 00 CF lights CALL and red tally", "ROM: H'20A1-H'20BA reads F6DB.5, writes H'E82A, and queues selector 0x0015", ], "value_meanings": [ {"value": 0x8000, "value_hex": "0x8000", "meaning": "CALL lamp and red tally on", "confidence": "bench-high"}, {"value": 0x0000, "value_hex": "0x0000", "meaning": "CALL inactive/clear report", "confidence": "bench-high"}, ], }, { "selector": 0x0017, "selector_hex": "0x0017", "name": "bars_lamp_lane", "summary": "Bench-visible BARS lamp/latch lane; low writes do not reliably clear the visible latch.", "primary_word_address": PRIMARY_TABLE_BASE + 0x0017 * 2, "primary_word_address_hex": "H'E02E", "current_word_address": CURRENT_TABLE_BASE + 0x0017 * 2, "current_word_address_hex": "H'E82E", "dispatch_handler": "handler unknown", "confidence": "bench-high", "evidence": [ "bench: 00 00 17 80 00 CD lights BARS", "bench: 00 00 17 40 00 0D also lights the BARS latch in neighbor sweep", "ROM: H'1EDE can queue selector 0x0017 from F6D4.2", ], "value_meanings": [ {"value": 0x8000, "value_hex": "0x8000", "meaning": "BARS lamp on", "confidence": "bench-high"}, {"value": 0x4000, "value_hex": "0x4000", "meaning": "BARS lamp/latch on", "confidence": "bench-medium-high"}, {"value": 0x0000, "value_hex": "0x0000", "meaning": "BARS low write; visible latch may remain", "confidence": "bench-medium"}, ], }, { "selector": 0x001A, "selector_hex": "0x001A", "name": "monitor_selector_lamps", "summary": "Bench-visible MONITOR selector cluster found from ROM-derived button-output sweep.", "primary_word_address": PRIMARY_TABLE_BASE + 0x001A * 2, "primary_word_address_hex": "H'E034", "current_word_address": CURRENT_TABLE_BASE + 0x001A * 2, "current_word_address_hex": "H'E834", "dispatch_handler": "handler unknown", "confidence": "bench-high", "evidence": [ "bench: 00 00 1A 08 08 40 lights MONITOR ENC", "bench: 00 00 1A 20 20 40 lights MONITOR B", "bench: 00 00 1A 40 40 40 lights MONITOR G", "bench: 00 00 1A 80 80 40 lights MONITOR R", "ROM: H'1CB2-H'1D56 writes packed values to H'E834 and queues selector 0x001A", ], "value_meanings": [ {"value": 0x0808, "value_hex": "0x0808", "meaning": "MONITOR ENC lamp", "confidence": "bench-high"}, {"value": 0x2020, "value_hex": "0x2020", "meaning": "MONITOR B lamp", "confidence": "bench-high"}, {"value": 0x4040, "value_hex": "0x4040", "meaning": "MONITOR G lamp", "confidence": "bench-high"}, {"value": 0x8080, "value_hex": "0x8080", "meaning": "MONITOR R lamp", "confidence": "bench-high"}, ], }, { "selector": 0x0024, "selector_hex": "0x0024", "name": "lcd_selector_button_lamp", "summary": "Bench-visible LCD selector-button lamp lane.", "primary_word_address": PRIMARY_TABLE_BASE + 0x0024 * 2, "primary_word_address_hex": "H'E048", "current_word_address": CURRENT_TABLE_BASE + 0x0024 * 2, "current_word_address_hex": "H'E848", "confidence": "bench-medium", "value_meanings": [ {"value": 0x8000, "value_hex": "0x8000", "meaning": "LCD selector-button lamp visible", "confidence": "bench-medium"}, {"value": 0x0000, "value_hex": "0x0000", "meaning": "lamp remained visible at 0.5 s in isolation run", "confidence": "bench-low"}, ], }, { "selector": 0x006B, "selector_hex": "0x006B", "name": "standard_lamp_lane", "summary": "Bench-visible STANDARD lamp lane found from ROM-derived F6D4.6 handler candidate.", "primary_word_address": PRIMARY_TABLE_BASE + 0x006B * 2, "primary_word_address_hex": "H'E0D6", "current_word_address": CURRENT_TABLE_BASE + 0x006B * 2, "current_word_address_hex": "H'E8D6", "dispatch_handler": "handler unknown", "confidence": "bench-high", "evidence": [ "bench: 00 00 6B 80 00 B1 lights STANDARD", "ROM: H'2048 can write H'E8D6=0x8000 and queue selector 0x006B from F6D4.6", ], "value_meanings": [ {"value": 0x8000, "value_hex": "0x8000", "meaning": "STANDARD lamp on", "confidence": "bench-high"}, ], }, { "selector": 0x0082, "selector_hex": "0x0082", "name": "iris_readout_lane", "summary": "Bench-visible IRIS seven-segment/display lane.", "primary_word_address": PRIMARY_TABLE_BASE + 0x0082 * 2, "primary_word_address_hex": "H'E104", "current_word_address": CURRENT_TABLE_BASE + 0x0082 * 2, "current_word_address_hex": "H'E904", "confidence": "bench-high", "value_meanings": [ {"value": 0x8000, "value_hex": "0x8000", "meaning": "IRIS display OP", "confidence": "bench-high"}, {"value": 0x4000, "value_hex": "0x4000", "meaning": "IRIS display 1.4", "confidence": "bench-high"}, {"value": 0x0000, "value_hex": "0x0000", "meaning": "IRIS display blank", "confidence": "bench-high"}, ], }, { "selector": 0x0083, "selector_hex": "0x0083", "name": "combined_iris_shutter_master_gain_status_lane", "summary": "Bench-visible combined status/readout lane; clear behavior appears latched or copied elsewhere.", "primary_word_address": PRIMARY_TABLE_BASE + 0x0083 * 2, "primary_word_address_hex": "H'E106", "current_word_address": CURRENT_TABLE_BASE + 0x0083 * 2, "current_word_address_hex": "H'E906", "confidence": "bench-medium-high", "value_meanings": [ {"value": 0x8000, "value_hex": "0x8000", "meaning": "IRIS AUTO, SHUTTER OFF, MASTER GAIN -3", "confidence": "bench-medium-high"}, {"value": 0x4000, "value_hex": "0x4000", "meaning": "IRIS AUTO, SHUTTER OFF, MASTER GAIN 0", "confidence": "bench-high"}, {"value": 0x2000, "value_hex": "0x2000", "meaning": "IRIS AUTO, SHUTTER OFF, MASTER GAIN 3", "confidence": "bench-high"}, {"value": 0x0004, "value_hex": "0x0004", "meaning": "IRIS AUTO, SHUTTER OFF, MASTER GAIN HP", "confidence": "bench-high"}, {"value": 0x0000, "value_hex": "0x0000", "meaning": "same visible state remained at 0.5 s", "confidence": "bench-low"}, ], }, { "selector": 0x008F, "selector_hex": "0x008F", "name": "shutter_display_status_lane", "summary": "Bench-visible shutter/status display lane; local F6D0.6/F6D0.7 handlers also queue this selector.", "primary_word_address": PRIMARY_TABLE_BASE + 0x008F * 2, "primary_word_address_hex": "H'E11E", "current_word_address": CURRENT_TABLE_BASE + 0x008F * 2, "current_word_address_hex": "H'E91E", "confidence": "bench-high", "evidence": [ "bench: 00 01 0F 80 00 D4 shows IRIS AUTO and shutter value beginning with 1", "bench: 00 01 0F 20 00 74 shows IRIS AUTO and shutter 00.0", "bench: 00 01 0F 08 00 5C shows IRIS AUTO and shutter EVS", "bench: 00 01 0F 10 00 44 shows IRIS AUTO and shutter OFF", "ROM: H'24E8/H'252E write H'E91E and queue selector 0x008F from F6D0.7/F6D0.6", ], "value_meanings": [ {"value": 0x8000, "value_hex": "0x8000", "meaning": "IRIS AUTO plus shutter value beginning with 1", "confidence": "bench-medium-high"}, {"value": 0x2000, "value_hex": "0x2000", "meaning": "IRIS AUTO plus shutter 00.0", "confidence": "bench-high"}, {"value": 0x0800, "value_hex": "0x0800", "meaning": "IRIS AUTO plus shutter EVS", "confidence": "bench-high"}, {"value": 0x1000, "value_hex": "0x1000", "meaning": "IRIS AUTO plus shutter OFF", "confidence": "bench-high"}, ], }, { "selector": 0x0093, "selector_hex": "0x0093", "name": "white_balance_black_flare_mode_lane", "summary": "Bench-visible white-balance and black/flare lamp lane.", "primary_word_address": PRIMARY_TABLE_BASE + 0x0093 * 2, "primary_word_address_hex": "H'E126", "current_word_address": CURRENT_TABLE_BASE + 0x0093 * 2, "current_word_address_hex": "H'E926", "confidence": "bench-high", "value_meanings": [ {"value": 0x8000, "value_hex": "0x8000", "meaning": "BLACK/FLARE MANUAL plus white-balance PRESET", "confidence": "bench-high"}, {"value": 0x4000, "value_hex": "0x4000", "meaning": "BLACK/FLARE MANUAL plus white-balance AUTO", "confidence": "bench-high"}, {"value": 0x2000, "value_hex": "0x2000", "meaning": "BLACK/FLARE MANUAL plus white-balance MANUAL", "confidence": "bench-high"}, {"value": 0x1020, "value_hex": "0x1020", "meaning": "BLACK/FLARE MANUAL plus white-balance MANUAL", "confidence": "bench-high"}, {"value": 0x4040, "value_hex": "0x4040", "meaning": "BLACK/FLARE AUTO plus white-balance AUTO", "confidence": "bench-high"}, {"value": 0x8040, "value_hex": "0x8040", "meaning": "BLACK/FLARE AUTO plus white-balance PRESET", "confidence": "bench-high"}, {"value": 0x0020, "value_hex": "0x0020", "meaning": "BLACK/FLARE MANUAL plus white-balance MANUAL", "confidence": "bench-high"}, {"value": 0x0040, "value_hex": "0x0040", "meaning": "BLACK/FLARE AUTO plus white-balance MANUAL", "confidence": "bench-high"}, {"value": 0x0000, "value_hex": "0x0000", "meaning": "BLACK/FLARE MANUAL plus white-balance MANUAL", "confidence": "bench-high"}, ], }, { "selector": 0x0110, "selector_hex": "0x0110", "name": "knee_auto_lamp_or_page_status_lane", "summary": "Bench-visible KNEE AUTO source; ROM notes indicate timed KNEE/detail page interaction.", "primary_word_address": PRIMARY_TABLE_BASE + 0x0110 * 2, "primary_word_address_hex": "H'E220", "current_word_address": CURRENT_TABLE_BASE + 0x0110 * 2, "current_word_address_hex": "H'EA20", "confidence": "bench-high", "evidence": [ "bench: 00 01 90 80 00 4B lights KNEE AUTO", "ROM: KNEE notes identify E000[0x0110].15 as a strong KNEE AUTO/timed display source", ], "value_meanings": [ {"value": 0x8000, "value_hex": "0x8000", "meaning": "KNEE AUTO lamp/status on", "confidence": "bench-high"}, ], }, ) def panel_selector_semantics_payload() -> list[JsonObject]: return deepcopy(list(PANEL_SELECTOR_SEMANTICS)) def known_panel_selector(selector: int) -> JsonObject | None: normalized = selector & 0x01FF for item in PANEL_SELECTOR_SEMANTICS: if int(item["selector"]) == normalized: return deepcopy(item) return None def selector_word_address(table_base: int, selector: int) -> int: return (table_base + ((selector & 0x01FF) * 2)) & 0xFFFF def describe_selector_value(selector: int, value: int) -> list[str]: item = known_panel_selector(selector) if item is None: return [] normalized_value = value & 0xFFFF lines: list[str] = [] for meaning in item.get("value_meanings", []): if not isinstance(meaning, dict) or meaning.get("value") != normalized_value: continue lines.append(str(meaning.get("meaning") or "known panel selector value")) for effect in item.get("effects", []): if not isinstance(effect, dict) or not isinstance(effect.get("mask"), int): continue mask = int(effect["mask"]) & 0xFFFF state = "set" if normalized_value & mask else "clear" action = effect.get("when_set") if state == "set" else effect.get("when_clear") name = str(effect.get("name") or f"bit {effect.get('bit', '?')}") if action: lines.append(f"{name}: bit {effect.get('bit', '?')} {state}; {action}") else: lines.append(f"{name}: bit {effect.get('bit', '?')} {state}") return lines