350 lines
17 KiB
Python
350 lines
17 KiB
Python
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
|