updates
This commit is contained in:
@@ -278,6 +278,7 @@ def _declarations(tx_candidate: JsonObject | None, rx_candidate: JsonObject | No
|
||||
"typedef uint8_t u8;",
|
||||
"typedef uint16_t u16;",
|
||||
"",
|
||||
"#define BIT(n) (1u << (n))",
|
||||
"extern volatile u8 MEM8[0x10000];",
|
||||
"",
|
||||
f"#define {channel}_SCR MEM8[{_c_hex(scr)}]",
|
||||
@@ -424,6 +425,7 @@ def _semantics_lines(
|
||||
lines.extend(_command_effect_comment_lines(protocol.get("command_effects"), opts, prefix=" * "))
|
||||
lines.extend(_response_schema_comment_lines(_schema_list(protocol), opts, prefix=" * "))
|
||||
lines.extend(_table_map_comment_lines(_table_map_list(protocol), opts, prefix=" * "))
|
||||
lines.extend(_panel_selector_comment_lines(protocol.get("panel_selector_semantics"), opts, prefix=" * "))
|
||||
lines.extend(_state_variable_comment_lines(protocol.get("state_variable_candidates"), opts, prefix=" * "))
|
||||
lines.extend(_retry_error_comment_lines(protocol.get("retry_error_model"), opts, prefix=" * "))
|
||||
lines.extend(_gate_queue_comment_lines(protocol.get("gate_queue_model"), opts, prefix=" * "))
|
||||
@@ -466,6 +468,8 @@ def _semantics_lines(
|
||||
)
|
||||
lines.extend(_gate_queue_predicate_function_lines(protocol.get("gate_queue_model")))
|
||||
lines.extend(_timer_architecture_function_lines(protocol))
|
||||
lines.extend(_panel_selector_function_lines(protocol.get("panel_selector_semantics")))
|
||||
lines.extend(_panel_selector_provisional_function_lines(protocol.get("panel_selector_semantics")))
|
||||
lines.extend(
|
||||
[
|
||||
"void sci1_process_candidate_protocol_command(void)",
|
||||
@@ -474,6 +478,8 @@ def _semantics_lines(
|
||||
" u16 logical_index = sci1_rx_candidate_logical_index();",
|
||||
" u16 value = sci1_rx_candidate_value();",
|
||||
"",
|
||||
" sci1_candidate_panel_selector_annotation(logical_index, value);",
|
||||
"",
|
||||
],
|
||||
)
|
||||
lines.extend(_command_dispatch_switch_lines(commands, opts))
|
||||
@@ -644,6 +650,70 @@ def _table_map_comment_lines(
|
||||
return lines
|
||||
|
||||
|
||||
def _panel_selector_comment_lines(
|
||||
value: object,
|
||||
opts: SerialPseudocodeOptions,
|
||||
*,
|
||||
prefix: str,
|
||||
) -> list[str]:
|
||||
selectors = _object_list(value)
|
||||
if not selectors:
|
||||
return []
|
||||
lines = [f"{prefix}panel selector semantics:"]
|
||||
for selector in selectors[:6]:
|
||||
selector_hex = selector.get("selector_hex") or _selector_hex(selector.get("selector"))
|
||||
name = selector.get("name") or "panel_selector"
|
||||
current = selector.get("current_word_address_hex") or "current table"
|
||||
dispatch = selector.get("dispatch_handler") or "dispatch unknown"
|
||||
summary = _comment_text(str(selector.get("summary") or "bench/ROM selector annotation"))
|
||||
lines.append(f"{prefix}- {selector_hex} {name}: {summary}")
|
||||
lines.append(f"{prefix} current word: {current}; dispatch: {dispatch}")
|
||||
for effect in _object_list(selector.get("effects"))[:4]:
|
||||
mask = effect.get("mask_hex") or _selector_hex(effect.get("mask"))
|
||||
effect_name = effect.get("name") or "effect"
|
||||
when_set = _comment_text(str(effect.get("when_set") or "set"))
|
||||
bits = ", ".join(str(item) for item in effect.get("ram_bits", []))
|
||||
suffix = f"; RAM {bits}" if bits else ""
|
||||
lines.append(f"{prefix} {mask} -> {effect_name}: {when_set}{suffix}")
|
||||
meanings = []
|
||||
for meaning in _object_list(selector.get("value_meanings"))[:4]:
|
||||
value_hex = meaning.get("value_hex") or _selector_hex(meaning.get("value"))
|
||||
label = _comment_text(str(meaning.get("meaning") or "known panel value"))
|
||||
meanings.append(f"{value_hex} {label}")
|
||||
if meanings:
|
||||
lines.append(f"{prefix} observed values: {'; '.join(meanings)}")
|
||||
state_machine = selector.get("state_machine")
|
||||
if isinstance(state_machine, dict):
|
||||
name_candidate = state_machine.get("name_candidate") or "selector_state_machine_candidate"
|
||||
summary = _comment_text(str(state_machine.get("summary") or "bench-proven selector state-machine candidate"))
|
||||
lines.append(f"{prefix} state machine: {name_candidate}: {summary}")
|
||||
active = state_machine.get("active_report_frame")
|
||||
clear = state_machine.get("clear_report_frame")
|
||||
ack = state_machine.get("ack_frame")
|
||||
mirror_active = state_machine.get("active_mirror_frame")
|
||||
mirror_clear = state_machine.get("clear_mirror_frame")
|
||||
if active or clear or ack:
|
||||
lines.append(
|
||||
f"{prefix} frames: active report {active or '?'}; clear report {clear or '?'}; "
|
||||
f"ACK {ack or '?'}; mirror active {mirror_active or '?'}; mirror clear {mirror_clear or '?'}"
|
||||
)
|
||||
triggers = []
|
||||
for trigger in _object_list(selector.get("local_triggers"))[:3]:
|
||||
source = trigger.get("source") or trigger.get("handler") or "local path"
|
||||
summary = _comment_text(str(trigger.get("summary") or "local trigger candidate"))
|
||||
name_candidate = trigger.get("name_candidate")
|
||||
prefix_text = f"{name_candidate} " if name_candidate else ""
|
||||
triggers.append(f"{prefix_text}{source}: {summary}")
|
||||
if triggers:
|
||||
lines.append(f"{prefix} local trigger candidates: {'; '.join(triggers)}")
|
||||
evidence = ", ".join(str(item) for item in selector.get("evidence", []) if item)
|
||||
if opts.include_evidence and evidence:
|
||||
lines.append(f"{prefix} evidence: {_comment_text(evidence)}")
|
||||
if len(selectors) > 6:
|
||||
lines.append(f"{prefix}- ... {len(selectors) - 6} more panel selector annotations")
|
||||
return lines
|
||||
|
||||
|
||||
def _state_variable_comment_lines(
|
||||
value: object,
|
||||
opts: SerialPseudocodeOptions,
|
||||
@@ -955,6 +1025,121 @@ def _timer_architecture_function_lines(protocol: JsonObject) -> list[str]:
|
||||
)
|
||||
|
||||
|
||||
def _panel_selector_function_lines(value: object) -> list[str]:
|
||||
selectors = _object_list(value)
|
||||
if not selectors:
|
||||
return [
|
||||
"static void sci1_candidate_panel_selector_annotation(u16 logical_index, u16 value)",
|
||||
"{",
|
||||
" (void)logical_index;",
|
||||
" (void)value;",
|
||||
"}",
|
||||
"",
|
||||
]
|
||||
|
||||
lines = [
|
||||
"static void sci1_candidate_panel_selector_annotation(u16 logical_index, u16 value)",
|
||||
"{",
|
||||
" /* Known bench/ROM selector labels. This helper is commentary for the decompile. */",
|
||||
" switch (logical_index) {",
|
||||
]
|
||||
for selector in selectors:
|
||||
selector_value = selector.get("selector")
|
||||
if not isinstance(selector_value, int):
|
||||
continue
|
||||
selector_hex = selector.get("selector_hex") or f"0x{selector_value:04X}"
|
||||
name = _comment_text(str(selector.get("name") or "panel selector"))
|
||||
current = selector.get("current_word_address_hex") or "current table"
|
||||
dispatch = selector.get("dispatch_handler") or "dispatch unknown"
|
||||
lines.append(f" case 0x{selector_value & 0x01FF:04X}u:")
|
||||
lines.append(f" /* {selector_hex} {name}; current word {current}; {dispatch}. */")
|
||||
for effect in _object_list(selector.get("effects")):
|
||||
mask = effect.get("mask")
|
||||
if not isinstance(mask, int):
|
||||
continue
|
||||
effect_name = _comment_text(str(effect.get("name") or "panel effect"))
|
||||
when_set = _comment_text(str(effect.get("when_set") or "set"))
|
||||
when_clear = _comment_text(str(effect.get("when_clear") or "clear"))
|
||||
lines.append(f" if ((value & 0x{mask & 0xFFFF:04X}u) != 0u) {{")
|
||||
lines.append(f" /* {effect_name}: {when_set}. */")
|
||||
lines.append(" } else {")
|
||||
lines.append(f" /* {effect_name}: {when_clear}. */")
|
||||
lines.append(" }")
|
||||
for meaning in _object_list(selector.get("value_meanings")):
|
||||
known_value = meaning.get("value")
|
||||
if not isinstance(known_value, int):
|
||||
continue
|
||||
label = _comment_text(str(meaning.get("meaning") or "known panel value"))
|
||||
lines.append(f" if (value == 0x{known_value & 0xFFFF:04X}u) {{")
|
||||
lines.append(f" /* {label}. */")
|
||||
lines.append(" }")
|
||||
lines.append(" break;")
|
||||
lines.extend(
|
||||
[
|
||||
" default:",
|
||||
" break;",
|
||||
" }",
|
||||
"}",
|
||||
"",
|
||||
],
|
||||
)
|
||||
return lines
|
||||
|
||||
|
||||
def _panel_selector_provisional_function_lines(value: object) -> list[str]:
|
||||
selectors = _object_list(value)
|
||||
lines: list[str] = []
|
||||
for selector in selectors:
|
||||
selector_value = selector.get("selector")
|
||||
if not isinstance(selector_value, int):
|
||||
continue
|
||||
state_machine = selector.get("state_machine")
|
||||
if not isinstance(state_machine, dict):
|
||||
continue
|
||||
for trigger in _object_list(selector.get("local_triggers")):
|
||||
name = str(trigger.get("name_candidate") or "").strip()
|
||||
if not name:
|
||||
continue
|
||||
handler = _comment_text(str(trigger.get("handler") or "handler unknown"))
|
||||
source = _comment_text(str(trigger.get("source") or "source unknown"))
|
||||
gate = _comment_text(str(trigger.get("gate") or "gate unknown"))
|
||||
current_bit = _comment_text(str(trigger.get("current_state_bit") or "current state bit unknown"))
|
||||
summary = _comment_text(str(trigger.get("summary") or "local trigger candidate"))
|
||||
active_value = _int_from_object(trigger.get("active_value"), 0x4000)
|
||||
clear_value = _int_from_object(trigger.get("clear_value"), 0x0000)
|
||||
active_report = _comment_text(str(state_machine.get("active_report_frame") or "active report unknown"))
|
||||
clear_report = _comment_text(str(state_machine.get("clear_report_frame") or "clear report unknown"))
|
||||
ack_frame = _comment_text(str(state_machine.get("ack_frame") or "ACK unknown"))
|
||||
active_mirror = _comment_text(str(state_machine.get("active_mirror_frame") or "active mirror unknown"))
|
||||
clear_mirror = _comment_text(str(state_machine.get("clear_mirror_frame") or "clear mirror unknown"))
|
||||
safe_name = _safe_identifier(name)
|
||||
lines.extend(
|
||||
[
|
||||
f"void {safe_name}(void)",
|
||||
"{",
|
||||
f" /* Provisional name for ROM {handler}: {summary} */",
|
||||
f" /* Source {source}; gate {gate}; current state {current_bit}. */",
|
||||
" if ((MEM8[0xF6DBu] & BIT(7)) == 0u) {",
|
||||
" return;",
|
||||
" }",
|
||||
" if (MEM8[0xF731u] > 3u) {",
|
||||
" return;",
|
||||
" }",
|
||||
"",
|
||||
" if ((MEM8[0xF791u] & BIT(5)) == 0u) {",
|
||||
f" /* Requests selector 0x{selector_value & 0x01FF:04X}=0x{active_value & 0xFFFF:04X}: {active_report}. */",
|
||||
f" /* CCU should ACK {ack_frame}, then mirror {active_mirror}. */",
|
||||
" } else {",
|
||||
f" /* Requests selector 0x{selector_value & 0x01FF:04X}=0x{clear_value & 0xFFFF:04X}: {clear_report}. */",
|
||||
f" /* CCU should ACK {ack_frame}, then mirror {clear_mirror}. */",
|
||||
" }",
|
||||
"}",
|
||||
"",
|
||||
],
|
||||
)
|
||||
return lines
|
||||
|
||||
|
||||
def _timer_tick_function_lines(function_name: str, counters: list[JsonObject], summary: str) -> list[str]:
|
||||
lines = [
|
||||
f"void {function_name}(void)",
|
||||
@@ -1130,6 +1315,16 @@ def _command_hex(value: object) -> str:
|
||||
return "?"
|
||||
|
||||
|
||||
def _selector_hex(value: object) -> str:
|
||||
if isinstance(value, int):
|
||||
return f"0x{value & 0xFFFF:04X}"
|
||||
return "?"
|
||||
|
||||
|
||||
def _int_from_object(value: object, default: int) -> int:
|
||||
return value if isinstance(value, int) else default
|
||||
|
||||
|
||||
def _tx_functions(candidate: JsonObject, opts: SerialPseudocodeOptions) -> list[str]:
|
||||
length = _int_field(candidate, "frame_length", 6)
|
||||
seed = _int_field(candidate, "checksum_seed", 0x5A)
|
||||
@@ -1386,3 +1581,7 @@ def _safe_identifier(value: str) -> str:
|
||||
|
||||
def _comment_text(text: str) -> str:
|
||||
return text.replace("*/", "* /").replace("\r", " ").replace("\n", " ")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
|
||||
Reference in New Issue
Block a user