From c0304c575c3f29d76291bc8aed8da01bf10dadad Mon Sep 17 00:00:00 2001 From: Aiden <68633820+awils27@users.noreply.github.com> Date: Wed, 27 May 2026 11:50:10 +1000 Subject: [PATCH] traces --- README.md | 16 +- build/panel_button_trace.json | 2919 +++ build/panel_button_trace.md | 64 + build/rom_f109_handlers.asm | 433 + build/rom_f109_handlers.json | 16353 ++++++++++++++++ build/rom_f109_tail.asm | 107 + build/rom_f109_tail.json | 2076 ++ ccu_emulator/README.md | 69 + ccu_emulator/__init__.py | 28 + ccu_emulator/__main__.py | 5 + ccu_emulator/cli.py | 180 + ccu_emulator/controller.py | 149 + ccu_emulator/frames.py | 59 + ccu_emulator/policy.py | 44 + ccu_emulator/refresh.py | 41 + ccu_emulator/serial_link.py | 67 + docs/pt2-button-report-bench-plan.md | 101 + docs/pt2-continuation-command-trace.md | 209 + docs/pt2-copy-state-machine.md | 19 + docs/pt2-known-button-rom-trace.md | 157 + docs/pt2-menu-state-machine.md | 83 + docs/pt2-protocol.md | 9 + docs/pt2-report-aftermath-trace.md | 215 + docs/pt2-session-rhythm-trace.md | 186 + docs/pt2-shutter-display-trace.md | 13 + h8536/bench_connect_lcd.py | 18 + h8536/emulator/__init__.py | 6 + h8536/emulator/panel.py | 203 + h8536/emulator/runner.py | 33 + h8536/emulator/rx_probe.py | 159 +- h8536/panel_button_trace.py | 306 + h8536/serial_scenario.py | 215 +- h8536/serial_scenario_compare.py | 121 + h8536/serial_scenario_unexpected.py | 10 + h8536_panel_button_trace.py | 8 + .../button-report-broad-gates-press.json | 208 + .../button-report-common-gate-baseline.json | 100 + .../button-report-common-gate-press.json | 100 + scenarios/copy-family00-006d-006c-1000ms.json | 47 + scenarios/copy-family00-006d-006c-250ms.json | 47 + scenarios/others-menu-gated-baseline.json | 124 + scenarios/others-menu-gated-press.json | 124 + ...-report-ack-c0-recover-ok-0096-prompt.json | 116 + ...-report-dynamic-queue-ack-0096-prompt.json | 105 + ...r-onoff-report-latch-open-0096-prompt.json | 58 + ...rt-recover-ok-after-clear-0096-prompt.json | 78 + ...hutter-onoff-report-unlock-0096-watch.json | 50 + ...hutter-onoff-report-unlock-00f8-watch.json | 50 + scripts/ccu_emulator.py | 16 + scripts/serial_scenario_compare.py | 15 + tests/test_bench_connect_lcd.py | 9 + tests/test_ccu_emulator.py | 33 + tests/test_emulator.py | 22 + tests/test_emulator_rx_probe.py | 31 +- tests/test_serial_scenario_compare.py | 37 + 55 files changed, 26035 insertions(+), 16 deletions(-) create mode 100644 build/panel_button_trace.json create mode 100644 build/panel_button_trace.md create mode 100644 build/rom_f109_handlers.asm create mode 100644 build/rom_f109_handlers.json create mode 100644 build/rom_f109_tail.asm create mode 100644 build/rom_f109_tail.json create mode 100644 ccu_emulator/README.md create mode 100644 ccu_emulator/__init__.py create mode 100644 ccu_emulator/__main__.py create mode 100644 ccu_emulator/cli.py create mode 100644 ccu_emulator/controller.py create mode 100644 ccu_emulator/frames.py create mode 100644 ccu_emulator/policy.py create mode 100644 ccu_emulator/refresh.py create mode 100644 ccu_emulator/serial_link.py create mode 100644 docs/pt2-button-report-bench-plan.md create mode 100644 docs/pt2-continuation-command-trace.md create mode 100644 docs/pt2-known-button-rom-trace.md create mode 100644 docs/pt2-report-aftermath-trace.md create mode 100644 docs/pt2-session-rhythm-trace.md create mode 100644 h8536/emulator/panel.py create mode 100644 h8536/panel_button_trace.py create mode 100644 h8536/serial_scenario_compare.py create mode 100644 h8536_panel_button_trace.py create mode 100644 scenarios/button-report-broad-gates-press.json create mode 100644 scenarios/button-report-common-gate-baseline.json create mode 100644 scenarios/button-report-common-gate-press.json create mode 100644 scenarios/copy-family00-006d-006c-1000ms.json create mode 100644 scenarios/copy-family00-006d-006c-250ms.json create mode 100644 scenarios/others-menu-gated-baseline.json create mode 100644 scenarios/others-menu-gated-press.json create mode 100644 scenarios/shutter-onoff-report-ack-c0-recover-ok-0096-prompt.json create mode 100644 scenarios/shutter-onoff-report-dynamic-queue-ack-0096-prompt.json create mode 100644 scenarios/shutter-onoff-report-latch-open-0096-prompt.json create mode 100644 scenarios/shutter-onoff-report-recover-ok-after-clear-0096-prompt.json create mode 100644 scenarios/shutter-onoff-report-unlock-0096-watch.json create mode 100644 scenarios/shutter-onoff-report-unlock-00f8-watch.json create mode 100644 scripts/ccu_emulator.py create mode 100644 scripts/serial_scenario_compare.py create mode 100644 tests/test_ccu_emulator.py create mode 100644 tests/test_serial_scenario_compare.py diff --git a/README.md b/README.md index f255259..fe180ae 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,8 @@ To start the current emulator harness: .\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\table-sweep-ack-000-07f.json --log captures\table-sweep-ack-000-07f.txt --result-json captures\table-sweep-ack-000-07f-result.json .\.venv\Scripts\python.exe scripts\state_map_runner.py --preset ok --prompt-screen .\.venv\Scripts\python.exe scripts\state_map_runner.py --analyze-log captures\ack-race-000-001.txt +.\.venv\Scripts\python.exe scripts\ccu_emulator.py --dry-run +.\.venv\Scripts\python.exe scripts\ccu_emulator.py --port COM5 --duration 30 --log captures\ccu-keepalive.txt .\.venv\Scripts\python.exe h8536_emulator_state_search.py --preset connect-queue --target ok --first-hit --json-out build\connect-state-search-ok.json .\.venv\Scripts\python.exe h8536_emulator_bench_replay.py captures\bench-connect-lcd-sequence-20260525-214411.txt --assert-bench-parity .\.venv\Scripts\python.exe h8536_emulator.py --max-steps 250000 --p9-fast-path --eeprom-seed blank --eeprom-save build\emulator-eeprom-boot.bin --eeprom-report build\emulator-eeprom-boot.txt --eeprom-report-json build\emulator-eeprom-boot.json @@ -62,7 +64,7 @@ To start the current emulator harness: The real-device bench helper uses `pyserial`; install repo dependencies with `.\.venv\Scripts\python.exe -m pip install -r requirements.txt` if needed. -The current PT2/protocol reconstruction is documented in [docs/pt2-protocol.md](docs/pt2-protocol.md), with focused mini-notes for [COPY state](docs/pt2-copy-state-machine.md) and [menu state](docs/pt2-menu-state-machine.md). +The current PT2/protocol reconstruction is documented in [docs/pt2-protocol.md](docs/pt2-protocol.md), with focused mini-notes for [COPY state](docs/pt2-copy-state-machine.md), [menu state](docs/pt2-menu-state-machine.md), the [session rhythm ROM trace](docs/pt2-session-rhythm-trace.md), [continuation commands](docs/pt2-continuation-command-trace.md), and [report aftermath handling](docs/pt2-report-aftermath-trace.md). ## Real Bench Serial Format @@ -133,6 +135,7 @@ Minimal smoke-test shape: - Includes a bench ACK probe that reproduces the `01 00 00...` -> `01 00 01...` visible retry burst, waits for `07 80 40 20 90 2D`, then sends a candidate command-5 ACK and reports whether the target keeps repeating. - Includes a checksum-resynchronizing bench receiver that scans RX byte streams for valid six-byte frames, avoids common shifted-heartbeat false locks, and can fall back to the old fixed six-byte slicer with `--sync fixed`. - Includes a JSON scenario bench runner for repeatable multi-step serial tests, including low-latency ACK-aware command-1 probes that can send the current command-5 ACK candidate immediately after the retry frame appears, with explicit max-ACK/max-target guardrails. +- Includes a modular fake-CCU runner in `ccu_emulator/` that seeds active state, listens for complete RCP report frames, and immediately sends the neutral command-5 ACK `05 00 40 00 00 1F`; optional periodic refresh frames let lamp/value streaming be tested separately from report ACKs. - Includes a PT2 state-map-aware bench runner/analyzer for the current CONNECT gate proof: it hunts a fresh device `07...` visible-drain token candidate, sends exactly one selector-zero command-4 force, probes `E000[0]` with command 1, optionally uses command 7 to recover a hidden finalized response, and labels likely token-destroying turns. - Includes a bounded emulator CONNECT state-search tool that patches small ROM-derived RAM/table surfaces, runs either the direct CONNECT branch or the selector-zero queue dispatch path, and classifies LCD outcomes as OK, DXC, NOT ACT, or other. - Includes a bench-log replay harness that feeds recorded host TX frames back into the ROM emulator with bench-style UART byte timing by default and asserts parity against the real device's observed response/LCD state. @@ -159,6 +162,7 @@ Current serial observations: - Emulator board-state finding: P7 now reads external pin state for input bits, so the DIP-off default is modeled as `--p7-input 0xFF`; `--eeprom-seed factory` can pre-seed the X24164 devices and `F400-F4FF` shadow from the ROM default table for already-initialized-state experiments. - RX probe finding: the `--preset connect-lcd` sequence is sensitive to injection timing and modeled external state. With timed UART injection, the emulator can still reach `CONNECT: OK`/`02 00 02 00 00 5A`, while the real bench remains at `CONNECT NOT ACT`; this points to missing session/P9/external-panel context rather than a simple checksum or UART-spacing issue. - Emulator state-search finding: the minimum ROM-visible OK display condition is now reproducible without serial. Direct entry at `loc_2CB9` with `E000[0]=0x8080` and unsuppressed `F730=0` reaches `CONNECT: OK`; the queued selector-zero path also reaches OK when `F970[0]=0`, `F9B9=0`, `F9B4=1`, `E000[0]=0x8080`, and `F730=0`. This makes the bench problem sharper: prove whether serial can retain `E000[0]=0x8080` and enqueue selector zero without the reset/clobber path clearing it first. +- Emulator panel-input finding: `h8536_emulator_rx_probe.py` can now inject ROM-level panel edges using traced shadow/dirty bytes. `--panel-press cam-power` models `F105 -> F6D4.3/F6F2.4`, `--panel-press call` models `F006 -> F6DB.5/F6F3.3`, and raw specs such as `--panel F6D4.6=press` let adjacent report-capable table entries be probed while the ROM still decides whether a serial report, menu action, or no-op happens. - Bench follow-up: replaying the emulator CONNECT sequence on the real device did not switch the LCD to OK. The real device answered the `04 00 00 80 00 DE` step with `07 80 C0 60 20 5D` in the captured run and remained at `CONNECT NOT ACT`, so the next mismatch to chase is the missing visible `07 80 C0 60 20 5D` response/session context rather than the LCD OK branch. - CCU seed-hint finding: `build\rom_ccu_seed_hints.txt` currently ranks selector `0x000`, `0x0F6`, `0x003`, and `0x040` as the highest-value fake-CCU stream candidates. The generated seed frames are `00 00 00 80 80 5A`, `00 01 76 20 00 0D`, `00 00 03 80 00 D9`, and `00 00 40 FF FF 1A`, with command-1 readbacks listed beside them. - Observed capture labels such as `cam_power_button_candidate` and `call_button_candidate` are deliberately treated as capture overlays, not protocol facts hard-coded in ROM. @@ -249,6 +253,7 @@ For gate/queue and table reports: python h8536_serial_gate.py --help python h8536_rx_branch_trace.py --help python h8536_report_source_trace.py --help +python h8536_panel_button_trace.py --help python h8536_table_xrefs.py --help python h8536_ccu_seed_hints.py --help python h8536_eeprom_layout.py --help @@ -258,6 +263,7 @@ python h8536_consistency.py --help - `h8536_serial_gate.py`: reports the autonomous TX gate and report queue evidence. - `h8536_rx_branch_trace.py`: reports the SCI1 RX branch tree. Current finding: command `0x04/0x05/0x06` are continuation-path commands behind `FAA2 != 0`, so a standalone command-4 force from idle should not reach `BD0E`. - `h8536_report_source_trace.py`: traces direct `loc_3E54` report enqueue sources. Current finding: no direct static `R3 = 0x0007` enqueue in the JSON, so CAM power `0x0007` remains runtime/capture-observed unless a later indirect/table path proves it. +- `h8536_panel_button_trace.py`: decodes the `H'2706` panel-button jump table and traces known CALL/CAM POWER reports back through the input shadow bytes. - `h8536_table_xrefs.py`: emits candidate table/index xrefs and LCD text correlation hints. - `h8536_ccu_seed_hints.py`: mines table, dispatch, LCD, and observed-report hints for the CCU-side state stream the RCP may expect before active displays/reports. - `h8536_eeprom_layout.py`: mines the X24164 EEPROM layout, ROM factory defaults, persistent record slots, and serial selector-to-EEPROM offset mapping. @@ -289,6 +295,9 @@ python h8536_emulator_rx_divergence.py --help - `--trace-report-gates`, `--trace-report-queue`, and `--trace-ram-lifecycle`: inspect the serial report queue, `loc_4046`/`F9C4` gate, and watched RAM byte history. - `--target-frame "00 00 00 00 80 DA"`: compare staged/emitted TX bytes against an expected six-byte frame. - `h8536_emulator_rx_probe.py "04 00 00 80 00"`: append the checksum, inject the host frame through SCI1 RX, and summarize responses. +- `h8536_emulator_rx_probe.py --wait-heartbeats 1 --panel-press cam-power`: inject the traced CAM POWER edge into the ROM panel shadow/dirty path and listen for the resulting selector `0x0007` behavior. +- `h8536_emulator_rx_probe.py --panel call=press --panel call=release --keep-listening`: preserve ordered synthetic panel actions and test the CALL active/inactive path through the normal ROM dispatcher. +- `h8536_emulator_rx_probe.py --panel F6D4.6=press`: probe an adjacent raw matrix bit from the table at `H'2706`; raw specs may be shadow bytes like `F6D4.6` or source bytes like `F105.6`. - `h8536_emulator_rx_probe.py --uart-timing --uart-baud 38400 "04 00 00 80 00"`: inject all six host bytes with bench-style wire spacing of about 260 us per byte, letting RXI/TXI/timers interleave; if the ROM has not cleared `RDRF` before the next byte, the SCI model raises `ORER`. The real bench link is `8E1`. - `h8536_emulator_rx_probe.py --uart-timing --uart-format 8E1 --tx-wire-timing --wait-heartbeats 2 --post-frame-ms 700 "04 00 00 80 00 DE" "04 00 00 80 00 DE"`: replay the CONNECT refresh shape after heartbeat readiness and keep the emulator running for a bench-scale gap after each frame. The RAM trace now tags interesting accesses with the executing ROM PC, models SCI1 TDRE/TXI at 8E1 character time, and reports whether X24164 EEPROM bytes were written. - `h8536_emulator_rx_probe.py --preset connect-lcd`: replay the current CONNECT LCD activation candidates. @@ -336,14 +345,17 @@ python h8536_emulator_rx_divergence.py --help - `h8536/protocol_capture.py`: timestamped serial capture parser, frame recombiner, and cadence/gate-session analyzer. - `h8536/serial_scenario.py`: JSON-driven bench scenario engine shared by real-device serial scripts. - `h8536/state_map_runner.py`: PT2 state-map proof runner and bench-log analyzer for visible-drain token, selector-zero force, `E000[0]` readback, and command-7 recovery experiments. +- `ccu_emulator/`: modular fake-CCU package for reactive report ACKs and optional periodic state refreshes. - `h8536/serial_gate.py`: autonomous TX gate/queue state-machine reconstruction. - `h8536/report_source_trace.py`: direct `loc_3E54` report enqueue source tracer. +- `h8536/panel_button_trace.py`: panel button matrix/jump-table tracer for CALL, CAM POWER, and adjacent report-capable button paths. - `h8536/table_xrefs.py`: table/index xrefs and LCD correlation report generation. - `h8536/ccu_seed_hints.py`: ROM miner for likely fake-CCU state seed selectors and candidate command/readback frames. - `h8536/eeprom_layout.py`: ROM miner for X24164 EEPROM defaults, 8-byte record slots, and serial persistence mapping. - `h8536/consistency.py`: decompiler/pseudocode semantic consistency checks. - `h8536/emulator/`: early H8/536 emulator package split into CPU state, memory map, SCI1 TX capture, bench-style UART injection timing, P9/X24164 EEPROM bus model, LCD model, manual-derived FRT timer scheduling, runner, probe, CLI, and peripheral scaffolding. - `h8536/emulator/eeprom_image.py`: logical EEPROM image dump/report helpers for emulator runs, including factory diffs and record-slot summaries. +- `h8536/emulator/panel.py`: synthetic panel input descriptors for known CALL/CAM POWER edges and raw ROM shadow/source-bit injection. - `h8536/emulator/rx_probe.py`: host-frame injection and response/listener probe for SCI1 RX experiments. - `h8536/emulator/state_search.py`: bounded internal-state search for CONNECT LCD outcomes using ROM execution plus explicit RAM/table patches. - `h8536/board_profile.py`: Sony RCP-TX7 board-trace annotations, including the MAX202 RS232 path. @@ -354,7 +366,7 @@ python h8536_emulator_rx_divergence.py --help - `h8536_pseudocode.py`: pseudocode CLI wrapper. - `h8536_serial_pseudocode.py`: focused serial pseudocode CLI wrapper. - `h8536_protocol_trace.py`, `h8536_protocol_capture.py`: protocol analysis CLI wrappers. -- `h8536_serial_gate.py`, `h8536_report_source_trace.py`, `h8536_table_xrefs.py`, `h8536_ccu_seed_hints.py`, `h8536_eeprom_layout.py`, `h8536_consistency.py`: sidecar analysis CLI wrappers. +- `h8536_serial_gate.py`, `h8536_report_source_trace.py`, `h8536_panel_button_trace.py`, `h8536_table_xrefs.py`, `h8536_ccu_seed_hints.py`, `h8536_eeprom_layout.py`, `h8536_consistency.py`: sidecar analysis CLI wrappers. - `h8536_emulator.py`, `h8536_emulator_probe.py`, `h8536_emulator_rx_probe.py`, `h8536_emulator_rx_divergence.py`, `h8536_emulator_bench_replay.py`: emulator CLI wrappers. - `h8536_emulator_state_search.py`: emulator CONNECT state-search CLI wrapper. - `scripts/bench_connect_lcd_sequence.py`: real-device COM5/COM6 bench runner for the CONNECT LCD sequence. diff --git a/build/panel_button_trace.json b/build/panel_button_trace.json new file mode 100644 index 0000000..9bd3890 --- /dev/null +++ b/build/panel_button_trace.json @@ -0,0 +1,2919 @@ +{ + "button_table_base": 9990, + "button_table_base_hex": "H'2706", + "entries": [ + { + "bank": "IRQ4 A8 panel byte path", + "bit": 7, + "dirty": "F6F2.7", + "dispatcher": "1B2D", + "handler": 18970, + "handler_hex": "H'4A1A", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6D7.7" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D7", + "source": "F102", + "table_address": 10116, + "table_address_hex": "H'2784", + "table_offset": 126 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 6, + "dirty": "F6F2.7", + "dispatcher": "1B2D", + "handler": 19082, + "handler_hex": "H'4A8A", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6D7.6" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D7", + "source": "F102", + "table_address": 10114, + "table_address_hex": "H'2782", + "table_offset": 124 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 5, + "dirty": "F6F2.7", + "dispatcher": "1B2D", + "handler": 19162, + "handler_hex": "H'4ADA", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6D7.5" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D7", + "source": "F102", + "table_address": 10112, + "table_address_hex": "H'2780", + "table_offset": 122 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 4, + "dirty": "F6F2.7", + "dispatcher": "1B2D", + "handler": 19234, + "handler_hex": "H'4B22", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6D7.4" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D7", + "source": "F102", + "table_address": 10110, + "table_address_hex": "H'277E", + "table_offset": 120 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 3, + "dirty": "F6F2.7", + "dispatcher": "1B2D", + "handler": 7205, + "handler_hex": "H'1C25", + "handler_summary": {}, + "is_noop": true, + "known_report": "", + "shadow": "F6D7", + "source": "F102", + "table_address": 10108, + "table_address_hex": "H'277C", + "table_offset": 118 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 2, + "dirty": "F6F2.7", + "dispatcher": "1B2D", + "handler": 19302, + "handler_hex": "H'4B66", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6D7.2" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D7", + "source": "F102", + "table_address": 10106, + "table_address_hex": "H'277A", + "table_offset": 116 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 1, + "dirty": "F6F2.7", + "dispatcher": "1B2D", + "handler": 19444, + "handler_hex": "H'4BF4", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6D7.1" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D7", + "source": "F102", + "table_address": 10104, + "table_address_hex": "H'2778", + "table_offset": 114 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 0, + "dirty": "F6F2.7", + "dispatcher": "1B2D", + "handler": 7205, + "handler_hex": "H'1C25", + "handler_summary": {}, + "is_noop": true, + "known_report": "", + "shadow": "F6D7", + "source": "F102", + "table_address": 10102, + "table_address_hex": "H'2776", + "table_offset": 112 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 7, + "dirty": "F6F2.6", + "dispatcher": "1B44", + "handler": 19578, + "handler_hex": "H'4C7A", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6D6.7" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D6", + "source": "F103", + "table_address": 10100, + "table_address_hex": "H'2774", + "table_offset": 110 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 6, + "dirty": "F6F2.6", + "dispatcher": "1B44", + "handler": 19746, + "handler_hex": "H'4D22", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6D6.6" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D6", + "source": "F103", + "table_address": 10098, + "table_address_hex": "H'2772", + "table_offset": 108 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 5, + "dirty": "F6F2.6", + "dispatcher": "1B44", + "handler": 19850, + "handler_hex": "H'4D8A", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6D6.5" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D6", + "source": "F103", + "table_address": 10096, + "table_address_hex": "H'2770", + "table_offset": 106 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 4, + "dirty": "F6F2.6", + "dispatcher": "1B44", + "handler": 19918, + "handler_hex": "H'4DCE", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6D6.4" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D6", + "source": "F103", + "table_address": 10094, + "table_address_hex": "H'276E", + "table_offset": 104 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 3, + "dirty": "F6F2.6", + "dispatcher": "1B44", + "handler": 19998, + "handler_hex": "H'4E1E", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6D6.3" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D6", + "source": "F103", + "table_address": 10092, + "table_address_hex": "H'276C", + "table_offset": 102 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 2, + "dirty": "F6F2.6", + "dispatcher": "1B44", + "handler": 20078, + "handler_hex": "H'4E6E", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6D6.2" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D6", + "source": "F103", + "table_address": 10090, + "table_address_hex": "H'276A", + "table_offset": 100 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 1, + "dirty": "F6F2.6", + "dispatcher": "1B44", + "handler": 20162, + "handler_hex": "H'4EC2", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6D6.1" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D6", + "source": "F103", + "table_address": 10088, + "table_address_hex": "H'2768", + "table_offset": 98 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 0, + "dirty": "F6F2.6", + "dispatcher": "1B44", + "handler": 7205, + "handler_hex": "H'1C25", + "handler_summary": {}, + "is_noop": true, + "known_report": "", + "shadow": "F6D6", + "source": "F103", + "table_address": 10086, + "table_address_hex": "H'2766", + "table_offset": 96 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 7, + "dirty": "F6F2.5", + "dispatcher": "1B5B", + "handler": 20230, + "handler_hex": "H'4F06", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6D5.7" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D5", + "source": "F104", + "table_address": 10084, + "table_address_hex": "H'2764", + "table_offset": 94 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 6, + "dirty": "F6F2.5", + "dispatcher": "1B5B", + "handler": 20298, + "handler_hex": "H'4F4A", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6D5.6" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D5", + "source": "F104", + "table_address": 10082, + "table_address_hex": "H'2762", + "table_offset": 92 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 5, + "dirty": "F6F2.5", + "dispatcher": "1B5B", + "handler": 20386, + "handler_hex": "H'4FA2", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6D5.5" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D5", + "source": "F104", + "table_address": 10080, + "table_address_hex": "H'2760", + "table_offset": 90 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 4, + "dirty": "F6F2.5", + "dispatcher": "1B5B", + "handler": 20466, + "handler_hex": "H'4FF2", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6D5.4" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D5", + "source": "F104", + "table_address": 10078, + "table_address_hex": "H'275E", + "table_offset": 88 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 3, + "dirty": "F6F2.5", + "dispatcher": "1B5B", + "handler": 20554, + "handler_hex": "H'504A", + "handler_summary": { + "instruction_count_scanned": 34, + "level_tests": [ + "F6D5.3" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D5", + "source": "F104", + "table_address": 10076, + "table_address_hex": "H'275C", + "table_offset": 86 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 2, + "dirty": "F6F2.5", + "dispatcher": "1B5B", + "handler": 21268, + "handler_hex": "H'5314", + "handler_summary": { + "instruction_count_scanned": 21, + "level_tests": [ + "F6D5.2" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D5", + "source": "F104", + "table_address": 10074, + "table_address_hex": "H'275A", + "table_offset": 84 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 1, + "dirty": "F6F2.5", + "dispatcher": "1B5B", + "handler": 21346, + "handler_hex": "H'5362", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6D5.1" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D5", + "source": "F104", + "table_address": 10072, + "table_address_hex": "H'2758", + "table_offset": 82 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 0, + "dirty": "F6F2.5", + "dispatcher": "1B5B", + "handler": 7205, + "handler_hex": "H'1C25", + "handler_summary": {}, + "is_noop": true, + "known_report": "", + "shadow": "F6D5", + "source": "F104", + "table_address": 10070, + "table_address_hex": "H'2756", + "table_offset": 80 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 7, + "dirty": "F6F2.4", + "dispatcher": "1BA0", + "handler": 7205, + "handler_hex": "H'1C25", + "handler_summary": {}, + "is_noop": true, + "known_report": "", + "shadow": "F6D4", + "source": "F105", + "table_address": 10068, + "table_address_hex": "H'2754", + "table_offset": 78 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 6, + "dirty": "F6F2.4", + "dispatcher": "1BA0", + "handler": 8264, + "handler_hex": "H'2048", + "handler_summary": { + "instruction_count_scanned": 25, + "level_tests": [ + "F6D4.6" + ], + "report_selectors": [ + 107 + ], + "report_selectors_hex": [ + "0x006B" + ], + "state_writes": [ + "E8D6" + ] + }, + "is_noop": false, + "known_report": "0x006B", + "shadow": "F6D4", + "source": "F105", + "table_address": 10066, + "table_address_hex": "H'2752", + "table_offset": 76 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 5, + "dirty": "F6F2.4", + "dispatcher": "1BA0", + "handler": 8083, + "handler_hex": "H'1F93", + "handler_summary": { + "instruction_count_scanned": 15, + "level_tests": [ + "F6D4.5" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D4", + "source": "F105", + "table_address": 10064, + "table_address_hex": "H'2750", + "table_offset": 74 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 4, + "dirty": "F6F2.4", + "dispatcher": "1BA0", + "handler": 8047, + "handler_hex": "H'1F6F", + "handler_summary": { + "instruction_count_scanned": 13, + "level_tests": [ + "F6D4.4" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D4", + "source": "F105", + "table_address": 10062, + "table_address_hex": "H'274E", + "table_offset": 72 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 3, + "dirty": "F6F2.4", + "dispatcher": "1BA0", + "handler": 8000, + "handler_hex": "H'1F40", + "handler_summary": { + "instruction_count_scanned": 15, + "level_tests": [ + "F6D4.3" + ], + "report_selectors": [ + 7 + ], + "report_selectors_hex": [ + "0x0007" + ], + "state_writes": [ + "E80E" + ] + }, + "is_noop": false, + "known_report": "CAM POWER", + "shadow": "F6D4", + "source": "F105", + "table_address": 10060, + "table_address_hex": "H'274C", + "table_offset": 70 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 2, + "dirty": "F6F2.4", + "dispatcher": "1BA0", + "handler": 7902, + "handler_hex": "H'1EDE", + "handler_summary": { + "instruction_count_scanned": 30, + "level_tests": [ + "F6D4.2" + ], + "report_selectors": [ + 23, + 24 + ], + "report_selectors_hex": [ + "0x0017", + "0x0018" + ], + "state_writes": [ + "E82E", + "E830" + ] + }, + "is_noop": false, + "known_report": "0x0017, 0x0018", + "shadow": "F6D4", + "source": "F105", + "table_address": 10058, + "table_address_hex": "H'274A", + "table_offset": 68 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 1, + "dirty": "F6F2.4", + "dispatcher": "1BA0", + "handler": 7849, + "handler_hex": "H'1EA9", + "handler_summary": { + "instruction_count_scanned": 17, + "level_tests": [ + "F6D4.1" + ], + "report_selectors": [ + 248 + ], + "report_selectors_hex": [ + "0x00F8" + ], + "state_writes": [ + "E9F0" + ] + }, + "is_noop": false, + "known_report": "0x00F8", + "shadow": "F6D4", + "source": "F105", + "table_address": 10056, + "table_address_hex": "H'2748", + "table_offset": 66 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 0, + "dirty": "F6F2.4", + "dispatcher": "1BA0", + "handler": 7712, + "handler_hex": "H'1E20", + "handler_summary": { + "instruction_count_scanned": 41, + "level_tests": [ + "F6D4.0" + ], + "report_selectors": [ + 183, + 196, + 198, + 151 + ], + "report_selectors_hex": [ + "0x00B7", + "0x00C4", + "0x00C6", + "0x0097" + ], + "state_writes": [ + "E96E", + "E988", + "E98C", + "E92E" + ] + }, + "is_noop": false, + "known_report": "0x00B7, 0x00C4, 0x00C6, 0x0097", + "shadow": "F6D4", + "source": "F105", + "table_address": 10054, + "table_address_hex": "H'2746", + "table_offset": 64 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 7, + "dirty": "F6F2.3", + "dispatcher": "1BB6", + "handler": 7630, + "handler_hex": "H'1DCE", + "handler_summary": { + "instruction_count_scanned": 25, + "level_tests": [ + "F6D3.7" + ], + "report_selectors": [ + 150 + ], + "report_selectors_hex": [ + "0x0096" + ], + "state_writes": [ + "E92C" + ] + }, + "is_noop": false, + "known_report": "0x0096", + "shadow": "F6D3", + "source": "F106", + "table_address": 10052, + "table_address_hex": "H'2744", + "table_offset": 62 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 6, + "dirty": "F6F2.3", + "dispatcher": "1BB6", + "handler": 7559, + "handler_hex": "H'1D87", + "handler_summary": { + "instruction_count_scanned": 21, + "level_tests": [ + "F6D3.6" + ], + "report_selectors": [ + 151 + ], + "report_selectors_hex": [ + "0x0097" + ], + "state_writes": [ + "E92E" + ] + }, + "is_noop": false, + "known_report": "0x0097", + "shadow": "F6D3", + "source": "F106", + "table_address": 10050, + "table_address_hex": "H'2742", + "table_offset": 60 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 5, + "dirty": "F6F2.3", + "dispatcher": "1BB6", + "handler": 7510, + "handler_hex": "H'1D56", + "handler_summary": { + "instruction_count_scanned": 18, + "level_tests": [ + "F6D3.5" + ], + "report_selectors": [ + 26 + ], + "report_selectors_hex": [ + "0x001A" + ], + "state_writes": [ + "E834" + ] + }, + "is_noop": false, + "known_report": "0x001A", + "shadow": "F6D3", + "source": "F106", + "table_address": 10048, + "table_address_hex": "H'2740", + "table_offset": 58 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 4, + "dirty": "F6F2.3", + "dispatcher": "1BB6", + "handler": 7461, + "handler_hex": "H'1D25", + "handler_summary": { + "instruction_count_scanned": 18, + "level_tests": [ + "F6D3.4" + ], + "report_selectors": [ + 26 + ], + "report_selectors_hex": [ + "0x001A" + ], + "state_writes": [ + "E834" + ] + }, + "is_noop": false, + "known_report": "0x001A", + "shadow": "F6D3", + "source": "F106", + "table_address": 10046, + "table_address_hex": "H'273E", + "table_offset": 56 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 3, + "dirty": "F6F2.3", + "dispatcher": "1BB6", + "handler": 7412, + "handler_hex": "H'1CF4", + "handler_summary": { + "instruction_count_scanned": 18, + "level_tests": [ + "F6D3.3" + ], + "report_selectors": [ + 26 + ], + "report_selectors_hex": [ + "0x001A" + ], + "state_writes": [ + "E834" + ] + }, + "is_noop": false, + "known_report": "0x001A", + "shadow": "F6D3", + "source": "F106", + "table_address": 10044, + "table_address_hex": "H'273C", + "table_offset": 54 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 2, + "dirty": "F6F2.3", + "dispatcher": "1BB6", + "handler": 7374, + "handler_hex": "H'1CCE", + "handler_summary": { + "instruction_count_scanned": 12, + "level_tests": [ + "F6D3.2" + ], + "report_selectors": [ + 26 + ], + "report_selectors_hex": [ + "0x001A" + ], + "state_writes": [ + "E834" + ] + }, + "is_noop": false, + "known_report": "0x001A", + "shadow": "F6D3", + "source": "F106", + "table_address": 10042, + "table_address_hex": "H'273A", + "table_offset": 52 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 1, + "dirty": "F6F2.3", + "dispatcher": "1BB6", + "handler": 7346, + "handler_hex": "H'1CB2", + "handler_summary": { + "instruction_count_scanned": 9, + "level_tests": [ + "F6D3.1" + ], + "report_selectors": [ + 26 + ], + "report_selectors_hex": [ + "0x001A" + ], + "state_writes": [ + "E834" + ] + }, + "is_noop": false, + "known_report": "0x001A", + "shadow": "F6D3", + "source": "F106", + "table_address": 10040, + "table_address_hex": "H'2738", + "table_offset": 50 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 0, + "dirty": "F6F2.3", + "dispatcher": "1BB6", + "handler": 7205, + "handler_hex": "H'1C25", + "handler_summary": {}, + "is_noop": true, + "known_report": "", + "shadow": "F6D3", + "source": "F106", + "table_address": 10038, + "table_address_hex": "H'2736", + "table_offset": 48 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 7, + "dirty": "F6F2.2", + "dispatcher": "1BCC", + "handler": 7205, + "handler_hex": "H'1C25", + "handler_summary": {}, + "is_noop": true, + "known_report": "", + "shadow": "F6D2", + "source": "F107", + "table_address": 10036, + "table_address_hex": "H'2734", + "table_offset": 46 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 6, + "dirty": "F6F2.2", + "dispatcher": "1BCC", + "handler": 7205, + "handler_hex": "H'1C25", + "handler_summary": {}, + "is_noop": true, + "known_report": "", + "shadow": "F6D2", + "source": "F107", + "table_address": 10034, + "table_address_hex": "H'2732", + "table_offset": 44 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 5, + "dirty": "F6F2.2", + "dispatcher": "1BCC", + "handler": 7205, + "handler_hex": "H'1C25", + "handler_summary": {}, + "is_noop": true, + "known_report": "", + "shadow": "F6D2", + "source": "F107", + "table_address": 10032, + "table_address_hex": "H'2730", + "table_offset": 42 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 4, + "dirty": "F6F2.2", + "dispatcher": "1BCC", + "handler": 7205, + "handler_hex": "H'1C25", + "handler_summary": {}, + "is_noop": true, + "known_report": "", + "shadow": "F6D2", + "source": "F107", + "table_address": 10030, + "table_address_hex": "H'272E", + "table_offset": 40 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 3, + "dirty": "F6F2.2", + "dispatcher": "1BCC", + "handler": 7206, + "handler_hex": "H'1C26", + "handler_summary": { + "instruction_count_scanned": 15, + "level_tests": [ + "F6D2.3", + "F6D1.1" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D2", + "source": "F107", + "table_address": 10028, + "table_address_hex": "H'272C", + "table_offset": 38 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 2, + "dirty": "F6F2.2", + "dispatcher": "1BCC", + "handler": 7256, + "handler_hex": "H'1C58", + "handler_summary": { + "instruction_count_scanned": 9, + "level_tests": [ + "F6D2.2" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D2", + "source": "F107", + "table_address": 10026, + "table_address_hex": "H'272A", + "table_offset": 36 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 1, + "dirty": "F6F2.2", + "dispatcher": "1BCC", + "handler": 7286, + "handler_hex": "H'1C76", + "handler_summary": { + "instruction_count_scanned": 9, + "level_tests": [ + "F6D2.1" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D2", + "source": "F107", + "table_address": 10024, + "table_address_hex": "H'2728", + "table_offset": 34 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 0, + "dirty": "F6F2.2", + "dispatcher": "1BCC", + "handler": 7316, + "handler_hex": "H'1C94", + "handler_summary": { + "instruction_count_scanned": 9, + "level_tests": [ + "F6D2.0" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D2", + "source": "F107", + "table_address": 10022, + "table_address_hex": "H'2726", + "table_offset": 32 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 7, + "dirty": "F6F2.1", + "dispatcher": "1B72", + "handler": 17885, + "handler_hex": "H'45DD", + "handler_summary": { + "instruction_count_scanned": 47, + "level_tests": [ + "F6D1.7" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D1", + "source": "F108", + "table_address": 10020, + "table_address_hex": "H'2724", + "table_offset": 30 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 6, + "dirty": "F6F2.1", + "dispatcher": "1B72", + "handler": 18163, + "handler_hex": "H'46F3", + "handler_summary": { + "instruction_count_scanned": 47, + "level_tests": [ + "F6D1.6" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D1", + "source": "F108", + "table_address": 10018, + "table_address_hex": "H'2722", + "table_offset": 28 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 5, + "dirty": "F6F2.1", + "dispatcher": "1B72", + "handler": 18914, + "handler_hex": "H'49E2", + "handler_summary": { + "instruction_count_scanned": 16, + "level_tests": [ + "F6D1.5" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D1", + "source": "F108", + "table_address": 10016, + "table_address_hex": "H'2720", + "table_offset": 26 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 4, + "dirty": "F6F2.1", + "dispatcher": "1B72", + "handler": 18969, + "handler_hex": "H'4A19", + "handler_summary": { + "instruction_count_scanned": 1, + "level_tests": [], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D1", + "source": "F108", + "table_address": 10014, + "table_address_hex": "H'271E", + "table_offset": 24 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 3, + "dirty": "F6F2.1", + "dispatcher": "1B72", + "handler": 18626, + "handler_hex": "H'48C2", + "handler_summary": { + "instruction_count_scanned": 15, + "level_tests": [ + "F6D1.3", + "F6D1.2" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D1", + "source": "F108", + "table_address": 10012, + "table_address_hex": "H'271C", + "table_offset": 22 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 2, + "dirty": "F6F2.1", + "dispatcher": "1B72", + "handler": 18581, + "handler_hex": "H'4895", + "handler_summary": { + "instruction_count_scanned": 15, + "level_tests": [ + "F6D1.2", + "F6D1.3" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D1", + "source": "F108", + "table_address": 10010, + "table_address_hex": "H'271A", + "table_offset": 20 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 1, + "dirty": "F6F2.1", + "dispatcher": "1B72", + "handler": 18302, + "handler_hex": "H'477E", + "handler_summary": { + "instruction_count_scanned": 47, + "level_tests": [ + "F6D1.1" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D1", + "source": "F108", + "table_address": 10008, + "table_address_hex": "H'2718", + "table_offset": 18 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 0, + "dirty": "F6F2.1", + "dispatcher": "1B72", + "handler": 18024, + "handler_hex": "H'4668", + "handler_summary": { + "instruction_count_scanned": 47, + "level_tests": [ + "F6D1.0" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D1", + "source": "F108", + "table_address": 10006, + "table_address_hex": "H'2716", + "table_offset": 16 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 7, + "dirty": "F6F2.0", + "dispatcher": "1B89", + "handler": 9448, + "handler_hex": "H'24E8", + "handler_summary": { + "instruction_count_scanned": 25, + "level_tests": [ + "F6D0.7" + ], + "report_selectors": [ + 143 + ], + "report_selectors_hex": [ + "0x008F" + ], + "state_writes": [ + "E91E" + ] + }, + "is_noop": false, + "known_report": "0x008F", + "shadow": "F6D0", + "source": "F109", + "table_address": 10004, + "table_address_hex": "H'2714", + "table_offset": 14 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 6, + "dirty": "F6F2.0", + "dispatcher": "1B89", + "handler": 9518, + "handler_hex": "H'252E", + "handler_summary": { + "instruction_count_scanned": 25, + "level_tests": [ + "F6D0.6" + ], + "report_selectors": [ + 143 + ], + "report_selectors_hex": [ + "0x008F" + ], + "state_writes": [ + "E91E" + ] + }, + "is_noop": false, + "known_report": "0x008F", + "shadow": "F6D0", + "source": "F109", + "table_address": 10002, + "table_address_hex": "H'2712", + "table_offset": 12 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 5, + "dirty": "F6F2.0", + "dispatcher": "1B89", + "handler": 9684, + "handler_hex": "H'25D4", + "handler_summary": { + "instruction_count_scanned": 34, + "level_tests": [ + "F6D0.5", + "F6D0.4" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D0", + "source": "F109", + "table_address": 10000, + "table_address_hex": "H'2710", + "table_offset": 10 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 4, + "dirty": "F6F2.0", + "dispatcher": "1B89", + "handler": 9588, + "handler_hex": "H'2574", + "handler_summary": { + "instruction_count_scanned": 34, + "level_tests": [ + "F6D0.4", + "F6D0.5" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6D0", + "source": "F109", + "table_address": 9998, + "table_address_hex": "H'270E", + "table_offset": 8 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 3, + "dirty": "F6F2.0", + "dispatcher": "1B89", + "handler": 9385, + "handler_hex": "H'24A9", + "handler_summary": { + "instruction_count_scanned": 22, + "level_tests": [ + "F6D0.3" + ], + "report_selectors": [ + 131 + ], + "report_selectors_hex": [ + "0x0083" + ], + "state_writes": [ + "E906" + ] + }, + "is_noop": false, + "known_report": "0x0083", + "shadow": "F6D0", + "source": "F109", + "table_address": 9996, + "table_address_hex": "H'270C", + "table_offset": 6 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 2, + "dirty": "F6F2.0", + "dispatcher": "1B89", + "handler": 9224, + "handler_hex": "H'2408", + "handler_summary": { + "instruction_count_scanned": 41, + "level_tests": [ + "F6D0.2", + "F6D0.1" + ], + "report_selectors": [ + 131 + ], + "report_selectors_hex": [ + "0x0083" + ], + "state_writes": [ + "E906" + ] + }, + "is_noop": false, + "known_report": "0x0083", + "shadow": "F6D0", + "source": "F109", + "table_address": 9994, + "table_address_hex": "H'270A", + "table_offset": 4 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 1, + "dirty": "F6F2.0", + "dispatcher": "1B89", + "handler": 9104, + "handler_hex": "H'2390", + "handler_summary": { + "instruction_count_scanned": 41, + "level_tests": [ + "F6D0.1", + "F6D0.2" + ], + "report_selectors": [ + 131 + ], + "report_selectors_hex": [ + "0x0083" + ], + "state_writes": [ + "E906" + ] + }, + "is_noop": false, + "known_report": "0x0083", + "shadow": "F6D0", + "source": "F109", + "table_address": 9992, + "table_address_hex": "H'2708", + "table_offset": 2 + }, + { + "bank": "IRQ4 A8 panel byte path", + "bit": 0, + "dirty": "F6F2.0", + "dispatcher": "1B89", + "handler": 7205, + "handler_hex": "H'1C25", + "handler_summary": {}, + "is_noop": true, + "known_report": "", + "shadow": "F6D0", + "source": "F109", + "table_address": 9990, + "table_address_hex": "H'2706", + "table_offset": 0 + }, + { + "bank": "IRQ3 A8 panel byte path", + "bit": 7, + "dirty": "F6F3.4", + "dispatcher": "1BE2", + "handler": 8433, + "handler_hex": "H'20F1", + "handler_summary": { + "instruction_count_scanned": 18, + "level_tests": [ + "F6DC.7" + ], + "report_selectors": [ + 185 + ], + "report_selectors_hex": [ + "0x00B9" + ], + "state_writes": [ + "E972" + ] + }, + "is_noop": false, + "known_report": "0x00B9", + "shadow": "F6DC", + "source": "F005", + "table_address": 10196, + "table_address_hex": "H'27D4", + "table_offset": 206 + }, + { + "bank": "IRQ3 A8 panel byte path", + "bit": 6, + "dirty": "F6F3.4", + "dispatcher": "1BE2", + "handler": 8516, + "handler_hex": "H'2144", + "handler_summary": { + "instruction_count_scanned": 9, + "level_tests": [ + "F6DC.6" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6DC", + "source": "F005", + "table_address": 10194, + "table_address_hex": "H'27D2", + "table_offset": 204 + }, + { + "bank": "IRQ3 A8 panel byte path", + "bit": 5, + "dirty": "F6F3.4", + "dispatcher": "1BE2", + "handler": 8708, + "handler_hex": "H'2204", + "handler_summary": { + "instruction_count_scanned": 21, + "level_tests": [ + "F6DC.5" + ], + "report_selectors": [ + 147 + ], + "report_selectors_hex": [ + "0x0093" + ], + "state_writes": [ + "E926" + ] + }, + "is_noop": false, + "known_report": "0x0093", + "shadow": "F6DC", + "source": "F005", + "table_address": 10192, + "table_address_hex": "H'27D0", + "table_offset": 202 + }, + { + "bank": "IRQ3 A8 panel byte path", + "bit": 4, + "dirty": "F6F3.4", + "dispatcher": "1BE2", + "handler": 8813, + "handler_hex": "H'226D", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6DC.4" + ], + "report_selectors": [ + 147 + ], + "report_selectors_hex": [ + "0x0093" + ], + "state_writes": [ + "E926" + ] + }, + "is_noop": false, + "known_report": "0x0093", + "shadow": "F6DC", + "source": "F005", + "table_address": 10190, + "table_address_hex": "H'27CE", + "table_offset": 200 + }, + { + "bank": "IRQ3 A8 panel byte path", + "bit": 3, + "dirty": "F6F3.4", + "dispatcher": "1BE2", + "handler": 8870, + "handler_hex": "H'22A6", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6DC.3" + ], + "report_selectors": [ + 147 + ], + "report_selectors_hex": [ + "0x0093" + ], + "state_writes": [ + "E926" + ] + }, + "is_noop": false, + "known_report": "0x0093", + "shadow": "F6DC", + "source": "F005", + "table_address": 10188, + "table_address_hex": "H'27CC", + "table_offset": 198 + }, + { + "bank": "IRQ3 A8 panel byte path", + "bit": 2, + "dirty": "F6F3.4", + "dispatcher": "1BE2", + "handler": 9040, + "handler_hex": "H'2350", + "handler_summary": { + "instruction_count_scanned": 19, + "level_tests": [ + "F6DC.2" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + "is_noop": false, + "known_report": "", + "shadow": "F6DC", + "source": "F005", + "table_address": 10186, + "table_address_hex": "H'27CA", + "table_offset": 196 + }, + { + "bank": "IRQ3 A8 panel byte path", + "bit": 1, + "dirty": "F6F3.4", + "dispatcher": "1BE2", + "handler": 8956, + "handler_hex": "H'22FC", + "handler_summary": { + "instruction_count_scanned": 14, + "level_tests": [ + "F6DC.1" + ], + "report_selectors": [ + 147 + ], + "report_selectors_hex": [ + "0x0093" + ], + "state_writes": [ + "E926" + ] + }, + "is_noop": false, + "known_report": "0x0093", + "shadow": "F6DC", + "source": "F005", + "table_address": 10184, + "table_address_hex": "H'27C8", + "table_offset": 194 + }, + { + "bank": "IRQ3 A8 panel byte path", + "bit": 0, + "dirty": "F6F3.4", + "dispatcher": "1BE2", + "handler": 8998, + "handler_hex": "H'2326", + "handler_summary": { + "instruction_count_scanned": 14, + "level_tests": [ + "F6DC.0" + ], + "report_selectors": [ + 147 + ], + "report_selectors_hex": [ + "0x0093" + ], + "state_writes": [ + "E926" + ] + }, + "is_noop": false, + "known_report": "0x0093", + "shadow": "F6DC", + "source": "F005", + "table_address": 10182, + "table_address_hex": "H'27C6", + "table_offset": 192 + }, + { + "bank": "IRQ3 A8 panel byte path", + "bit": 7, + "dirty": "F6F3.3", + "dispatcher": "1BF8", + "handler": 8206, + "handler_hex": "H'200E", + "handler_summary": { + "instruction_count_scanned": 20, + "level_tests": [ + "F6DB.7" + ], + "report_selectors": [ + 19 + ], + "report_selectors_hex": [ + "0x0013" + ], + "state_writes": [ + "E826" + ] + }, + "is_noop": false, + "known_report": "0x0013", + "shadow": "F6DB", + "source": "F006", + "table_address": 10180, + "table_address_hex": "H'27C4", + "table_offset": 190 + }, + { + "bank": "IRQ3 A8 panel byte path", + "bit": 6, + "dirty": "F6F3.3", + "dispatcher": "1BF8", + "handler": 7205, + "handler_hex": "H'1C25", + "handler_summary": {}, + "is_noop": true, + "known_report": "", + "shadow": "F6DB", + "source": "F006", + "table_address": 10178, + "table_address_hex": "H'27C2", + "table_offset": 188 + }, + { + "bank": "IRQ3 A8 panel byte path", + "bit": 5, + "dirty": "F6F3.3", + "dispatcher": "1BF8", + "handler": 8353, + "handler_hex": "H'20A1", + "handler_summary": { + "instruction_count_scanned": 11, + "level_tests": [ + "F6DB.5" + ], + "report_selectors": [ + 21 + ], + "report_selectors_hex": [ + "0x0015" + ], + "state_writes": [ + "E82A" + ] + }, + "is_noop": false, + "known_report": "CALL", + "shadow": "F6DB", + "source": "F006", + "table_address": 10176, + "table_address_hex": "H'27C0", + "table_offset": 186 + }, + { + "bank": "IRQ3 A8 panel byte path", + "bit": 4, + "dirty": "F6F3.3", + "dispatcher": "1BF8", + "handler": 7205, + "handler_hex": "H'1C25", + "handler_summary": {}, + "is_noop": true, + "known_report": "", + "shadow": "F6DB", + "source": "F006", + "table_address": 10174, + "table_address_hex": "H'27BE", + "table_offset": 184 + }, + { + "bank": "IRQ3 A8 panel byte path", + "bit": 3, + "dirty": "F6F3.3", + "dispatcher": "1BF8", + "handler": 8382, + "handler_hex": "H'20BE", + "handler_summary": { + "instruction_count_scanned": 19, + "level_tests": [ + "F6DB.3" + ], + "report_selectors": [ + 154 + ], + "report_selectors_hex": [ + "0x009A" + ], + "state_writes": [ + "E934" + ] + }, + "is_noop": false, + "known_report": "0x009A", + "shadow": "F6DB", + "source": "F006", + "table_address": 10172, + "table_address_hex": "H'27BC", + "table_offset": 182 + }, + { + "bank": "IRQ3 A8 panel byte path", + "bit": 2, + "dirty": "F6F3.3", + "dispatcher": "1BF8", + "handler": 7205, + "handler_hex": "H'1C25", + "handler_summary": {}, + "is_noop": true, + "known_report": "", + "shadow": "F6DB", + "source": "F006", + "table_address": 10170, + "table_address_hex": "H'27BA", + "table_offset": 180 + }, + { + "bank": "IRQ3 A8 panel byte path", + "bit": 1, + "dirty": "F6F3.3", + "dispatcher": "1BF8", + "handler": 7205, + "handler_hex": "H'1C25", + "handler_summary": {}, + "is_noop": true, + "known_report": "", + "shadow": "F6DB", + "source": "F006", + "table_address": 10168, + "table_address_hex": "H'27B8", + "table_offset": 178 + }, + { + "bank": "IRQ3 A8 panel byte path", + "bit": 0, + "dirty": "F6F3.3", + "dispatcher": "1BF8", + "handler": 7205, + "handler_hex": "H'1C25", + "handler_summary": {}, + "is_noop": true, + "known_report": "", + "shadow": "F6DB", + "source": "F006", + "table_address": 10166, + "table_address_hex": "H'27B6", + "table_offset": 176 + } + ], + "handler_summaries": [ + { + "handler": 7206, + "handler_hex": "H'1C26", + "instruction_count_scanned": 15, + "level_tests": [ + "F6D2.3", + "F6D1.1" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 7256, + "handler_hex": "H'1C58", + "instruction_count_scanned": 9, + "level_tests": [ + "F6D2.2" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 7286, + "handler_hex": "H'1C76", + "instruction_count_scanned": 9, + "level_tests": [ + "F6D2.1" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 7316, + "handler_hex": "H'1C94", + "instruction_count_scanned": 9, + "level_tests": [ + "F6D2.0" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 7346, + "handler_hex": "H'1CB2", + "instruction_count_scanned": 9, + "level_tests": [ + "F6D3.1" + ], + "report_selectors": [ + 26 + ], + "report_selectors_hex": [ + "0x001A" + ], + "state_writes": [ + "E834" + ] + }, + { + "handler": 7374, + "handler_hex": "H'1CCE", + "instruction_count_scanned": 12, + "level_tests": [ + "F6D3.2" + ], + "report_selectors": [ + 26 + ], + "report_selectors_hex": [ + "0x001A" + ], + "state_writes": [ + "E834" + ] + }, + { + "handler": 7412, + "handler_hex": "H'1CF4", + "instruction_count_scanned": 18, + "level_tests": [ + "F6D3.3" + ], + "report_selectors": [ + 26 + ], + "report_selectors_hex": [ + "0x001A" + ], + "state_writes": [ + "E834" + ] + }, + { + "handler": 7461, + "handler_hex": "H'1D25", + "instruction_count_scanned": 18, + "level_tests": [ + "F6D3.4" + ], + "report_selectors": [ + 26 + ], + "report_selectors_hex": [ + "0x001A" + ], + "state_writes": [ + "E834" + ] + }, + { + "handler": 7510, + "handler_hex": "H'1D56", + "instruction_count_scanned": 18, + "level_tests": [ + "F6D3.5" + ], + "report_selectors": [ + 26 + ], + "report_selectors_hex": [ + "0x001A" + ], + "state_writes": [ + "E834" + ] + }, + { + "handler": 7559, + "handler_hex": "H'1D87", + "instruction_count_scanned": 21, + "level_tests": [ + "F6D3.6" + ], + "report_selectors": [ + 151 + ], + "report_selectors_hex": [ + "0x0097" + ], + "state_writes": [ + "E92E" + ] + }, + { + "handler": 7630, + "handler_hex": "H'1DCE", + "instruction_count_scanned": 25, + "level_tests": [ + "F6D3.7" + ], + "report_selectors": [ + 150 + ], + "report_selectors_hex": [ + "0x0096" + ], + "state_writes": [ + "E92C" + ] + }, + { + "handler": 7712, + "handler_hex": "H'1E20", + "instruction_count_scanned": 41, + "level_tests": [ + "F6D4.0" + ], + "report_selectors": [ + 183, + 196, + 198, + 151 + ], + "report_selectors_hex": [ + "0x00B7", + "0x00C4", + "0x00C6", + "0x0097" + ], + "state_writes": [ + "E96E", + "E988", + "E98C", + "E92E" + ] + }, + { + "handler": 7849, + "handler_hex": "H'1EA9", + "instruction_count_scanned": 17, + "level_tests": [ + "F6D4.1" + ], + "report_selectors": [ + 248 + ], + "report_selectors_hex": [ + "0x00F8" + ], + "state_writes": [ + "E9F0" + ] + }, + { + "handler": 7902, + "handler_hex": "H'1EDE", + "instruction_count_scanned": 30, + "level_tests": [ + "F6D4.2" + ], + "report_selectors": [ + 23, + 24 + ], + "report_selectors_hex": [ + "0x0017", + "0x0018" + ], + "state_writes": [ + "E82E", + "E830" + ] + }, + { + "handler": 8000, + "handler_hex": "H'1F40", + "instruction_count_scanned": 15, + "level_tests": [ + "F6D4.3" + ], + "report_selectors": [ + 7 + ], + "report_selectors_hex": [ + "0x0007" + ], + "state_writes": [ + "E80E" + ] + }, + { + "handler": 8047, + "handler_hex": "H'1F6F", + "instruction_count_scanned": 13, + "level_tests": [ + "F6D4.4" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 8083, + "handler_hex": "H'1F93", + "instruction_count_scanned": 15, + "level_tests": [ + "F6D4.5" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 8206, + "handler_hex": "H'200E", + "instruction_count_scanned": 20, + "level_tests": [ + "F6DB.7" + ], + "report_selectors": [ + 19 + ], + "report_selectors_hex": [ + "0x0013" + ], + "state_writes": [ + "E826" + ] + }, + { + "handler": 8264, + "handler_hex": "H'2048", + "instruction_count_scanned": 25, + "level_tests": [ + "F6D4.6" + ], + "report_selectors": [ + 107 + ], + "report_selectors_hex": [ + "0x006B" + ], + "state_writes": [ + "E8D6" + ] + }, + { + "handler": 8353, + "handler_hex": "H'20A1", + "instruction_count_scanned": 11, + "level_tests": [ + "F6DB.5" + ], + "report_selectors": [ + 21 + ], + "report_selectors_hex": [ + "0x0015" + ], + "state_writes": [ + "E82A" + ] + }, + { + "handler": 8382, + "handler_hex": "H'20BE", + "instruction_count_scanned": 19, + "level_tests": [ + "F6DB.3" + ], + "report_selectors": [ + 154 + ], + "report_selectors_hex": [ + "0x009A" + ], + "state_writes": [ + "E934" + ] + }, + { + "handler": 8433, + "handler_hex": "H'20F1", + "instruction_count_scanned": 18, + "level_tests": [ + "F6DC.7" + ], + "report_selectors": [ + 185 + ], + "report_selectors_hex": [ + "0x00B9" + ], + "state_writes": [ + "E972" + ] + }, + { + "handler": 8516, + "handler_hex": "H'2144", + "instruction_count_scanned": 9, + "level_tests": [ + "F6DC.6" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 8708, + "handler_hex": "H'2204", + "instruction_count_scanned": 21, + "level_tests": [ + "F6DC.5" + ], + "report_selectors": [ + 147 + ], + "report_selectors_hex": [ + "0x0093" + ], + "state_writes": [ + "E926" + ] + }, + { + "handler": 8813, + "handler_hex": "H'226D", + "instruction_count_scanned": 20, + "level_tests": [ + "F6DC.4" + ], + "report_selectors": [ + 147 + ], + "report_selectors_hex": [ + "0x0093" + ], + "state_writes": [ + "E926" + ] + }, + { + "handler": 8870, + "handler_hex": "H'22A6", + "instruction_count_scanned": 20, + "level_tests": [ + "F6DC.3" + ], + "report_selectors": [ + 147 + ], + "report_selectors_hex": [ + "0x0093" + ], + "state_writes": [ + "E926" + ] + }, + { + "handler": 8956, + "handler_hex": "H'22FC", + "instruction_count_scanned": 14, + "level_tests": [ + "F6DC.1" + ], + "report_selectors": [ + 147 + ], + "report_selectors_hex": [ + "0x0093" + ], + "state_writes": [ + "E926" + ] + }, + { + "handler": 8998, + "handler_hex": "H'2326", + "instruction_count_scanned": 14, + "level_tests": [ + "F6DC.0" + ], + "report_selectors": [ + 147 + ], + "report_selectors_hex": [ + "0x0093" + ], + "state_writes": [ + "E926" + ] + }, + { + "handler": 9040, + "handler_hex": "H'2350", + "instruction_count_scanned": 19, + "level_tests": [ + "F6DC.2" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 9104, + "handler_hex": "H'2390", + "instruction_count_scanned": 41, + "level_tests": [ + "F6D0.1", + "F6D0.2" + ], + "report_selectors": [ + 131 + ], + "report_selectors_hex": [ + "0x0083" + ], + "state_writes": [ + "E906" + ] + }, + { + "handler": 9224, + "handler_hex": "H'2408", + "instruction_count_scanned": 41, + "level_tests": [ + "F6D0.2", + "F6D0.1" + ], + "report_selectors": [ + 131 + ], + "report_selectors_hex": [ + "0x0083" + ], + "state_writes": [ + "E906" + ] + }, + { + "handler": 9385, + "handler_hex": "H'24A9", + "instruction_count_scanned": 22, + "level_tests": [ + "F6D0.3" + ], + "report_selectors": [ + 131 + ], + "report_selectors_hex": [ + "0x0083" + ], + "state_writes": [ + "E906" + ] + }, + { + "handler": 9448, + "handler_hex": "H'24E8", + "instruction_count_scanned": 25, + "level_tests": [ + "F6D0.7" + ], + "report_selectors": [ + 143 + ], + "report_selectors_hex": [ + "0x008F" + ], + "state_writes": [ + "E91E" + ] + }, + { + "handler": 9518, + "handler_hex": "H'252E", + "instruction_count_scanned": 25, + "level_tests": [ + "F6D0.6" + ], + "report_selectors": [ + 143 + ], + "report_selectors_hex": [ + "0x008F" + ], + "state_writes": [ + "E91E" + ] + }, + { + "handler": 9588, + "handler_hex": "H'2574", + "instruction_count_scanned": 34, + "level_tests": [ + "F6D0.4", + "F6D0.5" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 9684, + "handler_hex": "H'25D4", + "instruction_count_scanned": 34, + "level_tests": [ + "F6D0.5", + "F6D0.4" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 17885, + "handler_hex": "H'45DD", + "instruction_count_scanned": 47, + "level_tests": [ + "F6D1.7" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 18024, + "handler_hex": "H'4668", + "instruction_count_scanned": 47, + "level_tests": [ + "F6D1.0" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 18163, + "handler_hex": "H'46F3", + "instruction_count_scanned": 47, + "level_tests": [ + "F6D1.6" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 18302, + "handler_hex": "H'477E", + "instruction_count_scanned": 47, + "level_tests": [ + "F6D1.1" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 18581, + "handler_hex": "H'4895", + "instruction_count_scanned": 15, + "level_tests": [ + "F6D1.2", + "F6D1.3" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 18626, + "handler_hex": "H'48C2", + "instruction_count_scanned": 15, + "level_tests": [ + "F6D1.3", + "F6D1.2" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 18914, + "handler_hex": "H'49E2", + "instruction_count_scanned": 16, + "level_tests": [ + "F6D1.5" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 18969, + "handler_hex": "H'4A19", + "instruction_count_scanned": 1, + "level_tests": [], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 18970, + "handler_hex": "H'4A1A", + "instruction_count_scanned": 20, + "level_tests": [ + "F6D7.7" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 19082, + "handler_hex": "H'4A8A", + "instruction_count_scanned": 20, + "level_tests": [ + "F6D7.6" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 19162, + "handler_hex": "H'4ADA", + "instruction_count_scanned": 20, + "level_tests": [ + "F6D7.5" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 19234, + "handler_hex": "H'4B22", + "instruction_count_scanned": 20, + "level_tests": [ + "F6D7.4" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 19302, + "handler_hex": "H'4B66", + "instruction_count_scanned": 20, + "level_tests": [ + "F6D7.2" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 19444, + "handler_hex": "H'4BF4", + "instruction_count_scanned": 20, + "level_tests": [ + "F6D7.1" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 19578, + "handler_hex": "H'4C7A", + "instruction_count_scanned": 20, + "level_tests": [ + "F6D6.7" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 19746, + "handler_hex": "H'4D22", + "instruction_count_scanned": 20, + "level_tests": [ + "F6D6.6" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 19850, + "handler_hex": "H'4D8A", + "instruction_count_scanned": 20, + "level_tests": [ + "F6D6.5" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 19918, + "handler_hex": "H'4DCE", + "instruction_count_scanned": 20, + "level_tests": [ + "F6D6.4" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 19998, + "handler_hex": "H'4E1E", + "instruction_count_scanned": 20, + "level_tests": [ + "F6D6.3" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 20078, + "handler_hex": "H'4E6E", + "instruction_count_scanned": 20, + "level_tests": [ + "F6D6.2" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 20162, + "handler_hex": "H'4EC2", + "instruction_count_scanned": 20, + "level_tests": [ + "F6D6.1" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 20230, + "handler_hex": "H'4F06", + "instruction_count_scanned": 20, + "level_tests": [ + "F6D5.7" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 20298, + "handler_hex": "H'4F4A", + "instruction_count_scanned": 20, + "level_tests": [ + "F6D5.6" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 20386, + "handler_hex": "H'4FA2", + "instruction_count_scanned": 20, + "level_tests": [ + "F6D5.5" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 20466, + "handler_hex": "H'4FF2", + "instruction_count_scanned": 20, + "level_tests": [ + "F6D5.4" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 20554, + "handler_hex": "H'504A", + "instruction_count_scanned": 34, + "level_tests": [ + "F6D5.3" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 21268, + "handler_hex": "H'5314", + "instruction_count_scanned": 21, + "level_tests": [ + "F6D5.2" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + }, + { + "handler": 21346, + "handler_hex": "H'5362", + "instruction_count_scanned": 20, + "level_tests": [ + "F6D5.1" + ], + "report_selectors": [], + "report_selectors_hex": [], + "state_writes": [] + } + ], + "kind": "panel_button_trace", + "known_paths": [ + { + "bank": "IRQ4 A8 panel byte path", + "bit": 3, + "dirty": "F6F2.4", + "dispatcher": "1BA0", + "handler": 8000, + "handler_hex": "H'1F40", + "handler_summary": { + "instruction_count_scanned": 15, + "level_tests": [ + "F6D4.3" + ], + "report_selectors": [ + 7 + ], + "report_selectors_hex": [ + "0x0007" + ], + "state_writes": [ + "E80E" + ] + }, + "is_noop": false, + "known_report": "CAM POWER", + "name": "CAM POWER", + "selector": 7, + "shadow": "F6D4", + "source": "F105", + "table_address": 10060, + "table_address_hex": "H'274C", + "table_offset": 70 + }, + { + "bank": "IRQ3 A8 panel byte path", + "bit": 5, + "dirty": "F6F3.3", + "dispatcher": "1BF8", + "handler": 8353, + "handler_hex": "H'20A1", + "handler_summary": { + "instruction_count_scanned": 11, + "level_tests": [ + "F6DB.5" + ], + "report_selectors": [ + 21 + ], + "report_selectors_hex": [ + "0x0015" + ], + "state_writes": [ + "E82A" + ] + }, + "is_noop": false, + "known_report": "CALL", + "name": "CALL", + "selector": 21, + "shadow": "F6DB", + "source": "F006", + "table_address": 10176, + "table_address_hex": "H'27C0", + "table_offset": 186 + } + ], + "noop_handler": 7205, + "noop_handler_hex": "H'1C25" +} diff --git a/build/panel_button_trace.md b/build/panel_button_trace.md new file mode 100644 index 0000000..b0f96bd --- /dev/null +++ b/build/panel_button_trace.md @@ -0,0 +1,64 @@ +# PT2 Known Button ROM Trace + +This report follows the panel button edge path from the serial-visible reports back into the ROM input scanner. +The key table is the indirect handler table at `H'2706`, used by `loc_1C0E` after byte-level panel input changes are detected. + +## Known Anchors + +### CAM POWER + +- Emitted selector: `0x0007` +- Handler: `H'1F40` +- Edge source: `F105 -> F6D4` via `F6F2.4` +- Trigger bit: `F6D4.3` +- Table slot: `H'274C` -> `H'1F40` +- Current-level tests: F6D4.3 +- State writes: E80E + +### CALL + +- Emitted selector: `0x0015` +- Handler: `H'20A1` +- Edge source: `F006 -> F6DB` via `F6F3.3` +- Trigger bit: `F6DB.5` +- Table slot: `H'27C0` -> `H'20A1` +- Current-level tests: F6DB.5 +- State writes: E82A + +## Button Matrix Entries With Serial Reports + +| Source | Shadow bit | Dirty | Handler | Selector(s) | State writes | +| --- | --- | --- | --- | --- | --- | +| `F105` | `F6D4.6` | `F6F2.4` | `H'2048` | `0x006B` | `E8D6` | +| `F105` | `F6D4.3` | `F6F2.4` | `H'1F40` | `0x0007` | `E80E` | +| `F105` | `F6D4.2` | `F6F2.4` | `H'1EDE` | `0x0017`, `0x0018` | `E82E`, `E830` | +| `F105` | `F6D4.1` | `F6F2.4` | `H'1EA9` | `0x00F8` | `E9F0` | +| `F105` | `F6D4.0` | `F6F2.4` | `H'1E20` | `0x00B7`, `0x00C4`, `0x00C6`, `0x0097` | `E96E`, `E988`, `E98C`, `E92E` | +| `F106` | `F6D3.7` | `F6F2.3` | `H'1DCE` | `0x0096` | `E92C` | +| `F106` | `F6D3.6` | `F6F2.3` | `H'1D87` | `0x0097` | `E92E` | +| `F106` | `F6D3.5` | `F6F2.3` | `H'1D56` | `0x001A` | `E834` | +| `F106` | `F6D3.4` | `F6F2.3` | `H'1D25` | `0x001A` | `E834` | +| `F106` | `F6D3.3` | `F6F2.3` | `H'1CF4` | `0x001A` | `E834` | +| `F106` | `F6D3.2` | `F6F2.3` | `H'1CCE` | `0x001A` | `E834` | +| `F106` | `F6D3.1` | `F6F2.3` | `H'1CB2` | `0x001A` | `E834` | +| `F109` | `F6D0.7` | `F6F2.0` | `H'24E8` | `0x008F` | `E91E` | +| `F109` | `F6D0.6` | `F6F2.0` | `H'252E` | `0x008F` | `E91E` | +| `F109` | `F6D0.3` | `F6F2.0` | `H'24A9` | `0x0083` | `E906` | +| `F109` | `F6D0.2` | `F6F2.0` | `H'2408` | `0x0083` | `E906` | +| `F109` | `F6D0.1` | `F6F2.0` | `H'2390` | `0x0083` | `E906` | +| `F005` | `F6DC.7` | `F6F3.4` | `H'20F1` | `0x00B9` | `E972` | +| `F005` | `F6DC.5` | `F6F3.4` | `H'2204` | `0x0093` | `E926` | +| `F005` | `F6DC.4` | `F6F3.4` | `H'226D` | `0x0093` | `E926` | +| `F005` | `F6DC.3` | `F6F3.4` | `H'22A6` | `0x0093` | `E926` | +| `F005` | `F6DC.1` | `F6F3.4` | `H'22FC` | `0x0093` | `E926` | +| `F005` | `F6DC.0` | `F6F3.4` | `H'2326` | `0x0093` | `E926` | +| `F006` | `F6DB.7` | `F6F3.3` | `H'200E` | `0x0013` | `E826` | +| `F006` | `F6DB.5` | `F6F3.3` | `H'20A1` | `0x0015` | `E82A` | +| `F006` | `F6DB.3` | `F6F3.3` | `H'20BE` | `0x009A` | `E934` | + +## Practical Read + +- CALL and CAM POWER do share the general panel edge path with many other buttons. +- The shared path is: panel byte snapshot -> shadow byte -> dirty bit -> `loc_1C0E` jump table -> handler -> `loc_3E54` report. +- Other buttons diverge in their handlers: many require `F731/F730/F791` session/menu gates, mutate page state, or emit different selectors. +- Some table entries are `H'1C25`, an immediate `RTS`, so those physical matrix positions are intentionally ignored in this firmware context. diff --git a/build/rom_f109_handlers.asm b/build/rom_f109_handlers.asm new file mode 100644 index 0000000..328d4eb --- /dev/null +++ b/build/rom_f109_handlers.asm @@ -0,0 +1,433 @@ +; H8/536 ROM disassembly +; input: ROM\M27C512@DIP28_1.BIN +; bytes: 65536 +; vector mode: min +; analysis: recursive trace from vectors +; +; Notes from the manual: +; - H8/536 uses the H8/500 CPU instruction set. +; - In minimum mode the reset vector at H'0000-H'0001 is a 16-bit PC. +; - The register field is H'FE80-H'FFFF; names below come from appendix B. +; - @aa:8 short absolute operands use BR as the upper address byte. +; - SCI baud inference uses section 14.2.8 BRR formulas when SMR/BRR are known. +; - LCD inference treats E-clock H'F200/H'F201 accesses as status/control and data candidates. +; - Pass --clock-hz to convert SCI BRR settings into numeric baud rates. +; - Cycle counts use Appendix A tables A-7/A-8 for on-chip access with no external wait states. + +; Memory Map +; H'0000-H'009F exception_vectors vectors +; H'00A0-H'00FF dtc_vectors dtc_vectors +; H'0100-H'F67F program_or_external program +; H'F680-H'FE7F on_chip_ram ram +; H'FE80-H'FFFF register_field registers + +; Vectors +; H'0000 reset -> vec_reset_1000 (H'1000) +; H'0004 invalid_instruction -> vec_reset_1000 (H'1000) +; H'0006 zero_divide -> vec_reset_1000 (H'1000) +; H'0008 trap_vs -> vec_reset_1000 (H'1000) +; H'0010 address_error -> vec_reset_1000 (H'1000) +; H'0012 trace -> vec_reset_1000 (H'1000) +; H'0016 nmi -> vec_nmi_4393 (H'4393) +; H'0020 trapa_0 -> vec_reset_1000 (H'1000) +; H'0022 trapa_1 -> vec_reset_1000 (H'1000) +; H'0024 trapa_2 -> vec_reset_1000 (H'1000) +; H'0026 trapa_3 -> vec_reset_1000 (H'1000) +; H'0028 trapa_4 -> vec_reset_1000 (H'1000) +; H'002A trapa_5 -> vec_reset_1000 (H'1000) +; H'002C trapa_6 -> vec_reset_1000 (H'1000) +; H'002E trapa_7 -> vec_reset_1000 (H'1000) +; H'0030 trapa_8 -> vec_reset_1000 (H'1000) +; H'0032 trapa_9 -> vec_reset_1000 (H'1000) +; H'0034 trapa_a -> vec_reset_1000 (H'1000) +; H'0036 trapa_b -> vec_reset_1000 (H'1000) +; H'0038 trapa_c -> vec_reset_1000 (H'1000) +; H'003A trapa_d -> vec_reset_1000 (H'1000) +; H'003C trapa_e -> vec_reset_1000 (H'1000) +; H'003E trapa_f -> vec_reset_1000 (H'1000) +; H'0040 irq0 -> vec_reset_1000 (H'1000) +; H'0042 interval_timer -> vec_interval_timer_BFC4 (H'BFC4) +; H'0048 irq1 -> vec_reset_1000 (H'1000) +; H'0050 irq2 -> vec_reset_1000 (H'1000) +; H'0052 irq3 -> vec_irq3_3C30 (H'3C30) +; H'0058 irq4 -> vec_irq4_3AC7 (H'3AC7) +; H'005A irq5 -> vec_reset_1000 (H'1000) +; H'0062 frt1_ocia -> vec_frt1_ocia_BEEA (H'BEEA) +; H'006A frt2_ocia -> vec_frt2_ocia_BF23 (H'BF23) +; H'0080 sci1_eri -> vec_sci1_eri_BB57 (H'BB57) +; H'0082 sci1_rxi -> vec_sci1_rxi_BB67 (H'BB67) +; H'0084 sci1_txi -> vec_sci1_txi_BA84 (H'BA84) +; H'0090 ad_adi -> vec_ad_adi_3D99 (H'3D99) + +; Symbols +; mem_E106 H'E106 program_or_external memory r=5 w=2 width=word +; mem_E110 H'E110 program_or_external memory r=7 w=0 width=word +; mem_E11E H'E11E program_or_external memory r=4 w=0 width=word +; mem_E506 H'E506 program_or_external memory r=2 w=0 width=word +; mem_E906 H'E906 program_or_external memory r=0 w=4 width=word +; mem_E91E H'E91E program_or_external memory r=0 w=2 width=word +; mem_E922 H'E922 program_or_external memory r=0 w=1 width=word +; mem_F404 H'F404 program_or_external memory r=11 w=0 width=byte +; ram_F6D0 H'F6D0 on_chip_ram ram r=13 w=0 width=byte +; ram_F6F4 H'F6F4 on_chip_ram ram r=0 w=2 width=word +; ram_F6F6 H'F6F6 on_chip_ram ram r=0 w=4 width=byte +; ram_F730 H'F730 on_chip_ram ram r=4 w=0 width=byte +; ram_F731 H'F731 on_chip_ram ram r=7 w=0 width=byte +; ram_F791 H'F791 on_chip_ram ram r=11 w=0 width=byte + +; Board Profile +; Board trace ties the H8/536 SCI1 pins to a MAX202 RS232 transceiver. +; H8 pin 66 P95/TXD (TXD) -> MAX202 pin 11 +; H8 pin 67 P96/RXD (RXD) -> MAX202 pin 12 +; SCI2 pin routing is disabled by SYSCR2.P9SCI2E=0 in the observed setup. + +; LCD/Text Scan +; search 'CONNECT': not literal, hits=0 +; LCD text candidates +; ... 1 more LCD text candidates + +2390: 15 F6 D0 F1 BTST.B #1, @H'F6D0 ; refs ram_F6D0 in on_chip_ram; cycles=7 +2394: 37 00 70 BEQ loc_2407 ; cycles=3/7 nt/t +2397: 15 F7 31 04 02 CMP:G.B #H'02, @H'F731 ; refs ram_F731 in on_chip_ram; cycles=6 +239C: 32 00 68 BHI loc_2407 ; cycles=3/7 nt/t +239F: 1D E1 10 FF BTST.W #15, @H'E110 ; refs mem_E110 in program_or_external; cycles=6 +23A3: 27 05 BEQ loc_23AA ; cycles=3/8 nt/t +23A5: 1E 03 40 BSR loc_26E8 ; cycles=14 +23A8: 20 5D BRA loc_2407 ; cycles=7 + +loc_23AA: +23AA: 15 F6 D0 F2 BTST.B #2, @H'F6D0 ; refs ram_F6D0 in on_chip_ram; cycles=7 +23AE: 36 00 CF BNE loc_2480 ; cycles=3/7 nt/t +23B1: 15 F7 30 F7 BTST.B #7, @H'F730 ; refs ram_F730 in on_chip_ram; cycles=6 +23B5: 27 35 BEQ loc_23EC ; cycles=3/8 nt/t +23B7: 1D E1 06 80 MOV:G.W @H'E106, R0 ; refs mem_E106 in program_or_external; cycles=6 + +loc_23BB: +23BB: A8 1B SHLR.W R0 ; cycles=3 + +loc_23BD: +23BD: A8 81 MOV:G.W R0, R1 ; cycles=3 +23BF: 27 26 BEQ loc_23E7 ; cycles=3/8 nt/t +23C1: 1D E5 06 51 AND.W @H'E506, R1 ; refs mem_E506 in program_or_external; cycles=6 +23C5: 0C FF C4 51 AND.W #H'FFC4, R1 ; cycles=4 +23C9: 27 F0 BEQ loc_23BB ; cycles=3/8 nt/t +23CB: 1D E9 06 91 MOV:G.W R1, @H'E906 ; refs mem_E906 in program_or_external; cycles=6 +23CF: 52 80 MOV:E.B #H'80, R2 ; dataflow R2=H'80; cycles=2 +23D1: 5B 00 83 MOV:I.W #H'0083, R3 ; dataflow R3=H'0083; cycles=3 +23D4: 15 F7 91 F7 BTST.B #7, @H'F791 ; refs ram_F791 in on_chip_ram; cycles=7 +23D8: 27 08 BEQ loc_23E2 ; cycles=3/7 nt/t +23DA: 15 F4 04 F5 BTST.B #5, @H'F404 ; refs mem_F404 in program_or_external; cycles=7 +23DE: 27 02 BEQ loc_23E2 ; cycles=3/7 nt/t +23E0: AB CE BSET.W #14, R3 ; cycles=3 + +loc_23E2: +23E2: 1E 1A 6F BSR loc_3E54 ; cycles=13 +23E5: 20 20 BRA loc_2407 ; cycles=8 + +loc_23E7: +23E7: 58 00 04 MOV:I.W #H'0004, R0 ; dataflow R0=H'0004; cycles=3 +23EA: 20 48 BRA loc_2434 ; cycles=7 + +loc_23EC: +23EC: 1D E1 06 D0 BCLR.W #0, @H'E106 ; refs mem_E106 in program_or_external; cycles=9 +23F0: 5C 00 00 MOV:I.W #H'0000, R4 ; dataflow R4=H'0000; cycles=3 +23F3: 5B 00 83 MOV:I.W #H'0083, R3 ; dataflow R3=H'0083; cycles=3 +23F6: 15 F7 91 F7 BTST.B #7, @H'F791 ; refs ram_F791 in on_chip_ram; cycles=7 +23FA: 27 08 BEQ loc_2404 ; cycles=3/7 nt/t +23FC: 15 F4 04 F5 BTST.B #5, @H'F404 ; refs mem_F404 in program_or_external; cycles=7 +2400: 27 02 BEQ loc_2404 ; cycles=3/7 nt/t +2402: AB CE BSET.W #14, R3 ; cycles=3 + +loc_2404: +2404: 1E F6 2E BSR loc_1A35 ; cycles=13 + +loc_2407: +2407: 19 RTS ; cycles=13 +2408: 15 F6 D0 F2 BTST.B #2, @H'F6D0 ; refs ram_F6D0 in on_chip_ram; cycles=7 +240C: 37 00 70 BEQ loc_247F ; cycles=3/7 nt/t +240F: 15 F7 31 04 02 CMP:G.B #H'02, @H'F731 ; refs ram_F731 in on_chip_ram; cycles=6 +2414: 32 00 68 BHI loc_247F ; cycles=3/7 nt/t +2417: 1D E1 10 FF BTST.W #15, @H'E110 ; refs mem_E110 in program_or_external; cycles=6 +241B: 27 05 BEQ loc_2422 ; cycles=3/8 nt/t +241D: 1E 02 C8 BSR loc_26E8 ; cycles=14 +2420: 20 5D BRA loc_247F ; cycles=7 + +loc_2422: +2422: 15 F6 D0 F1 BTST.B #1, @H'F6D0 ; refs ram_F6D0 in on_chip_ram; cycles=7 +2426: 26 58 BNE loc_2480 ; cycles=3/7 nt/t +2428: 15 F7 30 F7 BTST.B #7, @H'F730 ; refs ram_F730 in on_chip_ram; cycles=7 +242C: 27 36 BEQ loc_2464 ; cycles=3/7 nt/t +242E: 1D E1 06 80 MOV:G.W @H'E106, R0 ; refs mem_E106 in program_or_external; cycles=7 + +loc_2432: +2432: A8 1A SHLL.W R0 ; cycles=3 + +loc_2434: +2434: A8 81 MOV:G.W R0, R1 ; cycles=3 +2436: 27 26 BEQ loc_245E ; cycles=3/7 nt/t +2438: 1D E5 06 51 AND.W @H'E506, R1 ; refs mem_E506 in program_or_external; cycles=7 +243C: 0C FF C4 51 AND.W #H'FFC4, R1 ; cycles=4 +2440: 27 F0 BEQ loc_2432 ; cycles=3/7 nt/t +2442: 1D E9 06 91 MOV:G.W R1, @H'E906 ; refs mem_E906 in program_or_external; cycles=7 +2446: 52 80 MOV:E.B #H'80, R2 ; dataflow R2=H'80; cycles=2 +2448: 5B 00 83 MOV:I.W #H'0083, R3 ; dataflow R3=H'0083; cycles=3 +244B: 15 F7 91 F7 BTST.B #7, @H'F791 ; refs ram_F791 in on_chip_ram; cycles=6 +244F: 27 08 BEQ loc_2459 ; cycles=3/8 nt/t +2451: 15 F4 04 F5 BTST.B #5, @H'F404 ; refs mem_F404 in program_or_external; cycles=6 +2455: 27 02 BEQ loc_2459 ; cycles=3/8 nt/t +2457: AB CE BSET.W #14, R3 ; cycles=3 + +loc_2459: +2459: 1E 19 F8 BSR loc_3E54 ; cycles=14 +245C: 20 21 BRA loc_247F ; cycles=7 + +loc_245E: +245E: 58 80 00 MOV:I.W #H'8000, R0 ; dataflow R0=H'8000; cycles=3 +2461: 30 FF 59 BRA loc_23BD ; cycles=8 + +loc_2464: +2464: 1D E1 06 D0 BCLR.W #0, @H'E106 ; refs mem_E106 in program_or_external; cycles=9 +2468: 5C 00 01 MOV:I.W #H'0001, R4 ; dataflow R4=H'0001; cycles=3 +246B: 5B 00 83 MOV:I.W #H'0083, R3 ; dataflow R3=H'0083; cycles=3 +246E: 15 F7 91 F7 BTST.B #7, @H'F791 ; refs ram_F791 in on_chip_ram; cycles=7 +2472: 27 08 BEQ loc_247C ; cycles=3/7 nt/t +2474: 15 F4 04 F5 BTST.B #5, @H'F404 ; refs mem_F404 in program_or_external; cycles=7 +2478: 27 02 BEQ loc_247C ; cycles=3/7 nt/t +247A: AB CE BSET.W #14, R3 ; cycles=3 + +loc_247C: +247C: 1E F5 B6 BSR loc_1A35 ; cycles=13 + +loc_247F: +247F: 19 RTS ; cycles=13 + +loc_2480: +2480: 15 F7 30 F7 BTST.B #7, @H'F730 ; refs ram_F730 in on_chip_ram; cycles=7 +2484: 27 05 BEQ loc_248B ; cycles=3/7 nt/t +2486: 58 40 00 MOV:I.W #H'4000, R0 ; dataflow R0=H'4000; cycles=3 +2489: 20 03 BRA loc_248E ; cycles=8 + +loc_248B: +248B: 58 00 20 MOV:I.W #H'0020, R0 ; dataflow R0=H'0020; cycles=3 + +loc_248E: +248E: 1D E9 06 90 MOV:G.W R0, @H'E906 ; refs mem_E906 in program_or_external; cycles=7 +2492: 52 80 MOV:E.B #H'80, R2 ; dataflow R2=H'80; cycles=2 +2494: 5B 00 83 MOV:I.W #H'0083, R3 ; dataflow R3=H'0083; cycles=3 +2497: 15 F7 91 F7 BTST.B #7, @H'F791 ; refs ram_F791 in on_chip_ram; cycles=6 +249B: 27 08 BEQ loc_24A5 ; cycles=3/8 nt/t +249D: 15 F4 04 F5 BTST.B #5, @H'F404 ; refs mem_F404 in program_or_external; cycles=6 +24A1: 27 02 BEQ loc_24A5 ; cycles=3/8 nt/t +24A3: AB CE BSET.W #14, R3 ; cycles=3 + +loc_24A5: +24A5: 1E 19 AC BSR loc_3E54 ; cycles=14 +24A8: 19 RTS ; cycles=12 +24A9: 15 F6 D0 F3 BTST.B #3, @H'F6D0 ; refs ram_F6D0 in on_chip_ram; cycles=6 +24AD: 27 38 BEQ loc_24E7 ; cycles=3/8 nt/t +24AF: 15 F7 31 04 02 CMP:G.B #H'02, @H'F731 ; refs ram_F731 in on_chip_ram; cycles=6 +24B4: 22 31 BHI loc_24E7 ; cycles=3/7 nt/t +24B6: 1D E1 10 FF BTST.W #15, @H'E110 ; refs mem_E110 in program_or_external; cycles=7 +24BA: 27 05 BEQ loc_24C1 ; cycles=3/7 nt/t +24BC: 1E 02 29 BSR loc_26E8 ; cycles=13 +24BF: 20 26 BRA loc_24E7 ; cycles=8 + +loc_24C1: +24C1: 15 F7 30 F7 BTST.B #7, @H'F730 ; refs ram_F730 in on_chip_ram; cycles=6 +24C5: 27 20 BEQ loc_24E7 ; cycles=3/8 nt/t +24C7: 1D E1 06 80 MOV:G.W @H'E106, R0 ; refs mem_E106 in program_or_external; cycles=6 +24CB: A8 E0 BNOT.W #0, R0 ; cycles=3 +24CD: 1D E9 06 90 MOV:G.W R0, @H'E906 ; refs mem_E906 in program_or_external; cycles=6 +24D1: 52 80 MOV:E.B #H'80, R2 ; dataflow R2=H'80; cycles=2 +24D3: 5B 00 83 MOV:I.W #H'0083, R3 ; dataflow R3=H'0083; cycles=3 +24D6: 15 F7 91 F7 BTST.B #7, @H'F791 ; refs ram_F791 in on_chip_ram; cycles=7 +24DA: 27 08 BEQ loc_24E4 ; cycles=3/7 nt/t +24DC: 15 F4 04 F5 BTST.B #5, @H'F404 ; refs mem_F404 in program_or_external; cycles=7 +24E0: 27 02 BEQ loc_24E4 ; cycles=3/7 nt/t +24E2: AB CE BSET.W #14, R3 ; cycles=3 + +loc_24E4: +24E4: 1E 19 6D BSR loc_3E54 ; cycles=13 + +loc_24E7: +24E7: 19 RTS ; cycles=13 +24E8: 15 F6 D0 F7 BTST.B #7, @H'F6D0 ; refs ram_F6D0 in on_chip_ram; cycles=7 +24EC: 27 3F BEQ loc_252D ; cycles=3/7 nt/t +24EE: 15 F7 31 04 02 CMP:G.B #H'02, @H'F731 ; refs ram_F731 in on_chip_ram; cycles=7 +24F3: 22 38 BHI loc_252D ; cycles=3/8 nt/t +24F5: 1D E1 10 FE BTST.W #14, @H'E110 ; refs mem_E110 in program_or_external; cycles=6 +24F9: 27 05 BEQ loc_2500 ; cycles=3/8 nt/t +24FB: 1E 01 EA BSR loc_26E8 ; cycles=14 +24FE: 20 2D BRA loc_252D ; cycles=7 + +loc_2500: +2500: 15 F6 F6 13 CLR.B @H'F6F6 ; refs ram_F6F6 in on_chip_ram; cycles=9 +2504: 1D E1 1E 80 MOV:G.W @H'E11E, R0 ; refs mem_E11E in program_or_external; cycles=7 +2508: A8 FF BTST.W #15, R0 ; cycles=3 +250A: 26 05 BNE loc_2511 ; cycles=3/7 nt/t +250C: 58 80 00 MOV:I.W #H'8000, R0 ; dataflow R0=H'8000; cycles=3 +250F: 20 02 BRA loc_2513 ; cycles=8 + +loc_2511: +2511: A8 13 CLR.W R0 ; dataflow R0=H'0000; cycles=3 + +loc_2513: +2513: 1D E9 1E 90 MOV:G.W R0, @H'E91E ; refs mem_E91E in program_or_external; cycles=6 +2517: 52 80 MOV:E.B #H'80, R2 ; dataflow R2=H'80; cycles=2 +2519: 5B 00 8F MOV:I.W #H'008F, R3 ; dataflow R3=H'008F; cycles=3 +251C: 15 F7 91 F7 BTST.B #7, @H'F791 ; refs ram_F791 in on_chip_ram; cycles=7 +2520: 27 08 BEQ loc_252A ; cycles=3/7 nt/t +2522: 15 F4 04 F4 BTST.B #4, @H'F404 ; refs mem_F404 in program_or_external; cycles=7 +2526: 27 02 BEQ loc_252A ; cycles=3/7 nt/t +2528: AB CE BSET.W #14, R3 ; cycles=3 + +loc_252A: +252A: 1E 19 27 BSR loc_3E54 ; cycles=13 + +loc_252D: +252D: 19 RTS ; cycles=13 +252E: 15 F6 D0 F6 BTST.B #6, @H'F6D0 ; refs ram_F6D0 in on_chip_ram; cycles=7 +2532: 27 3F BEQ loc_2573 ; cycles=3/7 nt/t +2534: 15 F7 31 04 02 CMP:G.B #H'02, @H'F731 ; refs ram_F731 in on_chip_ram; cycles=7 +2539: 22 38 BHI loc_2573 ; cycles=3/8 nt/t +253B: 1D E1 10 FE BTST.W #14, @H'E110 ; refs mem_E110 in program_or_external; cycles=6 +253F: 27 05 BEQ loc_2546 ; cycles=3/8 nt/t +2541: 1E 01 A4 BSR loc_26E8 ; cycles=14 +2544: 20 2D BRA loc_2573 ; cycles=7 + +loc_2546: +2546: 15 F6 F6 13 CLR.B @H'F6F6 ; refs ram_F6F6 in on_chip_ram; cycles=9 +254A: 1D E1 1E 80 MOV:G.W @H'E11E, R0 ; refs mem_E11E in program_or_external; cycles=7 +254E: A8 FD BTST.W #13, R0 ; cycles=3 +2550: 26 05 BNE loc_2557 ; cycles=3/7 nt/t +2552: 58 20 00 MOV:I.W #H'2000, R0 ; dataflow R0=H'2000; cycles=3 +2555: 20 02 BRA loc_2559 ; cycles=8 + +loc_2557: +2557: A8 13 CLR.W R0 ; dataflow R0=H'0000; cycles=3 + +loc_2559: +2559: 1D E9 1E 90 MOV:G.W R0, @H'E91E ; refs mem_E91E in program_or_external; cycles=6 +255D: 52 80 MOV:E.B #H'80, R2 ; dataflow R2=H'80; cycles=2 +255F: 5B 00 8F MOV:I.W #H'008F, R3 ; dataflow R3=H'008F; cycles=3 +2562: 15 F7 91 F7 BTST.B #7, @H'F791 ; refs ram_F791 in on_chip_ram; cycles=7 +2566: 27 08 BEQ loc_2570 ; cycles=3/7 nt/t +2568: 15 F4 04 F4 BTST.B #4, @H'F404 ; refs mem_F404 in program_or_external; cycles=7 +256C: 27 02 BEQ loc_2570 ; cycles=3/7 nt/t +256E: AB CE BSET.W #14, R3 ; cycles=3 + +loc_2570: +2570: 1E 18 E1 BSR loc_3E54 ; cycles=13 + +loc_2573: +2573: 19 RTS ; cycles=13 +2574: 15 F6 D0 F4 BTST.B #4, @H'F6D0 ; refs ram_F6D0 in on_chip_ram; cycles=7 +2578: 37 01 45 BEQ loc_26C0 ; cycles=3/7 nt/t +257B: 15 F7 31 04 02 CMP:G.B #H'02, @H'F731 ; refs ram_F731 in on_chip_ram; cycles=6 +2580: 22 51 BHI loc_25D3 ; cycles=3/7 nt/t +2582: 1D E1 10 FE BTST.W #14, @H'E110 ; refs mem_E110 in program_or_external; cycles=7 +2586: 27 05 BEQ loc_258D ; cycles=3/7 nt/t +2588: 1E 01 5D BSR loc_26E8 ; cycles=13 +258B: 20 46 BRA loc_25D3 ; cycles=8 + +loc_258D: +258D: 1D E1 1E 80 MOV:G.W @H'E11E, R0 ; refs mem_E11E in program_or_external; cycles=6 +2591: A8 FF BTST.W #15, R0 ; cycles=3 +2593: 26 06 BNE loc_259B ; cycles=3/8 nt/t +2595: A8 FD BTST.W #13, R0 ; cycles=3 +2597: 26 26 BNE loc_25BF ; cycles=3/8 nt/t +2599: 20 38 BRA loc_25D3 ; cycles=8 + +loc_259B: +259B: 15 F6 D0 F5 BTST.B #5, @H'F6D0 ; refs ram_F6D0 in on_chip_ram; cycles=6 +259F: 27 05 BEQ loc_25A6 ; cycles=3/8 nt/t +25A1: 1E 00 8F BSR loc_2633 ; cycles=14 +25A4: 20 2D BRA loc_25D3 ; cycles=7 + +loc_25A6: +25A6: 5C 00 00 MOV:I.W #H'0000, R4 ; dataflow R4=H'0000; cycles=3 +25A9: 5B 00 91 MOV:I.W #H'0091, R3 ; dataflow R3=H'0091; cycles=3 +25AC: 15 F7 91 F7 BTST.B #7, @H'F791 ; refs ram_F791 in on_chip_ram; cycles=7 +25B0: 27 08 BEQ loc_25BA ; cycles=3/7 nt/t +25B2: 15 F4 04 F4 BTST.B #4, @H'F404 ; refs mem_F404 in program_or_external; cycles=7 +25B6: 27 02 BEQ loc_25BA ; cycles=3/7 nt/t +25B8: AB CE BSET.W #14, R3 ; cycles=3 + +loc_25BA: +25BA: 1E F4 78 BSR loc_1A35 ; cycles=13 +25BD: 20 14 BRA loc_25D3 ; cycles=8 + +loc_25BF: +25BF: 15 F6 D0 F5 BTST.B #5, @H'F6D0 ; refs ram_F6D0 in on_chip_ram; cycles=6 +25C3: 27 05 BEQ loc_25CA ; cycles=3/8 nt/t +25C5: 1E 00 FF BSR loc_26C7 ; cycles=14 +25C8: 20 09 BRA loc_25D3 ; cycles=7 + +loc_25CA: +25CA: 15 F6 F6 06 C0 MOV:G.B #H'C0, @H'F6F6 ; refs ram_F6F6 in on_chip_ram; cycles=9 +25CF: 1D F6 F4 13 CLR.W @H'F6F4 ; refs ram_F6F4 in on_chip_ram; cycles=8 + +loc_25D3: +25D3: 19 RTS ; cycles=13 +25D4: 15 F6 D0 F5 BTST.B #5, @H'F6D0 ; refs ram_F6D0 in on_chip_ram; cycles=7 +25D8: 37 00 E5 BEQ loc_26C0 ; cycles=3/7 nt/t +25DB: 15 F7 31 04 02 CMP:G.B #H'02, @H'F731 ; refs ram_F731 in on_chip_ram; cycles=6 +25E0: 22 50 BHI loc_2632 ; cycles=3/7 nt/t +25E2: 1D E1 10 FE BTST.W #14, @H'E110 ; refs mem_E110 in program_or_external; cycles=7 +25E6: 27 05 BEQ loc_25ED ; cycles=3/7 nt/t +25E8: 1E 00 FD BSR loc_26E8 ; cycles=13 +25EB: 20 45 BRA loc_2632 ; cycles=8 + +loc_25ED: +25ED: 1D E1 1E 80 MOV:G.W @H'E11E, R0 ; refs mem_E11E in program_or_external; cycles=6 +25F1: A8 FF BTST.W #15, R0 ; cycles=3 +25F3: 26 06 BNE loc_25FB ; cycles=3/8 nt/t +25F5: A8 FD BTST.W #13, R0 ; cycles=3 +25F7: 26 25 BNE loc_261E ; cycles=3/8 nt/t +25F9: 20 37 BRA loc_2632 ; cycles=8 + +loc_25FB: +25FB: 15 F6 D0 F4 BTST.B #4, @H'F6D0 ; refs ram_F6D0 in on_chip_ram; cycles=6 +25FF: 27 04 BEQ loc_2605 ; cycles=3/8 nt/t +2601: 0E 30 BSR loc_2633 ; cycles=14 +2603: 20 2D BRA loc_2632 ; cycles=8 + +loc_2605: +2605: 5C 00 01 MOV:I.W #H'0001, R4 ; dataflow R4=H'0001; cycles=3 +2608: 5B 00 91 MOV:I.W #H'0091, R3 ; dataflow R3=H'0091; cycles=3 +260B: 15 F7 91 F7 BTST.B #7, @H'F791 ; refs ram_F791 in on_chip_ram; cycles=6 +260F: 27 08 BEQ loc_2619 ; cycles=3/8 nt/t +2611: 15 F4 04 F4 BTST.B #4, @H'F404 ; refs mem_F404 in program_or_external; cycles=6 +2615: 27 02 BEQ loc_2619 ; cycles=3/8 nt/t +2617: AB CE BSET.W #14, R3 ; cycles=3 + +loc_2619: +2619: 1E F4 19 BSR loc_1A35 ; cycles=14 +261C: 20 14 BRA loc_2632 ; cycles=7 + +loc_261E: +261E: 15 F6 D0 F4 BTST.B #4, @H'F6D0 ; refs ram_F6D0 in on_chip_ram; cycles=7 +2622: 27 05 BEQ loc_2629 ; cycles=3/7 nt/t +2624: 1E 00 A0 BSR loc_26C7 ; cycles=13 +2627: 20 09 BRA loc_2632 ; cycles=8 + +loc_2629: +2629: 15 F6 F6 06 80 MOV:G.B #H'80, @H'F6F6 ; refs ram_F6F6 in on_chip_ram; cycles=9 +262E: 1D F6 F4 13 CLR.W @H'F6F4 ; refs ram_F6F4 in on_chip_ram; cycles=9 + +loc_2632: +2632: 19 RTS ; cycles=12 + +loc_2633: +2633: 1D E9 22 07 80 00 MOV:G.W #H'8000, @H'E922 ; refs mem_E922 in program_or_external; cycles=9 +2639: 52 80 MOV:E.B #H'80, R2 ; dataflow R2=H'80; cycles=2 +263B: 5B 00 91 MOV:I.W #H'0091, R3 ; dataflow R3=H'0091; cycles=3 +263E: 15 F7 91 F7 BTST.B #7, @H'F791 ; refs ram_F791 in on_chip_ram; cycles=7 +2642: 27 08 BEQ loc_264C ; cycles=3/7 nt/t +2644: 15 F4 04 F4 BTST.B #4, @H'F404 ; refs mem_F404 in program_or_external; cycles=7 +2648: 27 02 BEQ loc_264C ; cycles=3/7 nt/t +264A: AB CE BSET.W #14, R3 ; cycles=3 + +loc_264C: +264C: 1E 18 05 BSR loc_3E54 ; cycles=13 +264F: 19 RTS ; cycles=13 diff --git a/build/rom_f109_handlers.json b/build/rom_f109_handlers.json new file mode 100644 index 0000000..1af0eac --- /dev/null +++ b/build/rom_f109_handlers.json @@ -0,0 +1,16353 @@ +{ + "vectors": [ + { + "address": 0, + "name": "reset", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 4, + "name": "invalid_instruction", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 6, + "name": "zero_divide", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 8, + "name": "trap_vs", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 16, + "name": "address_error", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 18, + "name": "trace", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 22, + "name": "nmi", + "target": 17299, + "target_label": "vec_nmi_4393" + }, + { + "address": 32, + "name": "trapa_0", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 34, + "name": "trapa_1", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 36, + "name": "trapa_2", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 38, + "name": "trapa_3", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 40, + "name": "trapa_4", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 42, + "name": "trapa_5", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 44, + "name": "trapa_6", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 46, + "name": "trapa_7", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 48, + "name": "trapa_8", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 50, + "name": "trapa_9", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 52, + "name": "trapa_a", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 54, + "name": "trapa_b", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 56, + "name": "trapa_c", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 58, + "name": "trapa_d", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 60, + "name": "trapa_e", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 62, + "name": "trapa_f", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 64, + "name": "irq0", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 66, + "name": "interval_timer", + "target": 49092, + "target_label": "vec_interval_timer_BFC4" + }, + { + "address": 72, + "name": "irq1", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 80, + "name": "irq2", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 82, + "name": "irq3", + "target": 15408, + "target_label": "vec_irq3_3C30" + }, + { + "address": 88, + "name": "irq4", + "target": 15047, + "target_label": "vec_irq4_3AC7" + }, + { + "address": 90, + "name": "irq5", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 98, + "name": "frt1_ocia", + "target": 48874, + "target_label": "vec_frt1_ocia_BEEA" + }, + { + "address": 106, + "name": "frt2_ocia", + "target": 48931, + "target_label": "vec_frt2_ocia_BF23" + }, + { + "address": 128, + "name": "sci1_eri", + "target": 47959, + "target_label": "vec_sci1_eri_BB57" + }, + { + "address": 130, + "name": "sci1_rxi", + "target": 47975, + "target_label": "vec_sci1_rxi_BB67" + }, + { + "address": 132, + "name": "sci1_txi", + "target": 47748, + "target_label": "vec_sci1_txi_BA84" + }, + { + "address": 144, + "name": "ad_adi", + "target": 15769, + "target_label": "vec_ad_adi_3D99" + } + ], + "dtc_vectors": [], + "memory_regions": [ + { + "name": "exception_vectors", + "start": 0, + "end": 159, + "kind": "vectors", + "manual": "section 2 address space" + }, + { + "name": "dtc_vectors", + "start": 160, + "end": 255, + "kind": "dtc_vectors", + "manual": "section 2 address space" + }, + { + "name": "program_or_external", + "start": 256, + "end": 63103, + "kind": "program", + "manual": "section 2/17 mode-dependent ROM or external space" + }, + { + "name": "on_chip_ram", + "start": 63104, + "end": 65151, + "kind": "ram", + "manual": "section 16 RAM" + }, + { + "name": "register_field", + "start": 65152, + "end": 65535, + "kind": "registers", + "manual": "appendix B register map" + } + ], + "data_candidates": { + "strings": [], + "pointer_tables": [] + }, + "call_graph": { + "nodes": [ + { + "start": 9779, + "label": "loc_2633", + "sources": [], + "instruction_count": 10, + "end": 9807, + "calls": [ + 15956 + ], + "unresolved_calls": 0 + } + ], + "edges": [ + { + "from": 9779, + "from_label": "loc_2633", + "to": 15956, + "to_label": "loc_3E54", + "call_site": 9804 + } + ] + }, + "timing_summary": { + "blocks": [], + "loops": [] + }, + "sci": { + "clock_hz": null, + "formulas": { + "async": "B = clock_hz / (64 * 2^(2n) * (N + 1))", + "sync": "B = clock_hz / (8 * 2^(2n) * (N + 1))" + }, + "manual_references": [ + "Manual/0900766b802125d0.md:15837 SMR selects SCI mode and CKS1/CKS0 internal clock source", + "Manual/0900766b802125d0.md:16027 SCR.CKE1 selects internal or external clock source", + "Manual/0900766b802125d0.md:16177 BRR and SMR.CKS determine the baud-rate generator", + "Manual/0900766b802125d0.md:16303 asynchronous BRR formula", + "Manual/0900766b802125d0.md:16379 synchronous BRR formula", + "Manual/0900766b802125d0.md:16410 SCI clock source selection tables" + ], + "channels": { + "SCI1": { + "writes": [], + "configurations": [] + }, + "SCI2": { + "writes": [], + "configurations": [] + } + } + }, + "sci_protocol": { + "manual_references": [ + "Manual/0900766b802125d0.md:15748 SCI register map for RDR/TDR/SCR/SSR", + "Manual/0900766b802125d0.md:15794 RDR stores received data and is CPU-readable", + "Manual/0900766b802125d0.md:15823 TDR holds the next byte to transmit", + "Manual/0900766b802125d0.md:15976 SCR.TIE enables/disables TXI on TDRE", + "Manual/0900766b802125d0.md:15993 SCR.RIE enables RXI and ERI", + "Manual/0900766b802125d0.md:16008 SCR.TE enables the transmitter", + "Manual/0900766b802125d0.md:16028 SCR.RE enables the receiver", + "Manual/0900766b802125d0.md:16090 SSR flags are cleared by writing zero", + "Manual/0900766b802125d0.md:16100 SSR.TDRE means TDR can accept the next byte", + "Manual/0900766b802125d0.md:16116 SSR.RDRF means received data reached RDR", + "Manual/0900766b802125d0.md:16127 SSR.ORER reports receive overrun", + "Manual/0900766b802125d0.md:16140 SSR.FER reports framing errors", + "Manual/0900766b802125d0.md:16147 SSR.PER reports parity errors" + ], + "channels": { + "SCI1": { + "events": [] + }, + "SCI2": { + "events": [] + } + }, + "events": [] + }, + "serial_reconstruction": { + "kind": "serial_reconstruction", + "candidates": [], + "ram_roles": [], + "evidence": [], + "required_evidence": { + "tx": [ + "tx_buffer_region", + "tx_checksum_seed", + "checksum_byte", + "xor_checksum_chain", + "initial_send_from_buffer_start", + "tx_index_initialized_to_one", + "tx_isr_indexed_send", + "tx_index_increment", + "tx_index_compare_frame_length" + ], + "rx": [ + "rx_rdr_read", + "rx_indexed_store", + "rx_index_increment_store", + "rx_isr_compare_frame_length", + "rx_complete_timer", + "rx_processor_requires_six_bytes", + "rx_copy_capture_to_frame_buffer", + "rx_checksum_seed", + "rx_xor_checksum_validation" + ] + } + }, + "board_profile": { + "board": "sony_rcp_tx7", + "name": "Sony RCP-TX7", + "summary": "Board trace ties the H8/536 SCI1 pins to a MAX202 RS232 transceiver.", + "manual_references": [ + "Manual/0900766b802125d0.md:2417 FP-80 H8/536 pin 66 is P95/TXD", + "Manual/0900766b802125d0.md:2418 FP-80 H8/536 pin 67 is P96/RXD", + "Manual/0900766b802125d0.md:11192 Port 9 carries SCI1 and SCI2 serial signals", + "Manual/0900766b802125d0.md:11201 P96 is RXD1 input", + "Manual/0900766b802125d0.md:11202 P95 is TXD1 output", + "Manual/0900766b802125d0.md:15725 SCI1 RXD input pin", + "Manual/0900766b802125d0.md:15726 SCI1 TXD output pin", + "Manual/0900766b802125d0.md:15750 SCI register table starts with SCI1 RDR/TDR/SMR/SCR/SSR/BRR", + "Manual/0900766b802125d0.md:15758 SCI register table lists SCI2 RDR/TDR/SMR/SCR/SSR/BRR", + "Manual/0900766b802125d0.md:15794 RDR receive data register", + "Manual/0900766b802125d0.md:15823 TDR transmit data register", + "Manual/0900766b802125d0.md:15969 SCR enables and disables SCI functions", + "Manual/0900766b802125d0.md:16009 SCR.TE makes the TXD pin output", + "Manual/0900766b802125d0.md:16029 SCR.RE makes the RXD pin input", + "Manual/0900766b802125d0.md:16090 SSR contains transmit/receive status flags", + "Manual/0900766b802125d0.md:10560 SYSCR2 controls port 9 pin functions", + "Manual/0900766b802125d0.md:10631 SYSCR2.P9SCI2E controls the SCI2 functions of P92-P94" + ], + "traces": [ + { + "channel": "SCI1", + "signal": "TXD", + "h8_pin": 66, + "h8_pin_name": "P95/TXD", + "h8_function": "TXD1", + "max202_pin": 11, + "evidence": "MAX202 pin 11 traces to H8 pin 66" + }, + { + "channel": "SCI1", + "signal": "RXD", + "h8_pin": 67, + "h8_pin_name": "P96/RXD", + "h8_function": "RXD1", + "max202_pin": 12, + "evidence": "MAX202 pin 12 traces to H8 pin 67" + } + ], + "channels": { + "SCI1": { + "traced_to_max202": true, + "path": "RS232/MAX202", + "pins": [ + { + "channel": "SCI1", + "signal": "TXD", + "h8_pin": 66, + "h8_pin_name": "P95/TXD", + "h8_function": "TXD1", + "max202_pin": 11, + "evidence": "MAX202 pin 11 traces to H8 pin 66" + }, + { + "channel": "SCI1", + "signal": "RXD", + "h8_pin": 67, + "h8_pin_name": "P96/RXD", + "h8_function": "RXD1", + "max202_pin": 12, + "evidence": "MAX202 pin 12 traces to H8 pin 67" + } + ], + "scr": { + "value": 12, + "value_hex": "H'0C", + "tie": false, + "rie": false, + "tx_enabled": false, + "rx_enabled": false + }, + "accesses": [] + }, + "SCI2": { + "traced_to_max202": false, + "path": null, + "note": "Sony RCP-TX7 MAX202 board traces are on SCI1 P95/P96, not SCI2 P92/P93.", + "p9sci2e": false, + "scr": { + "value": 12, + "value_hex": "H'0C", + "tie": false, + "rie": false, + "tx_enabled": false, + "rx_enabled": false + }, + "accesses": [] + } + }, + "instructions": {}, + "state": { + "SYSCR2": { + "value": 128, + "value_hex": "H'80" + }, + "P9SCI2E": false + } + }, + "peripheral_access": { + "manual_references": [ + "Manual/0900766b802125d0.md:12185 FRT FRC/OCRA/OCRB/ICR use TEMP for 16-bit CPU access", + "Manual/0900766b802125d0.md:12193 FRT byte access order is upper byte then lower byte", + "Manual/0900766b802125d0.md:12212 OCRA/OCRB reads are direct; writes still use TEMP", + "Manual/0900766b802125d0.md:17546 A/D ADDRA-ADDRD lower byte is accessed through TEMP", + "Manual/0900766b802125d0.md:17556 A/D full-result byte reads must be upper byte then lower byte" + ], + "warnings": [] + }, + "indirect_flow": { + "sites": [] + }, + "dataflow": { + "blocks": [ + { + "start": 9104, + "instructions": [ + 9104, + 9108 + ], + "end": 9108, + "end_exclusive": 9111 + }, + { + "start": 9111, + "instructions": [ + 9111, + 9116 + ], + "end": 9116, + "end_exclusive": 9119 + }, + { + "start": 9119, + "instructions": [ + 9119, + 9123 + ], + "end": 9123, + "end_exclusive": 9125 + }, + { + "start": 9125, + "instructions": [ + 9125, + 9128 + ], + "end": 9128, + "end_exclusive": 9130 + }, + { + "start": 9130, + "instructions": [ + 9130, + 9134 + ], + "end": 9134, + "end_exclusive": 9137 + }, + { + "start": 9137, + "instructions": [ + 9137, + 9141 + ], + "end": 9141, + "end_exclusive": 9143 + }, + { + "start": 9143, + "instructions": [ + 9143 + ], + "end": 9143, + "end_exclusive": 9147 + }, + { + "start": 9147, + "instructions": [ + 9147 + ], + "end": 9147, + "end_exclusive": 9149 + }, + { + "start": 9149, + "instructions": [ + 9149, + 9151 + ], + "end": 9151, + "end_exclusive": 9153 + }, + { + "start": 9153, + "instructions": [ + 9153, + 9157, + 9161 + ], + "end": 9161, + "end_exclusive": 9163 + }, + { + "start": 9163, + "instructions": [ + 9163, + 9167, + 9169, + 9172, + 9176 + ], + "end": 9176, + "end_exclusive": 9178 + }, + { + "start": 9178, + "instructions": [ + 9178, + 9182 + ], + "end": 9182, + "end_exclusive": 9184 + }, + { + "start": 9184, + "instructions": [ + 9184 + ], + "end": 9184, + "end_exclusive": 9186 + }, + { + "start": 9186, + "instructions": [ + 9186, + 9189 + ], + "end": 9189, + "end_exclusive": 9191 + }, + { + "start": 9191, + "instructions": [ + 9191, + 9194 + ], + "end": 9194, + "end_exclusive": 9196 + }, + { + "start": 9196, + "instructions": [ + 9196, + 9200, + 9203, + 9206, + 9210 + ], + "end": 9210, + "end_exclusive": 9212 + }, + { + "start": 9212, + "instructions": [ + 9212, + 9216 + ], + "end": 9216, + "end_exclusive": 9218 + }, + { + "start": 9218, + "instructions": [ + 9218 + ], + "end": 9218, + "end_exclusive": 9220 + }, + { + "start": 9220, + "instructions": [ + 9220 + ], + "end": 9220, + "end_exclusive": 9223 + }, + { + "start": 9223, + "instructions": [ + 9223 + ], + "end": 9223, + "end_exclusive": 9224 + }, + { + "start": 9224, + "instructions": [ + 9224, + 9228 + ], + "end": 9228, + "end_exclusive": 9231 + }, + { + "start": 9231, + "instructions": [ + 9231, + 9236 + ], + "end": 9236, + "end_exclusive": 9239 + }, + { + "start": 9239, + "instructions": [ + 9239, + 9243 + ], + "end": 9243, + "end_exclusive": 9245 + }, + { + "start": 9245, + "instructions": [ + 9245, + 9248 + ], + "end": 9248, + "end_exclusive": 9250 + }, + { + "start": 9250, + "instructions": [ + 9250, + 9254 + ], + "end": 9254, + "end_exclusive": 9256 + }, + { + "start": 9256, + "instructions": [ + 9256, + 9260 + ], + "end": 9260, + "end_exclusive": 9262 + }, + { + "start": 9262, + "instructions": [ + 9262 + ], + "end": 9262, + "end_exclusive": 9266 + }, + { + "start": 9266, + "instructions": [ + 9266 + ], + "end": 9266, + "end_exclusive": 9268 + }, + { + "start": 9268, + "instructions": [ + 9268, + 9270 + ], + "end": 9270, + "end_exclusive": 9272 + }, + { + "start": 9272, + "instructions": [ + 9272, + 9276, + 9280 + ], + "end": 9280, + "end_exclusive": 9282 + }, + { + "start": 9282, + "instructions": [ + 9282, + 9286, + 9288, + 9291, + 9295 + ], + "end": 9295, + "end_exclusive": 9297 + }, + { + "start": 9297, + "instructions": [ + 9297, + 9301 + ], + "end": 9301, + "end_exclusive": 9303 + }, + { + "start": 9303, + "instructions": [ + 9303 + ], + "end": 9303, + "end_exclusive": 9305 + }, + { + "start": 9305, + "instructions": [ + 9305, + 9308 + ], + "end": 9308, + "end_exclusive": 9310 + }, + { + "start": 9310, + "instructions": [ + 9310, + 9313 + ], + "end": 9313, + "end_exclusive": 9316 + }, + { + "start": 9316, + "instructions": [ + 9316, + 9320, + 9323, + 9326, + 9330 + ], + "end": 9330, + "end_exclusive": 9332 + }, + { + "start": 9332, + "instructions": [ + 9332, + 9336 + ], + "end": 9336, + "end_exclusive": 9338 + }, + { + "start": 9338, + "instructions": [ + 9338 + ], + "end": 9338, + "end_exclusive": 9340 + }, + { + "start": 9340, + "instructions": [ + 9340 + ], + "end": 9340, + "end_exclusive": 9343 + }, + { + "start": 9343, + "instructions": [ + 9343 + ], + "end": 9343, + "end_exclusive": 9344 + }, + { + "start": 9344, + "instructions": [ + 9344, + 9348 + ], + "end": 9348, + "end_exclusive": 9350 + }, + { + "start": 9350, + "instructions": [ + 9350, + 9353 + ], + "end": 9353, + "end_exclusive": 9355 + }, + { + "start": 9355, + "instructions": [ + 9355 + ], + "end": 9355, + "end_exclusive": 9358 + }, + { + "start": 9358, + "instructions": [ + 9358, + 9362, + 9364, + 9367, + 9371 + ], + "end": 9371, + "end_exclusive": 9373 + }, + { + "start": 9373, + "instructions": [ + 9373, + 9377 + ], + "end": 9377, + "end_exclusive": 9379 + }, + { + "start": 9379, + "instructions": [ + 9379 + ], + "end": 9379, + "end_exclusive": 9381 + }, + { + "start": 9381, + "instructions": [ + 9381, + 9384 + ], + "end": 9384, + "end_exclusive": 9385 + }, + { + "start": 9385, + "instructions": [ + 9385, + 9389 + ], + "end": 9389, + "end_exclusive": 9391 + }, + { + "start": 9391, + "instructions": [ + 9391, + 9396 + ], + "end": 9396, + "end_exclusive": 9398 + }, + { + "start": 9398, + "instructions": [ + 9398, + 9402 + ], + "end": 9402, + "end_exclusive": 9404 + }, + { + "start": 9404, + "instructions": [ + 9404, + 9407 + ], + "end": 9407, + "end_exclusive": 9409 + }, + { + "start": 9409, + "instructions": [ + 9409, + 9413 + ], + "end": 9413, + "end_exclusive": 9415 + }, + { + "start": 9415, + "instructions": [ + 9415, + 9419, + 9421, + 9425, + 9427, + 9430, + 9434 + ], + "end": 9434, + "end_exclusive": 9436 + }, + { + "start": 9436, + "instructions": [ + 9436, + 9440 + ], + "end": 9440, + "end_exclusive": 9442 + }, + { + "start": 9442, + "instructions": [ + 9442 + ], + "end": 9442, + "end_exclusive": 9444 + }, + { + "start": 9444, + "instructions": [ + 9444 + ], + "end": 9444, + "end_exclusive": 9447 + }, + { + "start": 9447, + "instructions": [ + 9447 + ], + "end": 9447, + "end_exclusive": 9448 + }, + { + "start": 9448, + "instructions": [ + 9448, + 9452 + ], + "end": 9452, + "end_exclusive": 9454 + }, + { + "start": 9454, + "instructions": [ + 9454, + 9459 + ], + "end": 9459, + "end_exclusive": 9461 + }, + { + "start": 9461, + "instructions": [ + 9461, + 9465 + ], + "end": 9465, + "end_exclusive": 9467 + }, + { + "start": 9467, + "instructions": [ + 9467, + 9470 + ], + "end": 9470, + "end_exclusive": 9472 + }, + { + "start": 9472, + "instructions": [ + 9472, + 9476, + 9480, + 9482 + ], + "end": 9482, + "end_exclusive": 9484 + }, + { + "start": 9484, + "instructions": [ + 9484, + 9487 + ], + "end": 9487, + "end_exclusive": 9489 + }, + { + "start": 9489, + "instructions": [ + 9489 + ], + "end": 9489, + "end_exclusive": 9491 + }, + { + "start": 9491, + "instructions": [ + 9491, + 9495, + 9497, + 9500, + 9504 + ], + "end": 9504, + "end_exclusive": 9506 + }, + { + "start": 9506, + "instructions": [ + 9506, + 9510 + ], + "end": 9510, + "end_exclusive": 9512 + }, + { + "start": 9512, + "instructions": [ + 9512 + ], + "end": 9512, + "end_exclusive": 9514 + }, + { + "start": 9514, + "instructions": [ + 9514 + ], + "end": 9514, + "end_exclusive": 9517 + }, + { + "start": 9517, + "instructions": [ + 9517 + ], + "end": 9517, + "end_exclusive": 9518 + }, + { + "start": 9518, + "instructions": [ + 9518, + 9522 + ], + "end": 9522, + "end_exclusive": 9524 + }, + { + "start": 9524, + "instructions": [ + 9524, + 9529 + ], + "end": 9529, + "end_exclusive": 9531 + }, + { + "start": 9531, + "instructions": [ + 9531, + 9535 + ], + "end": 9535, + "end_exclusive": 9537 + }, + { + "start": 9537, + "instructions": [ + 9537, + 9540 + ], + "end": 9540, + "end_exclusive": 9542 + }, + { + "start": 9542, + "instructions": [ + 9542, + 9546, + 9550, + 9552 + ], + "end": 9552, + "end_exclusive": 9554 + }, + { + "start": 9554, + "instructions": [ + 9554, + 9557 + ], + "end": 9557, + "end_exclusive": 9559 + }, + { + "start": 9559, + "instructions": [ + 9559 + ], + "end": 9559, + "end_exclusive": 9561 + }, + { + "start": 9561, + "instructions": [ + 9561, + 9565, + 9567, + 9570, + 9574 + ], + "end": 9574, + "end_exclusive": 9576 + }, + { + "start": 9576, + "instructions": [ + 9576, + 9580 + ], + "end": 9580, + "end_exclusive": 9582 + }, + { + "start": 9582, + "instructions": [ + 9582 + ], + "end": 9582, + "end_exclusive": 9584 + }, + { + "start": 9584, + "instructions": [ + 9584 + ], + "end": 9584, + "end_exclusive": 9587 + }, + { + "start": 9587, + "instructions": [ + 9587 + ], + "end": 9587, + "end_exclusive": 9588 + }, + { + "start": 9588, + "instructions": [ + 9588, + 9592 + ], + "end": 9592, + "end_exclusive": 9595 + }, + { + "start": 9595, + "instructions": [ + 9595, + 9600 + ], + "end": 9600, + "end_exclusive": 9602 + }, + { + "start": 9602, + "instructions": [ + 9602, + 9606 + ], + "end": 9606, + "end_exclusive": 9608 + }, + { + "start": 9608, + "instructions": [ + 9608, + 9611 + ], + "end": 9611, + "end_exclusive": 9613 + }, + { + "start": 9613, + "instructions": [ + 9613, + 9617, + 9619 + ], + "end": 9619, + "end_exclusive": 9621 + }, + { + "start": 9621, + "instructions": [ + 9621, + 9623 + ], + "end": 9623, + "end_exclusive": 9625 + }, + { + "start": 9625, + "instructions": [ + 9625 + ], + "end": 9625, + "end_exclusive": 9627 + }, + { + "start": 9627, + "instructions": [ + 9627, + 9631 + ], + "end": 9631, + "end_exclusive": 9633 + }, + { + "start": 9633, + "instructions": [ + 9633, + 9636 + ], + "end": 9636, + "end_exclusive": 9638 + }, + { + "start": 9638, + "instructions": [ + 9638, + 9641, + 9644, + 9648 + ], + "end": 9648, + "end_exclusive": 9650 + }, + { + "start": 9650, + "instructions": [ + 9650, + 9654 + ], + "end": 9654, + "end_exclusive": 9656 + }, + { + "start": 9656, + "instructions": [ + 9656 + ], + "end": 9656, + "end_exclusive": 9658 + }, + { + "start": 9658, + "instructions": [ + 9658, + 9661 + ], + "end": 9661, + "end_exclusive": 9663 + }, + { + "start": 9663, + "instructions": [ + 9663, + 9667 + ], + "end": 9667, + "end_exclusive": 9669 + }, + { + "start": 9669, + "instructions": [ + 9669, + 9672 + ], + "end": 9672, + "end_exclusive": 9674 + }, + { + "start": 9674, + "instructions": [ + 9674, + 9679 + ], + "end": 9679, + "end_exclusive": 9683 + }, + { + "start": 9683, + "instructions": [ + 9683 + ], + "end": 9683, + "end_exclusive": 9684 + }, + { + "start": 9684, + "instructions": [ + 9684, + 9688 + ], + "end": 9688, + "end_exclusive": 9691 + }, + { + "start": 9691, + "instructions": [ + 9691, + 9696 + ], + "end": 9696, + "end_exclusive": 9698 + }, + { + "start": 9698, + "instructions": [ + 9698, + 9702 + ], + "end": 9702, + "end_exclusive": 9704 + }, + { + "start": 9704, + "instructions": [ + 9704, + 9707 + ], + "end": 9707, + "end_exclusive": 9709 + }, + { + "start": 9709, + "instructions": [ + 9709, + 9713, + 9715 + ], + "end": 9715, + "end_exclusive": 9717 + }, + { + "start": 9717, + "instructions": [ + 9717, + 9719 + ], + "end": 9719, + "end_exclusive": 9721 + }, + { + "start": 9721, + "instructions": [ + 9721 + ], + "end": 9721, + "end_exclusive": 9723 + }, + { + "start": 9723, + "instructions": [ + 9723, + 9727 + ], + "end": 9727, + "end_exclusive": 9729 + }, + { + "start": 9729, + "instructions": [ + 9729, + 9731 + ], + "end": 9731, + "end_exclusive": 9733 + }, + { + "start": 9733, + "instructions": [ + 9733, + 9736, + 9739, + 9743 + ], + "end": 9743, + "end_exclusive": 9745 + }, + { + "start": 9745, + "instructions": [ + 9745, + 9749 + ], + "end": 9749, + "end_exclusive": 9751 + }, + { + "start": 9751, + "instructions": [ + 9751 + ], + "end": 9751, + "end_exclusive": 9753 + }, + { + "start": 9753, + "instructions": [ + 9753, + 9756 + ], + "end": 9756, + "end_exclusive": 9758 + }, + { + "start": 9758, + "instructions": [ + 9758, + 9762 + ], + "end": 9762, + "end_exclusive": 9764 + }, + { + "start": 9764, + "instructions": [ + 9764, + 9767 + ], + "end": 9767, + "end_exclusive": 9769 + }, + { + "start": 9769, + "instructions": [ + 9769, + 9774 + ], + "end": 9774, + "end_exclusive": 9778 + }, + { + "start": 9778, + "instructions": [ + 9778 + ], + "end": 9778, + "end_exclusive": 9779 + }, + { + "start": 9779, + "instructions": [ + 9779, + 9785, + 9787, + 9790, + 9794 + ], + "end": 9794, + "end_exclusive": 9796 + }, + { + "start": 9796, + "instructions": [ + 9796, + 9800 + ], + "end": 9800, + "end_exclusive": 9802 + }, + { + "start": 9802, + "instructions": [ + 9802 + ], + "end": 9802, + "end_exclusive": 9804 + }, + { + "start": 9804, + "instructions": [ + 9804, + 9807 + ], + "end": 9807, + "end_exclusive": 9808 + } + ], + "registers": [ + "R0", + "R1", + "R2", + "R3", + "R4", + "R5", + "R6", + "R7" + ], + "control_registers": [ + "CCR", + "BR", + "EP", + "DP", + "TP", + "SR" + ] + }, + "symbols": { + "symbols": [ + { + "address": 57606, + "name": "mem_E106", + "region": "program_or_external", + "kind": "memory", + "access_count": 5, + "read_count": 5, + "write_count": 2, + "unknown_count": 0, + "width_hints": [ + "word" + ], + "width": "word", + "first_access": 9143, + "last_access": 9415, + "accesses": [ + { + "address": 57606, + "instruction_address": 9143, + "instruction": "MOV:G.W @H'E106, R0", + "mnemonic": "MOV:G.W", + "direction": "read", + "width": "word", + "operand": "@H'E106", + "operand_index": 0 + }, + { + "address": 57606, + "instruction_address": 9196, + "instruction": "BCLR.W #0, @H'E106", + "mnemonic": "BCLR.W", + "direction": "read_write", + "width": "word", + "operand": "@H'E106", + "operand_index": 1 + }, + { + "address": 57606, + "instruction_address": 9262, + "instruction": "MOV:G.W @H'E106, R0", + "mnemonic": "MOV:G.W", + "direction": "read", + "width": "word", + "operand": "@H'E106", + "operand_index": 0 + }, + { + "address": 57606, + "instruction_address": 9316, + "instruction": "BCLR.W #0, @H'E106", + "mnemonic": "BCLR.W", + "direction": "read_write", + "width": "word", + "operand": "@H'E106", + "operand_index": 1 + }, + { + "address": 57606, + "instruction_address": 9415, + "instruction": "MOV:G.W @H'E106, R0", + "mnemonic": "MOV:G.W", + "direction": "read", + "width": "word", + "operand": "@H'E106", + "operand_index": 0 + } + ] + }, + { + "address": 57616, + "name": "mem_E110", + "region": "program_or_external", + "kind": "memory", + "access_count": 7, + "read_count": 7, + "write_count": 0, + "unknown_count": 0, + "width_hints": [ + "word" + ], + "width": "word", + "first_access": 9119, + "last_access": 9698, + "accesses": [ + { + "address": 57616, + "instruction_address": 9119, + "instruction": "BTST.W #15, @H'E110", + "mnemonic": "BTST.W", + "direction": "read", + "width": "word", + "operand": "@H'E110", + "operand_index": 1 + }, + { + "address": 57616, + "instruction_address": 9239, + "instruction": "BTST.W #15, @H'E110", + "mnemonic": "BTST.W", + "direction": "read", + "width": "word", + "operand": "@H'E110", + "operand_index": 1 + }, + { + "address": 57616, + "instruction_address": 9398, + "instruction": "BTST.W #15, @H'E110", + "mnemonic": "BTST.W", + "direction": "read", + "width": "word", + "operand": "@H'E110", + "operand_index": 1 + }, + { + "address": 57616, + "instruction_address": 9461, + "instruction": "BTST.W #14, @H'E110", + "mnemonic": "BTST.W", + "direction": "read", + "width": "word", + "operand": "@H'E110", + "operand_index": 1 + }, + { + "address": 57616, + "instruction_address": 9531, + "instruction": "BTST.W #14, @H'E110", + "mnemonic": "BTST.W", + "direction": "read", + "width": "word", + "operand": "@H'E110", + "operand_index": 1 + }, + { + "address": 57616, + "instruction_address": 9602, + "instruction": "BTST.W #14, @H'E110", + "mnemonic": "BTST.W", + "direction": "read", + "width": "word", + "operand": "@H'E110", + "operand_index": 1 + }, + { + "address": 57616, + "instruction_address": 9698, + "instruction": "BTST.W #14, @H'E110", + "mnemonic": "BTST.W", + "direction": "read", + "width": "word", + "operand": "@H'E110", + "operand_index": 1 + } + ] + }, + { + "address": 57630, + "name": "mem_E11E", + "region": "program_or_external", + "kind": "memory", + "access_count": 4, + "read_count": 4, + "write_count": 0, + "unknown_count": 0, + "width_hints": [ + "word" + ], + "width": "word", + "first_access": 9476, + "last_access": 9709, + "accesses": [ + { + "address": 57630, + "instruction_address": 9476, + "instruction": "MOV:G.W @H'E11E, R0", + "mnemonic": "MOV:G.W", + "direction": "read", + "width": "word", + "operand": "@H'E11E", + "operand_index": 0 + }, + { + "address": 57630, + "instruction_address": 9546, + "instruction": "MOV:G.W @H'E11E, R0", + "mnemonic": "MOV:G.W", + "direction": "read", + "width": "word", + "operand": "@H'E11E", + "operand_index": 0 + }, + { + "address": 57630, + "instruction_address": 9613, + "instruction": "MOV:G.W @H'E11E, R0", + "mnemonic": "MOV:G.W", + "direction": "read", + "width": "word", + "operand": "@H'E11E", + "operand_index": 0 + }, + { + "address": 57630, + "instruction_address": 9709, + "instruction": "MOV:G.W @H'E11E, R0", + "mnemonic": "MOV:G.W", + "direction": "read", + "width": "word", + "operand": "@H'E11E", + "operand_index": 0 + } + ] + }, + { + "address": 58630, + "name": "mem_E506", + "region": "program_or_external", + "kind": "memory", + "access_count": 2, + "read_count": 2, + "write_count": 0, + "unknown_count": 0, + "width_hints": [ + "word" + ], + "width": "word", + "first_access": 9153, + "last_access": 9272, + "accesses": [ + { + "address": 58630, + "instruction_address": 9153, + "instruction": "AND.W @H'E506, R1", + "mnemonic": "AND.W", + "direction": "read", + "width": "word", + "operand": "@H'E506", + "operand_index": 0 + }, + { + "address": 58630, + "instruction_address": 9272, + "instruction": "AND.W @H'E506, R1", + "mnemonic": "AND.W", + "direction": "read", + "width": "word", + "operand": "@H'E506", + "operand_index": 0 + } + ] + }, + { + "address": 59654, + "name": "mem_E906", + "region": "program_or_external", + "kind": "memory", + "access_count": 4, + "read_count": 0, + "write_count": 4, + "unknown_count": 0, + "width_hints": [ + "word" + ], + "width": "word", + "first_access": 9163, + "last_access": 9421, + "accesses": [ + { + "address": 59654, + "instruction_address": 9163, + "instruction": "MOV:G.W R1, @H'E906", + "mnemonic": "MOV:G.W", + "direction": "write", + "width": "word", + "operand": "@H'E906", + "operand_index": 1 + }, + { + "address": 59654, + "instruction_address": 9282, + "instruction": "MOV:G.W R1, @H'E906", + "mnemonic": "MOV:G.W", + "direction": "write", + "width": "word", + "operand": "@H'E906", + "operand_index": 1 + }, + { + "address": 59654, + "instruction_address": 9358, + "instruction": "MOV:G.W R0, @H'E906", + "mnemonic": "MOV:G.W", + "direction": "write", + "width": "word", + "operand": "@H'E906", + "operand_index": 1 + }, + { + "address": 59654, + "instruction_address": 9421, + "instruction": "MOV:G.W R0, @H'E906", + "mnemonic": "MOV:G.W", + "direction": "write", + "width": "word", + "operand": "@H'E906", + "operand_index": 1 + } + ] + }, + { + "address": 59678, + "name": "mem_E91E", + "region": "program_or_external", + "kind": "memory", + "access_count": 2, + "read_count": 0, + "write_count": 2, + "unknown_count": 0, + "width_hints": [ + "word" + ], + "width": "word", + "first_access": 9491, + "last_access": 9561, + "accesses": [ + { + "address": 59678, + "instruction_address": 9491, + "instruction": "MOV:G.W R0, @H'E91E", + "mnemonic": "MOV:G.W", + "direction": "write", + "width": "word", + "operand": "@H'E91E", + "operand_index": 1 + }, + { + "address": 59678, + "instruction_address": 9561, + "instruction": "MOV:G.W R0, @H'E91E", + "mnemonic": "MOV:G.W", + "direction": "write", + "width": "word", + "operand": "@H'E91E", + "operand_index": 1 + } + ] + }, + { + "address": 59682, + "name": "mem_E922", + "region": "program_or_external", + "kind": "memory", + "access_count": 1, + "read_count": 0, + "write_count": 1, + "unknown_count": 0, + "width_hints": [ + "word" + ], + "width": "word", + "first_access": 9779, + "last_access": 9779, + "accesses": [ + { + "address": 59682, + "instruction_address": 9779, + "instruction": "MOV:G.W #H'8000, @H'E922", + "mnemonic": "MOV:G.W", + "direction": "write", + "width": "word", + "operand": "@H'E922", + "operand_index": 1 + } + ] + }, + { + "address": 62468, + "name": "mem_F404", + "region": "program_or_external", + "kind": "memory", + "access_count": 11, + "read_count": 11, + "write_count": 0, + "unknown_count": 0, + "width_hints": [ + "byte" + ], + "width": "byte", + "first_access": 9178, + "last_access": 9796, + "accesses": [ + { + "address": 62468, + "instruction_address": 9178, + "instruction": "BTST.B #5, @H'F404", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F404", + "operand_index": 1 + }, + { + "address": 62468, + "instruction_address": 9212, + "instruction": "BTST.B #5, @H'F404", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F404", + "operand_index": 1 + }, + { + "address": 62468, + "instruction_address": 9297, + "instruction": "BTST.B #5, @H'F404", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F404", + "operand_index": 1 + }, + { + "address": 62468, + "instruction_address": 9332, + "instruction": "BTST.B #5, @H'F404", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F404", + "operand_index": 1 + }, + { + "address": 62468, + "instruction_address": 9373, + "instruction": "BTST.B #5, @H'F404", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F404", + "operand_index": 1 + }, + { + "address": 62468, + "instruction_address": 9436, + "instruction": "BTST.B #5, @H'F404", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F404", + "operand_index": 1 + }, + { + "address": 62468, + "instruction_address": 9506, + "instruction": "BTST.B #4, @H'F404", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F404", + "operand_index": 1 + }, + { + "address": 62468, + "instruction_address": 9576, + "instruction": "BTST.B #4, @H'F404", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F404", + "operand_index": 1 + }, + { + "address": 62468, + "instruction_address": 9650, + "instruction": "BTST.B #4, @H'F404", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F404", + "operand_index": 1 + }, + { + "address": 62468, + "instruction_address": 9745, + "instruction": "BTST.B #4, @H'F404", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F404", + "operand_index": 1 + }, + { + "address": 62468, + "instruction_address": 9796, + "instruction": "BTST.B #4, @H'F404", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F404", + "operand_index": 1 + } + ] + }, + { + "address": 63184, + "name": "ram_F6D0", + "region": "on_chip_ram", + "kind": "ram", + "access_count": 13, + "read_count": 13, + "write_count": 0, + "unknown_count": 0, + "width_hints": [ + "byte" + ], + "width": "byte", + "first_access": 9104, + "last_access": 9758, + "accesses": [ + { + "address": 63184, + "instruction_address": 9104, + "instruction": "BTST.B #1, @H'F6D0", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F6D0", + "operand_index": 1 + }, + { + "address": 63184, + "instruction_address": 9130, + "instruction": "BTST.B #2, @H'F6D0", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F6D0", + "operand_index": 1 + }, + { + "address": 63184, + "instruction_address": 9224, + "instruction": "BTST.B #2, @H'F6D0", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F6D0", + "operand_index": 1 + }, + { + "address": 63184, + "instruction_address": 9250, + "instruction": "BTST.B #1, @H'F6D0", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F6D0", + "operand_index": 1 + }, + { + "address": 63184, + "instruction_address": 9385, + "instruction": "BTST.B #3, @H'F6D0", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F6D0", + "operand_index": 1 + }, + { + "address": 63184, + "instruction_address": 9448, + "instruction": "BTST.B #7, @H'F6D0", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F6D0", + "operand_index": 1 + }, + { + "address": 63184, + "instruction_address": 9518, + "instruction": "BTST.B #6, @H'F6D0", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F6D0", + "operand_index": 1 + }, + { + "address": 63184, + "instruction_address": 9588, + "instruction": "BTST.B #4, @H'F6D0", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F6D0", + "operand_index": 1 + }, + { + "address": 63184, + "instruction_address": 9627, + "instruction": "BTST.B #5, @H'F6D0", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F6D0", + "operand_index": 1 + }, + { + "address": 63184, + "instruction_address": 9663, + "instruction": "BTST.B #5, @H'F6D0", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F6D0", + "operand_index": 1 + }, + { + "address": 63184, + "instruction_address": 9684, + "instruction": "BTST.B #5, @H'F6D0", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F6D0", + "operand_index": 1 + }, + { + "address": 63184, + "instruction_address": 9723, + "instruction": "BTST.B #4, @H'F6D0", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F6D0", + "operand_index": 1 + }, + { + "address": 63184, + "instruction_address": 9758, + "instruction": "BTST.B #4, @H'F6D0", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F6D0", + "operand_index": 1 + } + ] + }, + { + "address": 63220, + "name": "ram_F6F4", + "region": "on_chip_ram", + "kind": "ram", + "access_count": 2, + "read_count": 0, + "write_count": 2, + "unknown_count": 0, + "width_hints": [ + "word" + ], + "width": "word", + "first_access": 9679, + "last_access": 9774, + "accesses": [ + { + "address": 63220, + "instruction_address": 9679, + "instruction": "CLR.W @H'F6F4", + "mnemonic": "CLR.W", + "direction": "write", + "width": "word", + "operand": "@H'F6F4", + "operand_index": 0 + }, + { + "address": 63220, + "instruction_address": 9774, + "instruction": "CLR.W @H'F6F4", + "mnemonic": "CLR.W", + "direction": "write", + "width": "word", + "operand": "@H'F6F4", + "operand_index": 0 + } + ] + }, + { + "address": 63222, + "name": "ram_F6F6", + "region": "on_chip_ram", + "kind": "ram", + "access_count": 4, + "read_count": 0, + "write_count": 4, + "unknown_count": 0, + "width_hints": [ + "byte" + ], + "width": "byte", + "first_access": 9472, + "last_access": 9769, + "accesses": [ + { + "address": 63222, + "instruction_address": 9472, + "instruction": "CLR.B @H'F6F6", + "mnemonic": "CLR.B", + "direction": "write", + "width": "byte", + "operand": "@H'F6F6", + "operand_index": 0 + }, + { + "address": 63222, + "instruction_address": 9542, + "instruction": "CLR.B @H'F6F6", + "mnemonic": "CLR.B", + "direction": "write", + "width": "byte", + "operand": "@H'F6F6", + "operand_index": 0 + }, + { + "address": 63222, + "instruction_address": 9674, + "instruction": "MOV:G.B #H'C0, @H'F6F6", + "mnemonic": "MOV:G.B", + "direction": "write", + "width": "byte", + "operand": "@H'F6F6", + "operand_index": 1 + }, + { + "address": 63222, + "instruction_address": 9769, + "instruction": "MOV:G.B #H'80, @H'F6F6", + "mnemonic": "MOV:G.B", + "direction": "write", + "width": "byte", + "operand": "@H'F6F6", + "operand_index": 1 + } + ] + }, + { + "address": 63280, + "name": "ram_F730", + "region": "on_chip_ram", + "kind": "ram", + "access_count": 4, + "read_count": 4, + "write_count": 0, + "unknown_count": 0, + "width_hints": [ + "byte" + ], + "width": "byte", + "first_access": 9137, + "last_access": 9409, + "accesses": [ + { + "address": 63280, + "instruction_address": 9137, + "instruction": "BTST.B #7, @H'F730", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F730", + "operand_index": 1 + }, + { + "address": 63280, + "instruction_address": 9256, + "instruction": "BTST.B #7, @H'F730", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F730", + "operand_index": 1 + }, + { + "address": 63280, + "instruction_address": 9344, + "instruction": "BTST.B #7, @H'F730", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F730", + "operand_index": 1 + }, + { + "address": 63280, + "instruction_address": 9409, + "instruction": "BTST.B #7, @H'F730", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F730", + "operand_index": 1 + } + ] + }, + { + "address": 63281, + "name": "ram_F731", + "region": "on_chip_ram", + "kind": "ram", + "access_count": 7, + "read_count": 7, + "write_count": 0, + "unknown_count": 0, + "width_hints": [ + "byte" + ], + "width": "byte", + "first_access": 9111, + "last_access": 9691, + "accesses": [ + { + "address": 63281, + "instruction_address": 9111, + "instruction": "CMP:G.B #H'02, @H'F731", + "mnemonic": "CMP:G.B", + "direction": "read", + "width": "byte", + "operand": "@H'F731", + "operand_index": 1 + }, + { + "address": 63281, + "instruction_address": 9231, + "instruction": "CMP:G.B #H'02, @H'F731", + "mnemonic": "CMP:G.B", + "direction": "read", + "width": "byte", + "operand": "@H'F731", + "operand_index": 1 + }, + { + "address": 63281, + "instruction_address": 9391, + "instruction": "CMP:G.B #H'02, @H'F731", + "mnemonic": "CMP:G.B", + "direction": "read", + "width": "byte", + "operand": "@H'F731", + "operand_index": 1 + }, + { + "address": 63281, + "instruction_address": 9454, + "instruction": "CMP:G.B #H'02, @H'F731", + "mnemonic": "CMP:G.B", + "direction": "read", + "width": "byte", + "operand": "@H'F731", + "operand_index": 1 + }, + { + "address": 63281, + "instruction_address": 9524, + "instruction": "CMP:G.B #H'02, @H'F731", + "mnemonic": "CMP:G.B", + "direction": "read", + "width": "byte", + "operand": "@H'F731", + "operand_index": 1 + }, + { + "address": 63281, + "instruction_address": 9595, + "instruction": "CMP:G.B #H'02, @H'F731", + "mnemonic": "CMP:G.B", + "direction": "read", + "width": "byte", + "operand": "@H'F731", + "operand_index": 1 + }, + { + "address": 63281, + "instruction_address": 9691, + "instruction": "CMP:G.B #H'02, @H'F731", + "mnemonic": "CMP:G.B", + "direction": "read", + "width": "byte", + "operand": "@H'F731", + "operand_index": 1 + } + ] + }, + { + "address": 63377, + "name": "ram_F791", + "region": "on_chip_ram", + "kind": "ram", + "access_count": 11, + "read_count": 11, + "write_count": 0, + "unknown_count": 0, + "width_hints": [ + "byte" + ], + "width": "byte", + "first_access": 9172, + "last_access": 9790, + "accesses": [ + { + "address": 63377, + "instruction_address": 9172, + "instruction": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F791", + "operand_index": 1 + }, + { + "address": 63377, + "instruction_address": 9206, + "instruction": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F791", + "operand_index": 1 + }, + { + "address": 63377, + "instruction_address": 9291, + "instruction": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F791", + "operand_index": 1 + }, + { + "address": 63377, + "instruction_address": 9326, + "instruction": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F791", + "operand_index": 1 + }, + { + "address": 63377, + "instruction_address": 9367, + "instruction": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F791", + "operand_index": 1 + }, + { + "address": 63377, + "instruction_address": 9430, + "instruction": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F791", + "operand_index": 1 + }, + { + "address": 63377, + "instruction_address": 9500, + "instruction": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F791", + "operand_index": 1 + }, + { + "address": 63377, + "instruction_address": 9570, + "instruction": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F791", + "operand_index": 1 + }, + { + "address": 63377, + "instruction_address": 9644, + "instruction": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F791", + "operand_index": 1 + }, + { + "address": 63377, + "instruction_address": 9739, + "instruction": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F791", + "operand_index": 1 + }, + { + "address": 63377, + "instruction_address": 9790, + "instruction": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F791", + "operand_index": 1 + } + ] + } + ], + "by_address": { + "57606": "mem_E106", + "57616": "mem_E110", + "57630": "mem_E11E", + "58630": "mem_E506", + "59654": "mem_E906", + "59678": "mem_E91E", + "59682": "mem_E922", + "62468": "mem_F404", + "63184": "ram_F6D0", + "63220": "ram_F6F4", + "63222": "ram_F6F6", + "63280": "ram_F730", + "63281": "ram_F731", + "63377": "ram_F791" + } + }, + "lcd_text": { + "strings": [ + { + "address": 9188, + "length": 4, + "text": "o X", + "trimmed": "o X", + "kind": "printable_run", + "score": 0.738, + "confidence": "low" + } + ], + "regions": [], + "searches": [ + { + "term": "CONNECT", + "literal_hits": [], + "candidate_hits": [], + "near_matches": [], + "status": "not_found" + } + ], + "notes": [ + "LCD text scan is byte-oriented and conservative; strings may be inline script fields.", + "Raw xrefs include MOV:I.W immediates to the string address and nearby record prefixes." + ] + }, + "lcd_driver": { + "addresses": [ + { + "address": 61952, + "name": "lcd_status_control", + "role": "status/control register inferred from busy polling and command writes" + }, + { + "address": 61953, + "name": "lcd_data", + "role": "data register inferred from paired data reads/writes" + } + ], + "accesses": [], + "polling_loops": [], + "routines": [], + "instructions": {} + }, + "instructions": [ + { + "address": 9104, + "address_region": "program_or_external", + "bytes": "15F6D0F1", + "text": "BTST.B #1, @H'F6D0", + "mnemonic": "BTST.B", + "operands": "#1, @H'F6D0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63184, + "name": null, + "symbol": "ram_F6D0", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9104, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9108, + "address_region": "program_or_external", + "bytes": "370070", + "text": "BEQ loc_2407", + "mnemonic": "BEQ", + "operands": "loc_2407", + "kind": "branch", + "targets": [ + 9223 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9104, + "changes": [], + "notes": [] + } + }, + { + "address": 9111, + "address_region": "program_or_external", + "bytes": "15F7310402", + "text": "CMP:G.B #H'02, @H'F731", + "mnemonic": "CMP:G.B", + "operands": "#H'02, @H'F731", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63281, + "name": null, + "symbol": "ram_F731", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9111, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9116, + "address_region": "program_or_external", + "bytes": "320068", + "text": "BHI loc_2407", + "mnemonic": "BHI", + "operands": "loc_2407", + "kind": "branch", + "targets": [ + 9223 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9111, + "changes": [], + "notes": [] + } + }, + { + "address": 9119, + "address_region": "program_or_external", + "bytes": "1DE110FF", + "text": "BTST.W #15, @H'E110", + "mnemonic": "BTST.W", + "operands": "#15, @H'E110", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 57616, + "name": null, + "symbol": "mem_E110", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9119, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9123, + "address_region": "program_or_external", + "bytes": "2705", + "text": "BEQ loc_23AA", + "mnemonic": "BEQ", + "operands": "loc_23AA", + "kind": "branch", + "targets": [ + 9130 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9119, + "changes": [], + "notes": [] + } + }, + { + "address": 9125, + "address_region": "program_or_external", + "bytes": "1E0340", + "text": "BSR loc_26E8", + "mnemonic": "BSR", + "operands": "loc_26E8", + "kind": "call", + "targets": [ + 9960 + ], + "cycles": { + "cycles": 14, + "base_cycles": 9, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9125, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9128, + "address_region": "program_or_external", + "bytes": "205D", + "text": "BRA loc_2407", + "mnemonic": "BRA", + "operands": "loc_2407", + "kind": "jump", + "targets": [ + 9223 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "cycles": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9125, + "changes": [], + "notes": [] + } + }, + { + "address": 9130, + "address_region": "program_or_external", + "bytes": "15F6D0F2", + "text": "BTST.B #2, @H'F6D0", + "mnemonic": "BTST.B", + "operands": "#2, @H'F6D0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63184, + "name": null, + "symbol": "ram_F6D0", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9130, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9134, + "address_region": "program_or_external", + "bytes": "3600CF", + "text": "BNE loc_2480", + "mnemonic": "BNE", + "operands": "loc_2480", + "kind": "branch", + "targets": [ + 9344 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9130, + "changes": [], + "notes": [] + } + }, + { + "address": 9137, + "address_region": "program_or_external", + "bytes": "15F730F7", + "text": "BTST.B #7, @H'F730", + "mnemonic": "BTST.B", + "operands": "#7, @H'F730", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63280, + "name": null, + "symbol": "ram_F730", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9137, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9141, + "address_region": "program_or_external", + "bytes": "2735", + "text": "BEQ loc_23EC", + "mnemonic": "BEQ", + "operands": "loc_23EC", + "kind": "branch", + "targets": [ + 9196 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9137, + "changes": [], + "notes": [] + } + }, + { + "address": 9143, + "address_region": "program_or_external", + "bytes": "1DE10680", + "text": "MOV:G.W @H'E106, R0", + "mnemonic": "MOV:G.W", + "operands": "@H'E106, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 57606, + "name": null, + "symbol": "mem_E106", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9143, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "memory_load" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "R0 unknown after memory load" + ] + } + }, + { + "address": 9147, + "address_region": "program_or_external", + "bytes": "A81B", + "text": "SHLR.W R0", + "mnemonic": "SHLR.W", + "operands": "R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9147, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "unsupported:SHLR.W" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "unsupported operation invalidated R0" + ] + } + }, + { + "address": 9149, + "address_region": "program_or_external", + "bytes": "A881", + "text": "MOV:G.W R0, R1", + "mnemonic": "MOV:G.W", + "operands": "R0, R1", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9149, + "changes": [ + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "unknown_operand" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "R1 unknown after MOV source" + ] + } + }, + { + "address": 9151, + "address_region": "program_or_external", + "bytes": "2726", + "text": "BEQ loc_23E7", + "mnemonic": "BEQ", + "operands": "loc_23E7", + "kind": "branch", + "targets": [ + 9191 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9149, + "changes": [], + "notes": [] + } + }, + { + "address": 9153, + "address_region": "program_or_external", + "bytes": "1DE50651", + "text": "AND.W @H'E506, R1", + "mnemonic": "AND.W", + "operands": "@H'E506, R1", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 58630, + "name": null, + "symbol": "mem_E506", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9153, + "changes": [ + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "unsupported:AND.W" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "unsupported operation invalidated R1" + ] + } + }, + { + "address": 9157, + "address_region": "program_or_external", + "bytes": "0CFFC451", + "text": "AND.W #H'FFC4, R1", + "mnemonic": "AND.W", + "operands": "#H'FFC4, R1", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 4, + "base_cycles": 4, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9153, + "changes": [], + "notes": [ + "unsupported operation invalidated R1" + ] + } + }, + { + "address": 9161, + "address_region": "program_or_external", + "bytes": "27F0", + "text": "BEQ loc_23BB", + "mnemonic": "BEQ", + "operands": "loc_23BB", + "kind": "branch", + "targets": [ + 9147 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9153, + "changes": [], + "notes": [] + } + }, + { + "address": 9163, + "address_region": "program_or_external", + "bytes": "1DE90691", + "text": "MOV:G.W R1, @H'E906", + "mnemonic": "MOV:G.W", + "operands": "R1, @H'E906", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 59654, + "name": null, + "symbol": "mem_E906", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9163, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9167, + "address_region": "program_or_external", + "bytes": "5280", + "text": "MOV:E.B #H'80, R2", + "mnemonic": "MOV:E.B", + "operands": "#H'80, R2", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 2, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9163, + "changes": [ + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + } + } + ], + "notes": [ + "R2 = 0x80" + ], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + } + } + } + } + }, + { + "address": 9169, + "address_region": "program_or_external", + "bytes": "5B0083", + "text": "MOV:I.W #H'0083, R3", + "mnemonic": "MOV:I.W", + "operands": "#H'0083, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9163, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + } + } + ], + "notes": [ + "R3 = 0x0083" + ], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + } + } + } + } + }, + { + "address": 9172, + "address_region": "program_or_external", + "bytes": "15F791F7", + "text": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "operands": "#7, @H'F791", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63377, + "name": null, + "symbol": "ram_F791", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9163, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + } + } + } + } + }, + { + "address": 9176, + "address_region": "program_or_external", + "bytes": "2708", + "text": "BEQ loc_23E2", + "mnemonic": "BEQ", + "operands": "loc_23E2", + "kind": "branch", + "targets": [ + 9186 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9163, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + } + } + } + } + }, + { + "address": 9178, + "address_region": "program_or_external", + "bytes": "15F404F5", + "text": "BTST.B #5, @H'F404", + "mnemonic": "BTST.B", + "operands": "#5, @H'F404", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 62468, + "name": null, + "symbol": "mem_F404", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9178, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9182, + "address_region": "program_or_external", + "bytes": "2702", + "text": "BEQ loc_23E2", + "mnemonic": "BEQ", + "operands": "loc_23E2", + "kind": "branch", + "targets": [ + 9186 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9178, + "changes": [], + "notes": [] + } + }, + { + "address": 9184, + "address_region": "program_or_external", + "bytes": "ABCE", + "text": "BSET.W #14, R3", + "mnemonic": "BSET.W", + "operands": "#14, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9184, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "unsupported:BSET.W" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "unsupported operation invalidated R3" + ] + } + }, + { + "address": 9186, + "address_region": "program_or_external", + "bytes": "1E1A6F", + "text": "BSR loc_3E54", + "mnemonic": "BSR", + "operands": "loc_3E54", + "kind": "call", + "targets": [ + 15956 + ], + "cycles": { + "cycles": 13, + "base_cycles": 9, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9186, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9189, + "address_region": "program_or_external", + "bytes": "2020", + "text": "BRA loc_2407", + "mnemonic": "BRA", + "operands": "loc_2407", + "kind": "jump", + "targets": [ + 9223 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "cycles": 8, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9186, + "changes": [], + "notes": [] + } + }, + { + "address": 9191, + "address_region": "program_or_external", + "bytes": "580004", + "text": "MOV:I.W #H'0004, R0", + "mnemonic": "MOV:I.W", + "operands": "#H'0004, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9191, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 4, + "hex": "0x0004", + "width": 16, + "source": "MOV:I.W #H'0004, R0" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "R0 = 0x0004" + ], + "known_after": { + "registers": { + "R0": { + "known": true, + "value": 4, + "hex": "0x0004", + "width": 16, + "source": "MOV:I.W #H'0004, R0" + } + } + } + } + }, + { + "address": 9194, + "address_region": "program_or_external", + "bytes": "2048", + "text": "BRA loc_2434", + "mnemonic": "BRA", + "operands": "loc_2434", + "kind": "jump", + "targets": [ + 9268 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "cycles": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9191, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R0": { + "known": true, + "value": 4, + "hex": "0x0004", + "width": 16, + "source": "MOV:I.W #H'0004, R0" + } + } + } + } + }, + { + "address": 9196, + "address_region": "program_or_external", + "bytes": "1DE106D0", + "text": "BCLR.W #0, @H'E106", + "mnemonic": "BCLR.W", + "operands": "#0, @H'E106", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 9, + "base_cycles": 8, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 57606, + "name": null, + "symbol": "mem_E106", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9196, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9200, + "address_region": "program_or_external", + "bytes": "5C0000", + "text": "MOV:I.W #H'0000, R4", + "mnemonic": "MOV:I.W", + "operands": "#H'0000, R4", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9196, + "changes": [ + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 0, + "hex": "0x0000", + "width": 16, + "source": "MOV:I.W #H'0000, R4" + } + } + ], + "notes": [ + "R4 = 0x0000" + ], + "known_after": { + "registers": { + "R4": { + "known": true, + "value": 0, + "hex": "0x0000", + "width": 16, + "source": "MOV:I.W #H'0000, R4" + } + } + } + } + }, + { + "address": 9203, + "address_region": "program_or_external", + "bytes": "5B0083", + "text": "MOV:I.W #H'0083, R3", + "mnemonic": "MOV:I.W", + "operands": "#H'0083, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9196, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + } + } + ], + "notes": [ + "R3 = 0x0083" + ], + "known_after": { + "registers": { + "R3": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + }, + "R4": { + "known": true, + "value": 0, + "hex": "0x0000", + "width": 16, + "source": "MOV:I.W #H'0000, R4" + } + } + } + } + }, + { + "address": 9206, + "address_region": "program_or_external", + "bytes": "15F791F7", + "text": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "operands": "#7, @H'F791", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63377, + "name": null, + "symbol": "ram_F791", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9196, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R3": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + }, + "R4": { + "known": true, + "value": 0, + "hex": "0x0000", + "width": 16, + "source": "MOV:I.W #H'0000, R4" + } + } + } + } + }, + { + "address": 9210, + "address_region": "program_or_external", + "bytes": "2708", + "text": "BEQ loc_2404", + "mnemonic": "BEQ", + "operands": "loc_2404", + "kind": "branch", + "targets": [ + 9220 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9196, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R3": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + }, + "R4": { + "known": true, + "value": 0, + "hex": "0x0000", + "width": 16, + "source": "MOV:I.W #H'0000, R4" + } + } + } + } + }, + { + "address": 9212, + "address_region": "program_or_external", + "bytes": "15F404F5", + "text": "BTST.B #5, @H'F404", + "mnemonic": "BTST.B", + "operands": "#5, @H'F404", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 62468, + "name": null, + "symbol": "mem_F404", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9212, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9216, + "address_region": "program_or_external", + "bytes": "2702", + "text": "BEQ loc_2404", + "mnemonic": "BEQ", + "operands": "loc_2404", + "kind": "branch", + "targets": [ + 9220 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9212, + "changes": [], + "notes": [] + } + }, + { + "address": 9218, + "address_region": "program_or_external", + "bytes": "ABCE", + "text": "BSET.W #14, R3", + "mnemonic": "BSET.W", + "operands": "#14, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9218, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "unsupported:BSET.W" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "unsupported operation invalidated R3" + ] + } + }, + { + "address": 9220, + "address_region": "program_or_external", + "bytes": "1EF62E", + "text": "BSR loc_1A35", + "mnemonic": "BSR", + "operands": "loc_1A35", + "kind": "call", + "targets": [ + 6709 + ], + "cycles": { + "cycles": 13, + "base_cycles": 9, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9220, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9223, + "address_region": "program_or_external", + "bytes": "19", + "text": "RTS", + "mnemonic": "RTS", + "operands": "", + "kind": "return", + "targets": [], + "cycles": { + "cycles": 13, + "base_cycles": 8, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word pop from stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9223, + "changes": [], + "notes": [] + } + }, + { + "address": 9224, + "address_region": "program_or_external", + "bytes": "15F6D0F2", + "text": "BTST.B #2, @H'F6D0", + "mnemonic": "BTST.B", + "operands": "#2, @H'F6D0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63184, + "name": null, + "symbol": "ram_F6D0", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9224, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9228, + "address_region": "program_or_external", + "bytes": "370070", + "text": "BEQ loc_247F", + "mnemonic": "BEQ", + "operands": "loc_247F", + "kind": "branch", + "targets": [ + 9343 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9224, + "changes": [], + "notes": [] + } + }, + { + "address": 9231, + "address_region": "program_or_external", + "bytes": "15F7310402", + "text": "CMP:G.B #H'02, @H'F731", + "mnemonic": "CMP:G.B", + "operands": "#H'02, @H'F731", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63281, + "name": null, + "symbol": "ram_F731", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9231, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9236, + "address_region": "program_or_external", + "bytes": "320068", + "text": "BHI loc_247F", + "mnemonic": "BHI", + "operands": "loc_247F", + "kind": "branch", + "targets": [ + 9343 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9231, + "changes": [], + "notes": [] + } + }, + { + "address": 9239, + "address_region": "program_or_external", + "bytes": "1DE110FF", + "text": "BTST.W #15, @H'E110", + "mnemonic": "BTST.W", + "operands": "#15, @H'E110", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 57616, + "name": null, + "symbol": "mem_E110", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9239, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9243, + "address_region": "program_or_external", + "bytes": "2705", + "text": "BEQ loc_2422", + "mnemonic": "BEQ", + "operands": "loc_2422", + "kind": "branch", + "targets": [ + 9250 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9239, + "changes": [], + "notes": [] + } + }, + { + "address": 9245, + "address_region": "program_or_external", + "bytes": "1E02C8", + "text": "BSR loc_26E8", + "mnemonic": "BSR", + "operands": "loc_26E8", + "kind": "call", + "targets": [ + 9960 + ], + "cycles": { + "cycles": 14, + "base_cycles": 9, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9245, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9248, + "address_region": "program_or_external", + "bytes": "205D", + "text": "BRA loc_247F", + "mnemonic": "BRA", + "operands": "loc_247F", + "kind": "jump", + "targets": [ + 9343 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "cycles": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9245, + "changes": [], + "notes": [] + } + }, + { + "address": 9250, + "address_region": "program_or_external", + "bytes": "15F6D0F1", + "text": "BTST.B #1, @H'F6D0", + "mnemonic": "BTST.B", + "operands": "#1, @H'F6D0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63184, + "name": null, + "symbol": "ram_F6D0", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9250, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9254, + "address_region": "program_or_external", + "bytes": "2658", + "text": "BNE loc_2480", + "mnemonic": "BNE", + "operands": "loc_2480", + "kind": "branch", + "targets": [ + 9344 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9250, + "changes": [], + "notes": [] + } + }, + { + "address": 9256, + "address_region": "program_or_external", + "bytes": "15F730F7", + "text": "BTST.B #7, @H'F730", + "mnemonic": "BTST.B", + "operands": "#7, @H'F730", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63280, + "name": null, + "symbol": "ram_F730", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9256, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9260, + "address_region": "program_or_external", + "bytes": "2736", + "text": "BEQ loc_2464", + "mnemonic": "BEQ", + "operands": "loc_2464", + "kind": "branch", + "targets": [ + 9316 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9256, + "changes": [], + "notes": [] + } + }, + { + "address": 9262, + "address_region": "program_or_external", + "bytes": "1DE10680", + "text": "MOV:G.W @H'E106, R0", + "mnemonic": "MOV:G.W", + "operands": "@H'E106, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 57606, + "name": null, + "symbol": "mem_E106", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9262, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "memory_load" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "R0 unknown after memory load" + ] + } + }, + { + "address": 9266, + "address_region": "program_or_external", + "bytes": "A81A", + "text": "SHLL.W R0", + "mnemonic": "SHLL.W", + "operands": "R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9266, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "unsupported:SHLL.W" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "unsupported operation invalidated R0" + ] + } + }, + { + "address": 9268, + "address_region": "program_or_external", + "bytes": "A881", + "text": "MOV:G.W R0, R1", + "mnemonic": "MOV:G.W", + "operands": "R0, R1", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9268, + "changes": [ + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "unknown_operand" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "R1 unknown after MOV source" + ] + } + }, + { + "address": 9270, + "address_region": "program_or_external", + "bytes": "2726", + "text": "BEQ loc_245E", + "mnemonic": "BEQ", + "operands": "loc_245E", + "kind": "branch", + "targets": [ + 9310 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9268, + "changes": [], + "notes": [] + } + }, + { + "address": 9272, + "address_region": "program_or_external", + "bytes": "1DE50651", + "text": "AND.W @H'E506, R1", + "mnemonic": "AND.W", + "operands": "@H'E506, R1", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 58630, + "name": null, + "symbol": "mem_E506", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9272, + "changes": [ + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "unsupported:AND.W" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "unsupported operation invalidated R1" + ] + } + }, + { + "address": 9276, + "address_region": "program_or_external", + "bytes": "0CFFC451", + "text": "AND.W #H'FFC4, R1", + "mnemonic": "AND.W", + "operands": "#H'FFC4, R1", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 4, + "base_cycles": 4, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9272, + "changes": [], + "notes": [ + "unsupported operation invalidated R1" + ] + } + }, + { + "address": 9280, + "address_region": "program_or_external", + "bytes": "27F0", + "text": "BEQ loc_2432", + "mnemonic": "BEQ", + "operands": "loc_2432", + "kind": "branch", + "targets": [ + 9266 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9272, + "changes": [], + "notes": [] + } + }, + { + "address": 9282, + "address_region": "program_or_external", + "bytes": "1DE90691", + "text": "MOV:G.W R1, @H'E906", + "mnemonic": "MOV:G.W", + "operands": "R1, @H'E906", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 59654, + "name": null, + "symbol": "mem_E906", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9282, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9286, + "address_region": "program_or_external", + "bytes": "5280", + "text": "MOV:E.B #H'80, R2", + "mnemonic": "MOV:E.B", + "operands": "#H'80, R2", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 2, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9282, + "changes": [ + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + } + } + ], + "notes": [ + "R2 = 0x80" + ], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + } + } + } + } + }, + { + "address": 9288, + "address_region": "program_or_external", + "bytes": "5B0083", + "text": "MOV:I.W #H'0083, R3", + "mnemonic": "MOV:I.W", + "operands": "#H'0083, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9282, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + } + } + ], + "notes": [ + "R3 = 0x0083" + ], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + } + } + } + } + }, + { + "address": 9291, + "address_region": "program_or_external", + "bytes": "15F791F7", + "text": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "operands": "#7, @H'F791", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63377, + "name": null, + "symbol": "ram_F791", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9282, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + } + } + } + } + }, + { + "address": 9295, + "address_region": "program_or_external", + "bytes": "2708", + "text": "BEQ loc_2459", + "mnemonic": "BEQ", + "operands": "loc_2459", + "kind": "branch", + "targets": [ + 9305 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9282, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + } + } + } + } + }, + { + "address": 9297, + "address_region": "program_or_external", + "bytes": "15F404F5", + "text": "BTST.B #5, @H'F404", + "mnemonic": "BTST.B", + "operands": "#5, @H'F404", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 62468, + "name": null, + "symbol": "mem_F404", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9297, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9301, + "address_region": "program_or_external", + "bytes": "2702", + "text": "BEQ loc_2459", + "mnemonic": "BEQ", + "operands": "loc_2459", + "kind": "branch", + "targets": [ + 9305 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9297, + "changes": [], + "notes": [] + } + }, + { + "address": 9303, + "address_region": "program_or_external", + "bytes": "ABCE", + "text": "BSET.W #14, R3", + "mnemonic": "BSET.W", + "operands": "#14, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9303, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "unsupported:BSET.W" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "unsupported operation invalidated R3" + ] + } + }, + { + "address": 9305, + "address_region": "program_or_external", + "bytes": "1E19F8", + "text": "BSR loc_3E54", + "mnemonic": "BSR", + "operands": "loc_3E54", + "kind": "call", + "targets": [ + 15956 + ], + "cycles": { + "cycles": 14, + "base_cycles": 9, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9305, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9308, + "address_region": "program_or_external", + "bytes": "2021", + "text": "BRA loc_247F", + "mnemonic": "BRA", + "operands": "loc_247F", + "kind": "jump", + "targets": [ + 9343 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "cycles": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9305, + "changes": [], + "notes": [] + } + }, + { + "address": 9310, + "address_region": "program_or_external", + "bytes": "588000", + "text": "MOV:I.W #H'8000, R0", + "mnemonic": "MOV:I.W", + "operands": "#H'8000, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9310, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 32768, + "hex": "0x8000", + "width": 16, + "source": "MOV:I.W #H'8000, R0" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "R0 = 0x8000" + ], + "known_after": { + "registers": { + "R0": { + "known": true, + "value": 32768, + "hex": "0x8000", + "width": 16, + "source": "MOV:I.W #H'8000, R0" + } + } + } + } + }, + { + "address": 9313, + "address_region": "program_or_external", + "bytes": "30FF59", + "text": "BRA loc_23BD", + "mnemonic": "BRA", + "operands": "loc_23BD", + "kind": "jump", + "targets": [ + 9149 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "cycles": 8, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9310, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R0": { + "known": true, + "value": 32768, + "hex": "0x8000", + "width": 16, + "source": "MOV:I.W #H'8000, R0" + } + } + } + } + }, + { + "address": 9316, + "address_region": "program_or_external", + "bytes": "1DE106D0", + "text": "BCLR.W #0, @H'E106", + "mnemonic": "BCLR.W", + "operands": "#0, @H'E106", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 9, + "base_cycles": 8, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 57606, + "name": null, + "symbol": "mem_E106", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9316, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9320, + "address_region": "program_or_external", + "bytes": "5C0001", + "text": "MOV:I.W #H'0001, R4", + "mnemonic": "MOV:I.W", + "operands": "#H'0001, R4", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9316, + "changes": [ + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 1, + "hex": "0x0001", + "width": 16, + "source": "MOV:I.W #H'0001, R4" + } + } + ], + "notes": [ + "R4 = 0x0001" + ], + "known_after": { + "registers": { + "R4": { + "known": true, + "value": 1, + "hex": "0x0001", + "width": 16, + "source": "MOV:I.W #H'0001, R4" + } + } + } + } + }, + { + "address": 9323, + "address_region": "program_or_external", + "bytes": "5B0083", + "text": "MOV:I.W #H'0083, R3", + "mnemonic": "MOV:I.W", + "operands": "#H'0083, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9316, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + } + } + ], + "notes": [ + "R3 = 0x0083" + ], + "known_after": { + "registers": { + "R3": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + }, + "R4": { + "known": true, + "value": 1, + "hex": "0x0001", + "width": 16, + "source": "MOV:I.W #H'0001, R4" + } + } + } + } + }, + { + "address": 9326, + "address_region": "program_or_external", + "bytes": "15F791F7", + "text": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "operands": "#7, @H'F791", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63377, + "name": null, + "symbol": "ram_F791", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9316, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R3": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + }, + "R4": { + "known": true, + "value": 1, + "hex": "0x0001", + "width": 16, + "source": "MOV:I.W #H'0001, R4" + } + } + } + } + }, + { + "address": 9330, + "address_region": "program_or_external", + "bytes": "2708", + "text": "BEQ loc_247C", + "mnemonic": "BEQ", + "operands": "loc_247C", + "kind": "branch", + "targets": [ + 9340 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9316, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R3": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + }, + "R4": { + "known": true, + "value": 1, + "hex": "0x0001", + "width": 16, + "source": "MOV:I.W #H'0001, R4" + } + } + } + } + }, + { + "address": 9332, + "address_region": "program_or_external", + "bytes": "15F404F5", + "text": "BTST.B #5, @H'F404", + "mnemonic": "BTST.B", + "operands": "#5, @H'F404", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 62468, + "name": null, + "symbol": "mem_F404", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9332, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9336, + "address_region": "program_or_external", + "bytes": "2702", + "text": "BEQ loc_247C", + "mnemonic": "BEQ", + "operands": "loc_247C", + "kind": "branch", + "targets": [ + 9340 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9332, + "changes": [], + "notes": [] + } + }, + { + "address": 9338, + "address_region": "program_or_external", + "bytes": "ABCE", + "text": "BSET.W #14, R3", + "mnemonic": "BSET.W", + "operands": "#14, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9338, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "unsupported:BSET.W" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "unsupported operation invalidated R3" + ] + } + }, + { + "address": 9340, + "address_region": "program_or_external", + "bytes": "1EF5B6", + "text": "BSR loc_1A35", + "mnemonic": "BSR", + "operands": "loc_1A35", + "kind": "call", + "targets": [ + 6709 + ], + "cycles": { + "cycles": 13, + "base_cycles": 9, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9340, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9343, + "address_region": "program_or_external", + "bytes": "19", + "text": "RTS", + "mnemonic": "RTS", + "operands": "", + "kind": "return", + "targets": [], + "cycles": { + "cycles": 13, + "base_cycles": 8, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word pop from stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9343, + "changes": [], + "notes": [] + } + }, + { + "address": 9344, + "address_region": "program_or_external", + "bytes": "15F730F7", + "text": "BTST.B #7, @H'F730", + "mnemonic": "BTST.B", + "operands": "#7, @H'F730", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63280, + "name": null, + "symbol": "ram_F730", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9344, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9348, + "address_region": "program_or_external", + "bytes": "2705", + "text": "BEQ loc_248B", + "mnemonic": "BEQ", + "operands": "loc_248B", + "kind": "branch", + "targets": [ + 9355 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9344, + "changes": [], + "notes": [] + } + }, + { + "address": 9350, + "address_region": "program_or_external", + "bytes": "584000", + "text": "MOV:I.W #H'4000, R0", + "mnemonic": "MOV:I.W", + "operands": "#H'4000, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9350, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 16384, + "hex": "0x4000", + "width": 16, + "source": "MOV:I.W #H'4000, R0" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "R0 = 0x4000" + ], + "known_after": { + "registers": { + "R0": { + "known": true, + "value": 16384, + "hex": "0x4000", + "width": 16, + "source": "MOV:I.W #H'4000, R0" + } + } + } + } + }, + { + "address": 9353, + "address_region": "program_or_external", + "bytes": "2003", + "text": "BRA loc_248E", + "mnemonic": "BRA", + "operands": "loc_248E", + "kind": "jump", + "targets": [ + 9358 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "cycles": 8, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9350, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R0": { + "known": true, + "value": 16384, + "hex": "0x4000", + "width": 16, + "source": "MOV:I.W #H'4000, R0" + } + } + } + } + }, + { + "address": 9355, + "address_region": "program_or_external", + "bytes": "580020", + "text": "MOV:I.W #H'0020, R0", + "mnemonic": "MOV:I.W", + "operands": "#H'0020, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9355, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 32, + "hex": "0x0020", + "width": 16, + "source": "MOV:I.W #H'0020, R0" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "R0 = 0x0020" + ], + "known_after": { + "registers": { + "R0": { + "known": true, + "value": 32, + "hex": "0x0020", + "width": 16, + "source": "MOV:I.W #H'0020, R0" + } + } + } + } + }, + { + "address": 9358, + "address_region": "program_or_external", + "bytes": "1DE90690", + "text": "MOV:G.W R0, @H'E906", + "mnemonic": "MOV:G.W", + "operands": "R0, @H'E906", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 59654, + "name": null, + "symbol": "mem_E906", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9358, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9362, + "address_region": "program_or_external", + "bytes": "5280", + "text": "MOV:E.B #H'80, R2", + "mnemonic": "MOV:E.B", + "operands": "#H'80, R2", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 2, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9358, + "changes": [ + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + } + } + ], + "notes": [ + "R2 = 0x80" + ], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + } + } + } + } + }, + { + "address": 9364, + "address_region": "program_or_external", + "bytes": "5B0083", + "text": "MOV:I.W #H'0083, R3", + "mnemonic": "MOV:I.W", + "operands": "#H'0083, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9358, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + } + } + ], + "notes": [ + "R3 = 0x0083" + ], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + } + } + } + } + }, + { + "address": 9367, + "address_region": "program_or_external", + "bytes": "15F791F7", + "text": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "operands": "#7, @H'F791", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63377, + "name": null, + "symbol": "ram_F791", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9358, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + } + } + } + } + }, + { + "address": 9371, + "address_region": "program_or_external", + "bytes": "2708", + "text": "BEQ loc_24A5", + "mnemonic": "BEQ", + "operands": "loc_24A5", + "kind": "branch", + "targets": [ + 9381 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9358, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + } + } + } + } + }, + { + "address": 9373, + "address_region": "program_or_external", + "bytes": "15F404F5", + "text": "BTST.B #5, @H'F404", + "mnemonic": "BTST.B", + "operands": "#5, @H'F404", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 62468, + "name": null, + "symbol": "mem_F404", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9373, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9377, + "address_region": "program_or_external", + "bytes": "2702", + "text": "BEQ loc_24A5", + "mnemonic": "BEQ", + "operands": "loc_24A5", + "kind": "branch", + "targets": [ + 9381 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9373, + "changes": [], + "notes": [] + } + }, + { + "address": 9379, + "address_region": "program_or_external", + "bytes": "ABCE", + "text": "BSET.W #14, R3", + "mnemonic": "BSET.W", + "operands": "#14, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9379, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "unsupported:BSET.W" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "unsupported operation invalidated R3" + ] + } + }, + { + "address": 9381, + "address_region": "program_or_external", + "bytes": "1E19AC", + "text": "BSR loc_3E54", + "mnemonic": "BSR", + "operands": "loc_3E54", + "kind": "call", + "targets": [ + 15956 + ], + "cycles": { + "cycles": 14, + "base_cycles": 9, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9381, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9384, + "address_region": "program_or_external", + "bytes": "19", + "text": "RTS", + "mnemonic": "RTS", + "operands": "", + "kind": "return", + "targets": [], + "cycles": { + "cycles": 12, + "base_cycles": 8, + "stack_adjustment": 4, + "note": "PC word pop from stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9381, + "changes": [], + "notes": [] + } + }, + { + "address": 9385, + "address_region": "program_or_external", + "bytes": "15F6D0F3", + "text": "BTST.B #3, @H'F6D0", + "mnemonic": "BTST.B", + "operands": "#3, @H'F6D0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63184, + "name": null, + "symbol": "ram_F6D0", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9385, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9389, + "address_region": "program_or_external", + "bytes": "2738", + "text": "BEQ loc_24E7", + "mnemonic": "BEQ", + "operands": "loc_24E7", + "kind": "branch", + "targets": [ + 9447 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9385, + "changes": [], + "notes": [] + } + }, + { + "address": 9391, + "address_region": "program_or_external", + "bytes": "15F7310402", + "text": "CMP:G.B #H'02, @H'F731", + "mnemonic": "CMP:G.B", + "operands": "#H'02, @H'F731", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63281, + "name": null, + "symbol": "ram_F731", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9391, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9396, + "address_region": "program_or_external", + "bytes": "2231", + "text": "BHI loc_24E7", + "mnemonic": "BHI", + "operands": "loc_24E7", + "kind": "branch", + "targets": [ + 9447 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9391, + "changes": [], + "notes": [] + } + }, + { + "address": 9398, + "address_region": "program_or_external", + "bytes": "1DE110FF", + "text": "BTST.W #15, @H'E110", + "mnemonic": "BTST.W", + "operands": "#15, @H'E110", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 57616, + "name": null, + "symbol": "mem_E110", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9398, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9402, + "address_region": "program_or_external", + "bytes": "2705", + "text": "BEQ loc_24C1", + "mnemonic": "BEQ", + "operands": "loc_24C1", + "kind": "branch", + "targets": [ + 9409 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9398, + "changes": [], + "notes": [] + } + }, + { + "address": 9404, + "address_region": "program_or_external", + "bytes": "1E0229", + "text": "BSR loc_26E8", + "mnemonic": "BSR", + "operands": "loc_26E8", + "kind": "call", + "targets": [ + 9960 + ], + "cycles": { + "cycles": 13, + "base_cycles": 9, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9404, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9407, + "address_region": "program_or_external", + "bytes": "2026", + "text": "BRA loc_24E7", + "mnemonic": "BRA", + "operands": "loc_24E7", + "kind": "jump", + "targets": [ + 9447 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "cycles": 8, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9404, + "changes": [], + "notes": [] + } + }, + { + "address": 9409, + "address_region": "program_or_external", + "bytes": "15F730F7", + "text": "BTST.B #7, @H'F730", + "mnemonic": "BTST.B", + "operands": "#7, @H'F730", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63280, + "name": null, + "symbol": "ram_F730", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9409, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9413, + "address_region": "program_or_external", + "bytes": "2720", + "text": "BEQ loc_24E7", + "mnemonic": "BEQ", + "operands": "loc_24E7", + "kind": "branch", + "targets": [ + 9447 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9409, + "changes": [], + "notes": [] + } + }, + { + "address": 9415, + "address_region": "program_or_external", + "bytes": "1DE10680", + "text": "MOV:G.W @H'E106, R0", + "mnemonic": "MOV:G.W", + "operands": "@H'E106, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 57606, + "name": null, + "symbol": "mem_E106", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9415, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "memory_load" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "R0 unknown after memory load" + ] + } + }, + { + "address": 9419, + "address_region": "program_or_external", + "bytes": "A8E0", + "text": "BNOT.W #0, R0", + "mnemonic": "BNOT.W", + "operands": "#0, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9415, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "memory_load" + }, + "after": { + "known": false, + "reason": "unsupported:BNOT.W" + } + } + ], + "notes": [ + "unsupported operation invalidated R0" + ] + } + }, + { + "address": 9421, + "address_region": "program_or_external", + "bytes": "1DE90690", + "text": "MOV:G.W R0, @H'E906", + "mnemonic": "MOV:G.W", + "operands": "R0, @H'E906", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 59654, + "name": null, + "symbol": "mem_E906", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9415, + "changes": [], + "notes": [] + } + }, + { + "address": 9425, + "address_region": "program_or_external", + "bytes": "5280", + "text": "MOV:E.B #H'80, R2", + "mnemonic": "MOV:E.B", + "operands": "#H'80, R2", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 2, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9415, + "changes": [ + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + } + } + ], + "notes": [ + "R2 = 0x80" + ], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + } + } + } + } + }, + { + "address": 9427, + "address_region": "program_or_external", + "bytes": "5B0083", + "text": "MOV:I.W #H'0083, R3", + "mnemonic": "MOV:I.W", + "operands": "#H'0083, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9415, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + } + } + ], + "notes": [ + "R3 = 0x0083" + ], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + } + } + } + } + }, + { + "address": 9430, + "address_region": "program_or_external", + "bytes": "15F791F7", + "text": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "operands": "#7, @H'F791", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63377, + "name": null, + "symbol": "ram_F791", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9415, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + } + } + } + } + }, + { + "address": 9434, + "address_region": "program_or_external", + "bytes": "2708", + "text": "BEQ loc_24E4", + "mnemonic": "BEQ", + "operands": "loc_24E4", + "kind": "branch", + "targets": [ + 9444 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9415, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 131, + "hex": "0x0083", + "width": 16, + "source": "MOV:I.W #H'0083, R3" + } + } + } + } + }, + { + "address": 9436, + "address_region": "program_or_external", + "bytes": "15F404F5", + "text": "BTST.B #5, @H'F404", + "mnemonic": "BTST.B", + "operands": "#5, @H'F404", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 62468, + "name": null, + "symbol": "mem_F404", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9436, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9440, + "address_region": "program_or_external", + "bytes": "2702", + "text": "BEQ loc_24E4", + "mnemonic": "BEQ", + "operands": "loc_24E4", + "kind": "branch", + "targets": [ + 9444 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9436, + "changes": [], + "notes": [] + } + }, + { + "address": 9442, + "address_region": "program_or_external", + "bytes": "ABCE", + "text": "BSET.W #14, R3", + "mnemonic": "BSET.W", + "operands": "#14, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9442, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "unsupported:BSET.W" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "unsupported operation invalidated R3" + ] + } + }, + { + "address": 9444, + "address_region": "program_or_external", + "bytes": "1E196D", + "text": "BSR loc_3E54", + "mnemonic": "BSR", + "operands": "loc_3E54", + "kind": "call", + "targets": [ + 15956 + ], + "cycles": { + "cycles": 13, + "base_cycles": 9, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9444, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9447, + "address_region": "program_or_external", + "bytes": "19", + "text": "RTS", + "mnemonic": "RTS", + "operands": "", + "kind": "return", + "targets": [], + "cycles": { + "cycles": 13, + "base_cycles": 8, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word pop from stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9447, + "changes": [], + "notes": [] + } + }, + { + "address": 9448, + "address_region": "program_or_external", + "bytes": "15F6D0F7", + "text": "BTST.B #7, @H'F6D0", + "mnemonic": "BTST.B", + "operands": "#7, @H'F6D0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63184, + "name": null, + "symbol": "ram_F6D0", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9448, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9452, + "address_region": "program_or_external", + "bytes": "273F", + "text": "BEQ loc_252D", + "mnemonic": "BEQ", + "operands": "loc_252D", + "kind": "branch", + "targets": [ + 9517 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9448, + "changes": [], + "notes": [] + } + }, + { + "address": 9454, + "address_region": "program_or_external", + "bytes": "15F7310402", + "text": "CMP:G.B #H'02, @H'F731", + "mnemonic": "CMP:G.B", + "operands": "#H'02, @H'F731", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63281, + "name": null, + "symbol": "ram_F731", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9454, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9459, + "address_region": "program_or_external", + "bytes": "2238", + "text": "BHI loc_252D", + "mnemonic": "BHI", + "operands": "loc_252D", + "kind": "branch", + "targets": [ + 9517 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9454, + "changes": [], + "notes": [] + } + }, + { + "address": 9461, + "address_region": "program_or_external", + "bytes": "1DE110FE", + "text": "BTST.W #14, @H'E110", + "mnemonic": "BTST.W", + "operands": "#14, @H'E110", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 57616, + "name": null, + "symbol": "mem_E110", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9461, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9465, + "address_region": "program_or_external", + "bytes": "2705", + "text": "BEQ loc_2500", + "mnemonic": "BEQ", + "operands": "loc_2500", + "kind": "branch", + "targets": [ + 9472 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9461, + "changes": [], + "notes": [] + } + }, + { + "address": 9467, + "address_region": "program_or_external", + "bytes": "1E01EA", + "text": "BSR loc_26E8", + "mnemonic": "BSR", + "operands": "loc_26E8", + "kind": "call", + "targets": [ + 9960 + ], + "cycles": { + "cycles": 14, + "base_cycles": 9, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9467, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9470, + "address_region": "program_or_external", + "bytes": "202D", + "text": "BRA loc_252D", + "mnemonic": "BRA", + "operands": "loc_252D", + "kind": "jump", + "targets": [ + 9517 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "cycles": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9467, + "changes": [], + "notes": [] + } + }, + { + "address": 9472, + "address_region": "program_or_external", + "bytes": "15F6F613", + "text": "CLR.B @H'F6F6", + "mnemonic": "CLR.B", + "operands": "@H'F6F6", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 9, + "base_cycles": 8, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63222, + "name": null, + "symbol": "ram_F6F6", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9472, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9476, + "address_region": "program_or_external", + "bytes": "1DE11E80", + "text": "MOV:G.W @H'E11E, R0", + "mnemonic": "MOV:G.W", + "operands": "@H'E11E, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 57630, + "name": null, + "symbol": "mem_E11E", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9472, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "memory_load" + } + } + ], + "notes": [ + "R0 unknown after memory load" + ] + } + }, + { + "address": 9480, + "address_region": "program_or_external", + "bytes": "A8FF", + "text": "BTST.W #15, R0", + "mnemonic": "BTST.W", + "operands": "#15, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9472, + "changes": [], + "notes": [] + } + }, + { + "address": 9482, + "address_region": "program_or_external", + "bytes": "2605", + "text": "BNE loc_2511", + "mnemonic": "BNE", + "operands": "loc_2511", + "kind": "branch", + "targets": [ + 9489 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9472, + "changes": [], + "notes": [] + } + }, + { + "address": 9484, + "address_region": "program_or_external", + "bytes": "588000", + "text": "MOV:I.W #H'8000, R0", + "mnemonic": "MOV:I.W", + "operands": "#H'8000, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9484, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 32768, + "hex": "0x8000", + "width": 16, + "source": "MOV:I.W #H'8000, R0" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "R0 = 0x8000" + ], + "known_after": { + "registers": { + "R0": { + "known": true, + "value": 32768, + "hex": "0x8000", + "width": 16, + "source": "MOV:I.W #H'8000, R0" + } + } + } + } + }, + { + "address": 9487, + "address_region": "program_or_external", + "bytes": "2002", + "text": "BRA loc_2513", + "mnemonic": "BRA", + "operands": "loc_2513", + "kind": "jump", + "targets": [ + 9491 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "cycles": 8, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9484, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R0": { + "known": true, + "value": 32768, + "hex": "0x8000", + "width": 16, + "source": "MOV:I.W #H'8000, R0" + } + } + } + } + }, + { + "address": 9489, + "address_region": "program_or_external", + "bytes": "A813", + "text": "CLR.W R0", + "mnemonic": "CLR.W", + "operands": "R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9489, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 0, + "hex": "0x0000", + "width": 16, + "source": "CLR.W R0" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "R0 cleared" + ], + "known_after": { + "registers": { + "R0": { + "known": true, + "value": 0, + "hex": "0x0000", + "width": 16, + "source": "CLR.W R0" + } + } + } + } + }, + { + "address": 9491, + "address_region": "program_or_external", + "bytes": "1DE91E90", + "text": "MOV:G.W R0, @H'E91E", + "mnemonic": "MOV:G.W", + "operands": "R0, @H'E91E", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 59678, + "name": null, + "symbol": "mem_E91E", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9491, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9495, + "address_region": "program_or_external", + "bytes": "5280", + "text": "MOV:E.B #H'80, R2", + "mnemonic": "MOV:E.B", + "operands": "#H'80, R2", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 2, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9491, + "changes": [ + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + } + } + ], + "notes": [ + "R2 = 0x80" + ], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + } + } + } + } + }, + { + "address": 9497, + "address_region": "program_or_external", + "bytes": "5B008F", + "text": "MOV:I.W #H'008F, R3", + "mnemonic": "MOV:I.W", + "operands": "#H'008F, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9491, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 143, + "hex": "0x008F", + "width": 16, + "source": "MOV:I.W #H'008F, R3" + } + } + ], + "notes": [ + "R3 = 0x008F" + ], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 143, + "hex": "0x008F", + "width": 16, + "source": "MOV:I.W #H'008F, R3" + } + } + } + } + }, + { + "address": 9500, + "address_region": "program_or_external", + "bytes": "15F791F7", + "text": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "operands": "#7, @H'F791", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63377, + "name": null, + "symbol": "ram_F791", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9491, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 143, + "hex": "0x008F", + "width": 16, + "source": "MOV:I.W #H'008F, R3" + } + } + } + } + }, + { + "address": 9504, + "address_region": "program_or_external", + "bytes": "2708", + "text": "BEQ loc_252A", + "mnemonic": "BEQ", + "operands": "loc_252A", + "kind": "branch", + "targets": [ + 9514 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9491, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 143, + "hex": "0x008F", + "width": 16, + "source": "MOV:I.W #H'008F, R3" + } + } + } + } + }, + { + "address": 9506, + "address_region": "program_or_external", + "bytes": "15F404F4", + "text": "BTST.B #4, @H'F404", + "mnemonic": "BTST.B", + "operands": "#4, @H'F404", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 62468, + "name": null, + "symbol": "mem_F404", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9506, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9510, + "address_region": "program_or_external", + "bytes": "2702", + "text": "BEQ loc_252A", + "mnemonic": "BEQ", + "operands": "loc_252A", + "kind": "branch", + "targets": [ + 9514 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9506, + "changes": [], + "notes": [] + } + }, + { + "address": 9512, + "address_region": "program_or_external", + "bytes": "ABCE", + "text": "BSET.W #14, R3", + "mnemonic": "BSET.W", + "operands": "#14, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9512, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "unsupported:BSET.W" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "unsupported operation invalidated R3" + ] + } + }, + { + "address": 9514, + "address_region": "program_or_external", + "bytes": "1E1927", + "text": "BSR loc_3E54", + "mnemonic": "BSR", + "operands": "loc_3E54", + "kind": "call", + "targets": [ + 15956 + ], + "cycles": { + "cycles": 13, + "base_cycles": 9, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9514, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9517, + "address_region": "program_or_external", + "bytes": "19", + "text": "RTS", + "mnemonic": "RTS", + "operands": "", + "kind": "return", + "targets": [], + "cycles": { + "cycles": 13, + "base_cycles": 8, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word pop from stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9517, + "changes": [], + "notes": [] + } + }, + { + "address": 9518, + "address_region": "program_or_external", + "bytes": "15F6D0F6", + "text": "BTST.B #6, @H'F6D0", + "mnemonic": "BTST.B", + "operands": "#6, @H'F6D0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63184, + "name": null, + "symbol": "ram_F6D0", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9518, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9522, + "address_region": "program_or_external", + "bytes": "273F", + "text": "BEQ loc_2573", + "mnemonic": "BEQ", + "operands": "loc_2573", + "kind": "branch", + "targets": [ + 9587 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9518, + "changes": [], + "notes": [] + } + }, + { + "address": 9524, + "address_region": "program_or_external", + "bytes": "15F7310402", + "text": "CMP:G.B #H'02, @H'F731", + "mnemonic": "CMP:G.B", + "operands": "#H'02, @H'F731", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63281, + "name": null, + "symbol": "ram_F731", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9524, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9529, + "address_region": "program_or_external", + "bytes": "2238", + "text": "BHI loc_2573", + "mnemonic": "BHI", + "operands": "loc_2573", + "kind": "branch", + "targets": [ + 9587 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9524, + "changes": [], + "notes": [] + } + }, + { + "address": 9531, + "address_region": "program_or_external", + "bytes": "1DE110FE", + "text": "BTST.W #14, @H'E110", + "mnemonic": "BTST.W", + "operands": "#14, @H'E110", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 57616, + "name": null, + "symbol": "mem_E110", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9531, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9535, + "address_region": "program_or_external", + "bytes": "2705", + "text": "BEQ loc_2546", + "mnemonic": "BEQ", + "operands": "loc_2546", + "kind": "branch", + "targets": [ + 9542 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9531, + "changes": [], + "notes": [] + } + }, + { + "address": 9537, + "address_region": "program_or_external", + "bytes": "1E01A4", + "text": "BSR loc_26E8", + "mnemonic": "BSR", + "operands": "loc_26E8", + "kind": "call", + "targets": [ + 9960 + ], + "cycles": { + "cycles": 14, + "base_cycles": 9, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9537, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9540, + "address_region": "program_or_external", + "bytes": "202D", + "text": "BRA loc_2573", + "mnemonic": "BRA", + "operands": "loc_2573", + "kind": "jump", + "targets": [ + 9587 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "cycles": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9537, + "changes": [], + "notes": [] + } + }, + { + "address": 9542, + "address_region": "program_or_external", + "bytes": "15F6F613", + "text": "CLR.B @H'F6F6", + "mnemonic": "CLR.B", + "operands": "@H'F6F6", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 9, + "base_cycles": 8, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63222, + "name": null, + "symbol": "ram_F6F6", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9542, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9546, + "address_region": "program_or_external", + "bytes": "1DE11E80", + "text": "MOV:G.W @H'E11E, R0", + "mnemonic": "MOV:G.W", + "operands": "@H'E11E, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 57630, + "name": null, + "symbol": "mem_E11E", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9542, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "memory_load" + } + } + ], + "notes": [ + "R0 unknown after memory load" + ] + } + }, + { + "address": 9550, + "address_region": "program_or_external", + "bytes": "A8FD", + "text": "BTST.W #13, R0", + "mnemonic": "BTST.W", + "operands": "#13, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9542, + "changes": [], + "notes": [] + } + }, + { + "address": 9552, + "address_region": "program_or_external", + "bytes": "2605", + "text": "BNE loc_2557", + "mnemonic": "BNE", + "operands": "loc_2557", + "kind": "branch", + "targets": [ + 9559 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9542, + "changes": [], + "notes": [] + } + }, + { + "address": 9554, + "address_region": "program_or_external", + "bytes": "582000", + "text": "MOV:I.W #H'2000, R0", + "mnemonic": "MOV:I.W", + "operands": "#H'2000, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9554, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 8192, + "hex": "0x2000", + "width": 16, + "source": "MOV:I.W #H'2000, R0" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "R0 = 0x2000" + ], + "known_after": { + "registers": { + "R0": { + "known": true, + "value": 8192, + "hex": "0x2000", + "width": 16, + "source": "MOV:I.W #H'2000, R0" + } + } + } + } + }, + { + "address": 9557, + "address_region": "program_or_external", + "bytes": "2002", + "text": "BRA loc_2559", + "mnemonic": "BRA", + "operands": "loc_2559", + "kind": "jump", + "targets": [ + 9561 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "cycles": 8, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9554, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R0": { + "known": true, + "value": 8192, + "hex": "0x2000", + "width": 16, + "source": "MOV:I.W #H'2000, R0" + } + } + } + } + }, + { + "address": 9559, + "address_region": "program_or_external", + "bytes": "A813", + "text": "CLR.W R0", + "mnemonic": "CLR.W", + "operands": "R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9559, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 0, + "hex": "0x0000", + "width": 16, + "source": "CLR.W R0" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "R0 cleared" + ], + "known_after": { + "registers": { + "R0": { + "known": true, + "value": 0, + "hex": "0x0000", + "width": 16, + "source": "CLR.W R0" + } + } + } + } + }, + { + "address": 9561, + "address_region": "program_or_external", + "bytes": "1DE91E90", + "text": "MOV:G.W R0, @H'E91E", + "mnemonic": "MOV:G.W", + "operands": "R0, @H'E91E", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 59678, + "name": null, + "symbol": "mem_E91E", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9561, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9565, + "address_region": "program_or_external", + "bytes": "5280", + "text": "MOV:E.B #H'80, R2", + "mnemonic": "MOV:E.B", + "operands": "#H'80, R2", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 2, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9561, + "changes": [ + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + } + } + ], + "notes": [ + "R2 = 0x80" + ], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + } + } + } + } + }, + { + "address": 9567, + "address_region": "program_or_external", + "bytes": "5B008F", + "text": "MOV:I.W #H'008F, R3", + "mnemonic": "MOV:I.W", + "operands": "#H'008F, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9561, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 143, + "hex": "0x008F", + "width": 16, + "source": "MOV:I.W #H'008F, R3" + } + } + ], + "notes": [ + "R3 = 0x008F" + ], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 143, + "hex": "0x008F", + "width": 16, + "source": "MOV:I.W #H'008F, R3" + } + } + } + } + }, + { + "address": 9570, + "address_region": "program_or_external", + "bytes": "15F791F7", + "text": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "operands": "#7, @H'F791", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63377, + "name": null, + "symbol": "ram_F791", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9561, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 143, + "hex": "0x008F", + "width": 16, + "source": "MOV:I.W #H'008F, R3" + } + } + } + } + }, + { + "address": 9574, + "address_region": "program_or_external", + "bytes": "2708", + "text": "BEQ loc_2570", + "mnemonic": "BEQ", + "operands": "loc_2570", + "kind": "branch", + "targets": [ + 9584 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9561, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 143, + "hex": "0x008F", + "width": 16, + "source": "MOV:I.W #H'008F, R3" + } + } + } + } + }, + { + "address": 9576, + "address_region": "program_or_external", + "bytes": "15F404F4", + "text": "BTST.B #4, @H'F404", + "mnemonic": "BTST.B", + "operands": "#4, @H'F404", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 62468, + "name": null, + "symbol": "mem_F404", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9576, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9580, + "address_region": "program_or_external", + "bytes": "2702", + "text": "BEQ loc_2570", + "mnemonic": "BEQ", + "operands": "loc_2570", + "kind": "branch", + "targets": [ + 9584 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9576, + "changes": [], + "notes": [] + } + }, + { + "address": 9582, + "address_region": "program_or_external", + "bytes": "ABCE", + "text": "BSET.W #14, R3", + "mnemonic": "BSET.W", + "operands": "#14, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9582, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "unsupported:BSET.W" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "unsupported operation invalidated R3" + ] + } + }, + { + "address": 9584, + "address_region": "program_or_external", + "bytes": "1E18E1", + "text": "BSR loc_3E54", + "mnemonic": "BSR", + "operands": "loc_3E54", + "kind": "call", + "targets": [ + 15956 + ], + "cycles": { + "cycles": 13, + "base_cycles": 9, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9584, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9587, + "address_region": "program_or_external", + "bytes": "19", + "text": "RTS", + "mnemonic": "RTS", + "operands": "", + "kind": "return", + "targets": [], + "cycles": { + "cycles": 13, + "base_cycles": 8, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word pop from stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9587, + "changes": [], + "notes": [] + } + }, + { + "address": 9588, + "address_region": "program_or_external", + "bytes": "15F6D0F4", + "text": "BTST.B #4, @H'F6D0", + "mnemonic": "BTST.B", + "operands": "#4, @H'F6D0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63184, + "name": null, + "symbol": "ram_F6D0", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9588, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9592, + "address_region": "program_or_external", + "bytes": "370145", + "text": "BEQ loc_26C0", + "mnemonic": "BEQ", + "operands": "loc_26C0", + "kind": "branch", + "targets": [ + 9920 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9588, + "changes": [], + "notes": [] + } + }, + { + "address": 9595, + "address_region": "program_or_external", + "bytes": "15F7310402", + "text": "CMP:G.B #H'02, @H'F731", + "mnemonic": "CMP:G.B", + "operands": "#H'02, @H'F731", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63281, + "name": null, + "symbol": "ram_F731", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9595, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9600, + "address_region": "program_or_external", + "bytes": "2251", + "text": "BHI loc_25D3", + "mnemonic": "BHI", + "operands": "loc_25D3", + "kind": "branch", + "targets": [ + 9683 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9595, + "changes": [], + "notes": [] + } + }, + { + "address": 9602, + "address_region": "program_or_external", + "bytes": "1DE110FE", + "text": "BTST.W #14, @H'E110", + "mnemonic": "BTST.W", + "operands": "#14, @H'E110", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 57616, + "name": null, + "symbol": "mem_E110", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9602, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9606, + "address_region": "program_or_external", + "bytes": "2705", + "text": "BEQ loc_258D", + "mnemonic": "BEQ", + "operands": "loc_258D", + "kind": "branch", + "targets": [ + 9613 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9602, + "changes": [], + "notes": [] + } + }, + { + "address": 9608, + "address_region": "program_or_external", + "bytes": "1E015D", + "text": "BSR loc_26E8", + "mnemonic": "BSR", + "operands": "loc_26E8", + "kind": "call", + "targets": [ + 9960 + ], + "cycles": { + "cycles": 13, + "base_cycles": 9, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9608, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9611, + "address_region": "program_or_external", + "bytes": "2046", + "text": "BRA loc_25D3", + "mnemonic": "BRA", + "operands": "loc_25D3", + "kind": "jump", + "targets": [ + 9683 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "cycles": 8, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9608, + "changes": [], + "notes": [] + } + }, + { + "address": 9613, + "address_region": "program_or_external", + "bytes": "1DE11E80", + "text": "MOV:G.W @H'E11E, R0", + "mnemonic": "MOV:G.W", + "operands": "@H'E11E, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 57630, + "name": null, + "symbol": "mem_E11E", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9613, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "memory_load" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "R0 unknown after memory load" + ] + } + }, + { + "address": 9617, + "address_region": "program_or_external", + "bytes": "A8FF", + "text": "BTST.W #15, R0", + "mnemonic": "BTST.W", + "operands": "#15, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9613, + "changes": [], + "notes": [] + } + }, + { + "address": 9619, + "address_region": "program_or_external", + "bytes": "2606", + "text": "BNE loc_259B", + "mnemonic": "BNE", + "operands": "loc_259B", + "kind": "branch", + "targets": [ + 9627 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9613, + "changes": [], + "notes": [] + } + }, + { + "address": 9621, + "address_region": "program_or_external", + "bytes": "A8FD", + "text": "BTST.W #13, R0", + "mnemonic": "BTST.W", + "operands": "#13, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9621, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9623, + "address_region": "program_or_external", + "bytes": "2626", + "text": "BNE loc_25BF", + "mnemonic": "BNE", + "operands": "loc_25BF", + "kind": "branch", + "targets": [ + 9663 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9621, + "changes": [], + "notes": [] + } + }, + { + "address": 9625, + "address_region": "program_or_external", + "bytes": "2038", + "text": "BRA loc_25D3", + "mnemonic": "BRA", + "operands": "loc_25D3", + "kind": "jump", + "targets": [ + 9683 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "cycles": 8, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9625, + "changes": [], + "notes": [] + } + }, + { + "address": 9627, + "address_region": "program_or_external", + "bytes": "15F6D0F5", + "text": "BTST.B #5, @H'F6D0", + "mnemonic": "BTST.B", + "operands": "#5, @H'F6D0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63184, + "name": null, + "symbol": "ram_F6D0", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9627, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9631, + "address_region": "program_or_external", + "bytes": "2705", + "text": "BEQ loc_25A6", + "mnemonic": "BEQ", + "operands": "loc_25A6", + "kind": "branch", + "targets": [ + 9638 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9627, + "changes": [], + "notes": [] + } + }, + { + "address": 9633, + "address_region": "program_or_external", + "bytes": "1E008F", + "text": "BSR loc_2633", + "mnemonic": "BSR", + "operands": "loc_2633", + "kind": "call", + "targets": [ + 9779 + ], + "cycles": { + "cycles": 14, + "base_cycles": 9, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9633, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9636, + "address_region": "program_or_external", + "bytes": "202D", + "text": "BRA loc_25D3", + "mnemonic": "BRA", + "operands": "loc_25D3", + "kind": "jump", + "targets": [ + 9683 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "cycles": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9633, + "changes": [], + "notes": [] + } + }, + { + "address": 9638, + "address_region": "program_or_external", + "bytes": "5C0000", + "text": "MOV:I.W #H'0000, R4", + "mnemonic": "MOV:I.W", + "operands": "#H'0000, R4", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9638, + "changes": [ + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 0, + "hex": "0x0000", + "width": 16, + "source": "MOV:I.W #H'0000, R4" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "R4 = 0x0000" + ], + "known_after": { + "registers": { + "R4": { + "known": true, + "value": 0, + "hex": "0x0000", + "width": 16, + "source": "MOV:I.W #H'0000, R4" + } + } + } + } + }, + { + "address": 9641, + "address_region": "program_or_external", + "bytes": "5B0091", + "text": "MOV:I.W #H'0091, R3", + "mnemonic": "MOV:I.W", + "operands": "#H'0091, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9638, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 145, + "hex": "0x0091", + "width": 16, + "source": "MOV:I.W #H'0091, R3" + } + } + ], + "notes": [ + "R3 = 0x0091" + ], + "known_after": { + "registers": { + "R3": { + "known": true, + "value": 145, + "hex": "0x0091", + "width": 16, + "source": "MOV:I.W #H'0091, R3" + }, + "R4": { + "known": true, + "value": 0, + "hex": "0x0000", + "width": 16, + "source": "MOV:I.W #H'0000, R4" + } + } + } + } + }, + { + "address": 9644, + "address_region": "program_or_external", + "bytes": "15F791F7", + "text": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "operands": "#7, @H'F791", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63377, + "name": null, + "symbol": "ram_F791", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9638, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R3": { + "known": true, + "value": 145, + "hex": "0x0091", + "width": 16, + "source": "MOV:I.W #H'0091, R3" + }, + "R4": { + "known": true, + "value": 0, + "hex": "0x0000", + "width": 16, + "source": "MOV:I.W #H'0000, R4" + } + } + } + } + }, + { + "address": 9648, + "address_region": "program_or_external", + "bytes": "2708", + "text": "BEQ loc_25BA", + "mnemonic": "BEQ", + "operands": "loc_25BA", + "kind": "branch", + "targets": [ + 9658 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9638, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R3": { + "known": true, + "value": 145, + "hex": "0x0091", + "width": 16, + "source": "MOV:I.W #H'0091, R3" + }, + "R4": { + "known": true, + "value": 0, + "hex": "0x0000", + "width": 16, + "source": "MOV:I.W #H'0000, R4" + } + } + } + } + }, + { + "address": 9650, + "address_region": "program_or_external", + "bytes": "15F404F4", + "text": "BTST.B #4, @H'F404", + "mnemonic": "BTST.B", + "operands": "#4, @H'F404", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 62468, + "name": null, + "symbol": "mem_F404", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9650, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9654, + "address_region": "program_or_external", + "bytes": "2702", + "text": "BEQ loc_25BA", + "mnemonic": "BEQ", + "operands": "loc_25BA", + "kind": "branch", + "targets": [ + 9658 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9650, + "changes": [], + "notes": [] + } + }, + { + "address": 9656, + "address_region": "program_or_external", + "bytes": "ABCE", + "text": "BSET.W #14, R3", + "mnemonic": "BSET.W", + "operands": "#14, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9656, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "unsupported:BSET.W" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "unsupported operation invalidated R3" + ] + } + }, + { + "address": 9658, + "address_region": "program_or_external", + "bytes": "1EF478", + "text": "BSR loc_1A35", + "mnemonic": "BSR", + "operands": "loc_1A35", + "kind": "call", + "targets": [ + 6709 + ], + "cycles": { + "cycles": 13, + "base_cycles": 9, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9658, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9661, + "address_region": "program_or_external", + "bytes": "2014", + "text": "BRA loc_25D3", + "mnemonic": "BRA", + "operands": "loc_25D3", + "kind": "jump", + "targets": [ + 9683 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "cycles": 8, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9658, + "changes": [], + "notes": [] + } + }, + { + "address": 9663, + "address_region": "program_or_external", + "bytes": "15F6D0F5", + "text": "BTST.B #5, @H'F6D0", + "mnemonic": "BTST.B", + "operands": "#5, @H'F6D0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63184, + "name": null, + "symbol": "ram_F6D0", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9663, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9667, + "address_region": "program_or_external", + "bytes": "2705", + "text": "BEQ loc_25CA", + "mnemonic": "BEQ", + "operands": "loc_25CA", + "kind": "branch", + "targets": [ + 9674 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9663, + "changes": [], + "notes": [] + } + }, + { + "address": 9669, + "address_region": "program_or_external", + "bytes": "1E00FF", + "text": "BSR loc_26C7", + "mnemonic": "BSR", + "operands": "loc_26C7", + "kind": "call", + "targets": [ + 9927 + ], + "cycles": { + "cycles": 14, + "base_cycles": 9, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9669, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9672, + "address_region": "program_or_external", + "bytes": "2009", + "text": "BRA loc_25D3", + "mnemonic": "BRA", + "operands": "loc_25D3", + "kind": "jump", + "targets": [ + 9683 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "cycles": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9669, + "changes": [], + "notes": [] + } + }, + { + "address": 9674, + "address_region": "program_or_external", + "bytes": "15F6F606C0", + "text": "MOV:G.B #H'C0, @H'F6F6", + "mnemonic": "MOV:G.B", + "operands": "#H'C0, @H'F6F6", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 9, + "base_cycles": 8, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63222, + "name": null, + "symbol": "ram_F6F6", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9674, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9679, + "address_region": "program_or_external", + "bytes": "1DF6F413", + "text": "CLR.W @H'F6F4", + "mnemonic": "CLR.W", + "operands": "@H'F6F4", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 8, + "base_cycles": 8, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63220, + "name": null, + "symbol": "ram_F6F4", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9674, + "changes": [], + "notes": [] + } + }, + { + "address": 9683, + "address_region": "program_or_external", + "bytes": "19", + "text": "RTS", + "mnemonic": "RTS", + "operands": "", + "kind": "return", + "targets": [], + "cycles": { + "cycles": 13, + "base_cycles": 8, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word pop from stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9683, + "changes": [], + "notes": [] + } + }, + { + "address": 9684, + "address_region": "program_or_external", + "bytes": "15F6D0F5", + "text": "BTST.B #5, @H'F6D0", + "mnemonic": "BTST.B", + "operands": "#5, @H'F6D0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63184, + "name": null, + "symbol": "ram_F6D0", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9684, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9688, + "address_region": "program_or_external", + "bytes": "3700E5", + "text": "BEQ loc_26C0", + "mnemonic": "BEQ", + "operands": "loc_26C0", + "kind": "branch", + "targets": [ + 9920 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9684, + "changes": [], + "notes": [] + } + }, + { + "address": 9691, + "address_region": "program_or_external", + "bytes": "15F7310402", + "text": "CMP:G.B #H'02, @H'F731", + "mnemonic": "CMP:G.B", + "operands": "#H'02, @H'F731", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63281, + "name": null, + "symbol": "ram_F731", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9691, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9696, + "address_region": "program_or_external", + "bytes": "2250", + "text": "BHI loc_2632", + "mnemonic": "BHI", + "operands": "loc_2632", + "kind": "branch", + "targets": [ + 9778 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9691, + "changes": [], + "notes": [] + } + }, + { + "address": 9698, + "address_region": "program_or_external", + "bytes": "1DE110FE", + "text": "BTST.W #14, @H'E110", + "mnemonic": "BTST.W", + "operands": "#14, @H'E110", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 57616, + "name": null, + "symbol": "mem_E110", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9698, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9702, + "address_region": "program_or_external", + "bytes": "2705", + "text": "BEQ loc_25ED", + "mnemonic": "BEQ", + "operands": "loc_25ED", + "kind": "branch", + "targets": [ + 9709 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9698, + "changes": [], + "notes": [] + } + }, + { + "address": 9704, + "address_region": "program_or_external", + "bytes": "1E00FD", + "text": "BSR loc_26E8", + "mnemonic": "BSR", + "operands": "loc_26E8", + "kind": "call", + "targets": [ + 9960 + ], + "cycles": { + "cycles": 13, + "base_cycles": 9, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9704, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9707, + "address_region": "program_or_external", + "bytes": "2045", + "text": "BRA loc_2632", + "mnemonic": "BRA", + "operands": "loc_2632", + "kind": "jump", + "targets": [ + 9778 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "cycles": 8, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9704, + "changes": [], + "notes": [] + } + }, + { + "address": 9709, + "address_region": "program_or_external", + "bytes": "1DE11E80", + "text": "MOV:G.W @H'E11E, R0", + "mnemonic": "MOV:G.W", + "operands": "@H'E11E, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 57630, + "name": null, + "symbol": "mem_E11E", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9709, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "memory_load" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "R0 unknown after memory load" + ] + } + }, + { + "address": 9713, + "address_region": "program_or_external", + "bytes": "A8FF", + "text": "BTST.W #15, R0", + "mnemonic": "BTST.W", + "operands": "#15, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9709, + "changes": [], + "notes": [] + } + }, + { + "address": 9715, + "address_region": "program_or_external", + "bytes": "2606", + "text": "BNE loc_25FB", + "mnemonic": "BNE", + "operands": "loc_25FB", + "kind": "branch", + "targets": [ + 9723 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9709, + "changes": [], + "notes": [] + } + }, + { + "address": 9717, + "address_region": "program_or_external", + "bytes": "A8FD", + "text": "BTST.W #13, R0", + "mnemonic": "BTST.W", + "operands": "#13, R0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9717, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9719, + "address_region": "program_or_external", + "bytes": "2625", + "text": "BNE loc_261E", + "mnemonic": "BNE", + "operands": "loc_261E", + "kind": "branch", + "targets": [ + 9758 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9717, + "changes": [], + "notes": [] + } + }, + { + "address": 9721, + "address_region": "program_or_external", + "bytes": "2037", + "text": "BRA loc_2632", + "mnemonic": "BRA", + "operands": "loc_2632", + "kind": "jump", + "targets": [ + 9778 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "cycles": 8, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9721, + "changes": [], + "notes": [] + } + }, + { + "address": 9723, + "address_region": "program_or_external", + "bytes": "15F6D0F4", + "text": "BTST.B #4, @H'F6D0", + "mnemonic": "BTST.B", + "operands": "#4, @H'F6D0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63184, + "name": null, + "symbol": "ram_F6D0", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9723, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9727, + "address_region": "program_or_external", + "bytes": "2704", + "text": "BEQ loc_2605", + "mnemonic": "BEQ", + "operands": "loc_2605", + "kind": "branch", + "targets": [ + 9733 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9723, + "changes": [], + "notes": [] + } + }, + { + "address": 9729, + "address_region": "program_or_external", + "bytes": "0E30", + "text": "BSR loc_2633", + "mnemonic": "BSR", + "operands": "loc_2633", + "kind": "call", + "targets": [ + 9779 + ], + "cycles": { + "cycles": 14, + "base_cycles": 9, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9729, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9731, + "address_region": "program_or_external", + "bytes": "202D", + "text": "BRA loc_2632", + "mnemonic": "BRA", + "operands": "loc_2632", + "kind": "jump", + "targets": [ + 9778 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "cycles": 8, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9729, + "changes": [], + "notes": [] + } + }, + { + "address": 9733, + "address_region": "program_or_external", + "bytes": "5C0001", + "text": "MOV:I.W #H'0001, R4", + "mnemonic": "MOV:I.W", + "operands": "#H'0001, R4", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9733, + "changes": [ + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 1, + "hex": "0x0001", + "width": 16, + "source": "MOV:I.W #H'0001, R4" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "R4 = 0x0001" + ], + "known_after": { + "registers": { + "R4": { + "known": true, + "value": 1, + "hex": "0x0001", + "width": 16, + "source": "MOV:I.W #H'0001, R4" + } + } + } + } + }, + { + "address": 9736, + "address_region": "program_or_external", + "bytes": "5B0091", + "text": "MOV:I.W #H'0091, R3", + "mnemonic": "MOV:I.W", + "operands": "#H'0091, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9733, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 145, + "hex": "0x0091", + "width": 16, + "source": "MOV:I.W #H'0091, R3" + } + } + ], + "notes": [ + "R3 = 0x0091" + ], + "known_after": { + "registers": { + "R3": { + "known": true, + "value": 145, + "hex": "0x0091", + "width": 16, + "source": "MOV:I.W #H'0091, R3" + }, + "R4": { + "known": true, + "value": 1, + "hex": "0x0001", + "width": 16, + "source": "MOV:I.W #H'0001, R4" + } + } + } + } + }, + { + "address": 9739, + "address_region": "program_or_external", + "bytes": "15F791F7", + "text": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "operands": "#7, @H'F791", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63377, + "name": null, + "symbol": "ram_F791", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9733, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R3": { + "known": true, + "value": 145, + "hex": "0x0091", + "width": 16, + "source": "MOV:I.W #H'0091, R3" + }, + "R4": { + "known": true, + "value": 1, + "hex": "0x0001", + "width": 16, + "source": "MOV:I.W #H'0001, R4" + } + } + } + } + }, + { + "address": 9743, + "address_region": "program_or_external", + "bytes": "2708", + "text": "BEQ loc_2619", + "mnemonic": "BEQ", + "operands": "loc_2619", + "kind": "branch", + "targets": [ + 9753 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9733, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R3": { + "known": true, + "value": 145, + "hex": "0x0091", + "width": 16, + "source": "MOV:I.W #H'0091, R3" + }, + "R4": { + "known": true, + "value": 1, + "hex": "0x0001", + "width": 16, + "source": "MOV:I.W #H'0001, R4" + } + } + } + } + }, + { + "address": 9745, + "address_region": "program_or_external", + "bytes": "15F404F4", + "text": "BTST.B #4, @H'F404", + "mnemonic": "BTST.B", + "operands": "#4, @H'F404", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 6, + "base_cycles": 6, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 62468, + "name": null, + "symbol": "mem_F404", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9745, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9749, + "address_region": "program_or_external", + "bytes": "2702", + "text": "BEQ loc_2619", + "mnemonic": "BEQ", + "operands": "loc_2619", + "kind": "branch", + "targets": [ + 9753 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9745, + "changes": [], + "notes": [] + } + }, + { + "address": 9751, + "address_region": "program_or_external", + "bytes": "ABCE", + "text": "BSET.W #14, R3", + "mnemonic": "BSET.W", + "operands": "#14, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9751, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "unsupported:BSET.W" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "unsupported operation invalidated R3" + ] + } + }, + { + "address": 9753, + "address_region": "program_or_external", + "bytes": "1EF419", + "text": "BSR loc_1A35", + "mnemonic": "BSR", + "operands": "loc_1A35", + "kind": "call", + "targets": [ + 6709 + ], + "cycles": { + "cycles": 14, + "base_cycles": 9, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9753, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9756, + "address_region": "program_or_external", + "bytes": "2014", + "text": "BRA loc_2632", + "mnemonic": "BRA", + "operands": "loc_2632", + "kind": "jump", + "targets": [ + 9778 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "cycles": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9753, + "changes": [], + "notes": [] + } + }, + { + "address": 9758, + "address_region": "program_or_external", + "bytes": "15F6D0F4", + "text": "BTST.B #4, @H'F6D0", + "mnemonic": "BTST.B", + "operands": "#4, @H'F6D0", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63184, + "name": null, + "symbol": "ram_F6D0", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9758, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9762, + "address_region": "program_or_external", + "bytes": "2705", + "text": "BEQ loc_2629", + "mnemonic": "BEQ", + "operands": "loc_2629", + "kind": "branch", + "targets": [ + 9769 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9758, + "changes": [], + "notes": [] + } + }, + { + "address": 9764, + "address_region": "program_or_external", + "bytes": "1E00A0", + "text": "BSR loc_26C7", + "mnemonic": "BSR", + "operands": "loc_26C7", + "kind": "call", + "targets": [ + 9927 + ], + "cycles": { + "cycles": 13, + "base_cycles": 9, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9764, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9767, + "address_region": "program_or_external", + "bytes": "2009", + "text": "BRA loc_2632", + "mnemonic": "BRA", + "operands": "loc_2632", + "kind": "jump", + "targets": [ + 9778 + ], + "cycles": { + "not_taken": 3, + "taken": 8, + "base_taken": 7, + "alignment_adjustment_taken": 1, + "cycles": 8, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9764, + "changes": [], + "notes": [] + } + }, + { + "address": 9769, + "address_region": "program_or_external", + "bytes": "15F6F60680", + "text": "MOV:G.B #H'80, @H'F6F6", + "mnemonic": "MOV:G.B", + "operands": "#H'80, @H'F6F6", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 9, + "base_cycles": 8, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63222, + "name": null, + "symbol": "ram_F6F6", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9769, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9774, + "address_region": "program_or_external", + "bytes": "1DF6F413", + "text": "CLR.W @H'F6F4", + "mnemonic": "CLR.W", + "operands": "@H'F6F4", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 9, + "base_cycles": 8, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63220, + "name": null, + "symbol": "ram_F6F4", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9769, + "changes": [], + "notes": [] + } + }, + { + "address": 9778, + "address_region": "program_or_external", + "bytes": "19", + "text": "RTS", + "mnemonic": "RTS", + "operands": "", + "kind": "return", + "targets": [], + "cycles": { + "cycles": 12, + "base_cycles": 8, + "stack_adjustment": 4, + "note": "PC word pop from stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9778, + "changes": [], + "notes": [] + } + }, + { + "address": 9779, + "address_region": "program_or_external", + "bytes": "1DE922078000", + "text": "MOV:G.W #H'8000, @H'E922", + "mnemonic": "MOV:G.W", + "operands": "#H'8000, @H'E922", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 9, + "base_cycles": 9, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 59682, + "name": null, + "symbol": "mem_E922", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9779, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9785, + "address_region": "program_or_external", + "bytes": "5280", + "text": "MOV:E.B #H'80, R2", + "mnemonic": "MOV:E.B", + "operands": "#H'80, R2", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 2, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9779, + "changes": [ + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + } + } + ], + "notes": [ + "R2 = 0x80" + ], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + } + } + } + } + }, + { + "address": 9787, + "address_region": "program_or_external", + "bytes": "5B0091", + "text": "MOV:I.W #H'0091, R3", + "mnemonic": "MOV:I.W", + "operands": "#H'0091, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9779, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 145, + "hex": "0x0091", + "width": 16, + "source": "MOV:I.W #H'0091, R3" + } + } + ], + "notes": [ + "R3 = 0x0091" + ], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 145, + "hex": "0x0091", + "width": 16, + "source": "MOV:I.W #H'0091, R3" + } + } + } + } + }, + { + "address": 9790, + "address_region": "program_or_external", + "bytes": "15F791F7", + "text": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "operands": "#7, @H'F791", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63377, + "name": null, + "symbol": "ram_F791", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9779, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 145, + "hex": "0x0091", + "width": 16, + "source": "MOV:I.W #H'0091, R3" + } + } + } + } + }, + { + "address": 9794, + "address_region": "program_or_external", + "bytes": "2708", + "text": "BEQ loc_264C", + "mnemonic": "BEQ", + "operands": "loc_264C", + "kind": "branch", + "targets": [ + 9804 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9779, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 145, + "hex": "0x0091", + "width": 16, + "source": "MOV:I.W #H'0091, R3" + } + } + } + } + }, + { + "address": 9796, + "address_region": "program_or_external", + "bytes": "15F404F4", + "text": "BTST.B #4, @H'F404", + "mnemonic": "BTST.B", + "operands": "#4, @H'F404", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 62468, + "name": null, + "symbol": "mem_F404", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9796, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9800, + "address_region": "program_or_external", + "bytes": "2702", + "text": "BEQ loc_264C", + "mnemonic": "BEQ", + "operands": "loc_264C", + "kind": "branch", + "targets": [ + 9804 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9796, + "changes": [], + "notes": [] + } + }, + { + "address": 9802, + "address_region": "program_or_external", + "bytes": "ABCE", + "text": "BSET.W #14, R3", + "mnemonic": "BSET.W", + "operands": "#14, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9802, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "unsupported:BSET.W" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "unsupported operation invalidated R3" + ] + } + }, + { + "address": 9804, + "address_region": "program_or_external", + "bytes": "1E1805", + "text": "BSR loc_3E54", + "mnemonic": "BSR", + "operands": "loc_3E54", + "kind": "call", + "targets": [ + 15956 + ], + "cycles": { + "cycles": 13, + "base_cycles": 9, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9804, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9807, + "address_region": "program_or_external", + "bytes": "19", + "text": "RTS", + "mnemonic": "RTS", + "operands": "", + "kind": "return", + "targets": [], + "cycles": { + "cycles": 13, + "base_cycles": 8, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word pop from stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9804, + "changes": [], + "notes": [] + } + } + ], + "decompiler_consistency": { + "kind": "decompiler_pseudocode_consistency", + "summary": "No byte-immediate-to-word destination cases found.", + "checks": [] + }, + "serial_semantics": { + "kind": "serial_semantics", + "protocol_semantics": [], + "fields": [], + "command_dispatch": null, + "commands": [], + "command_effects": [], + "response_candidates": [], + "response_schemas": [], + "response_schema": [], + "logical_table_map_candidates": [], + "table_map_candidates": [], + "state_variable_candidates": [], + "retry_error_model": null, + "gate_queue_model": null, + "tx_report_model": null, + "periodic_resend_model": null, + "timer_interrupt_model": null, + "confidence": "low", + "confidence_score": 0.0, + "caveat": "No protocol semantics are emitted without both RX and TX serial reconstruction candidates." + } +} \ No newline at end of file diff --git a/build/rom_f109_tail.asm b/build/rom_f109_tail.asm new file mode 100644 index 0000000..0cc01f6 --- /dev/null +++ b/build/rom_f109_tail.asm @@ -0,0 +1,107 @@ +; H8/536 ROM disassembly +; input: ROM\M27C512@DIP28_1.BIN +; bytes: 65536 +; vector mode: min +; analysis: recursive trace from vectors +; +; Notes from the manual: +; - H8/536 uses the H8/500 CPU instruction set. +; - In minimum mode the reset vector at H'0000-H'0001 is a 16-bit PC. +; - The register field is H'FE80-H'FFFF; names below come from appendix B. +; - @aa:8 short absolute operands use BR as the upper address byte. +; - SCI baud inference uses section 14.2.8 BRR formulas when SMR/BRR are known. +; - LCD inference treats E-clock H'F200/H'F201 accesses as status/control and data candidates. +; - Pass --clock-hz to convert SCI BRR settings into numeric baud rates. +; - Cycle counts use Appendix A tables A-7/A-8 for on-chip access with no external wait states. + +; Memory Map +; H'0000-H'009F exception_vectors vectors +; H'00A0-H'00FF dtc_vectors dtc_vectors +; H'0100-H'F67F program_or_external program +; H'F680-H'FE7F on_chip_ram ram +; H'FE80-H'FFFF register_field registers + +; Vectors +; H'0000 reset -> vec_reset_1000 (H'1000) +; H'0004 invalid_instruction -> vec_reset_1000 (H'1000) +; H'0006 zero_divide -> vec_reset_1000 (H'1000) +; H'0008 trap_vs -> vec_reset_1000 (H'1000) +; H'0010 address_error -> vec_reset_1000 (H'1000) +; H'0012 trace -> vec_reset_1000 (H'1000) +; H'0016 nmi -> vec_nmi_4393 (H'4393) +; H'0020 trapa_0 -> vec_reset_1000 (H'1000) +; H'0022 trapa_1 -> vec_reset_1000 (H'1000) +; H'0024 trapa_2 -> vec_reset_1000 (H'1000) +; H'0026 trapa_3 -> vec_reset_1000 (H'1000) +; H'0028 trapa_4 -> vec_reset_1000 (H'1000) +; H'002A trapa_5 -> vec_reset_1000 (H'1000) +; H'002C trapa_6 -> vec_reset_1000 (H'1000) +; H'002E trapa_7 -> vec_reset_1000 (H'1000) +; H'0030 trapa_8 -> vec_reset_1000 (H'1000) +; H'0032 trapa_9 -> vec_reset_1000 (H'1000) +; H'0034 trapa_a -> vec_reset_1000 (H'1000) +; H'0036 trapa_b -> vec_reset_1000 (H'1000) +; H'0038 trapa_c -> vec_reset_1000 (H'1000) +; H'003A trapa_d -> vec_reset_1000 (H'1000) +; H'003C trapa_e -> vec_reset_1000 (H'1000) +; H'003E trapa_f -> vec_reset_1000 (H'1000) +; H'0040 irq0 -> vec_reset_1000 (H'1000) +; H'0042 interval_timer -> vec_interval_timer_BFC4 (H'BFC4) +; H'0048 irq1 -> vec_reset_1000 (H'1000) +; H'0050 irq2 -> vec_reset_1000 (H'1000) +; H'0052 irq3 -> vec_irq3_3C30 (H'3C30) +; H'0058 irq4 -> vec_irq4_3AC7 (H'3AC7) +; H'005A irq5 -> vec_reset_1000 (H'1000) +; H'0062 frt1_ocia -> vec_frt1_ocia_BEEA (H'BEEA) +; H'006A frt2_ocia -> vec_frt2_ocia_BF23 (H'BF23) +; H'0080 sci1_eri -> vec_sci1_eri_BB57 (H'BB57) +; H'0082 sci1_rxi -> vec_sci1_rxi_BB67 (H'BB67) +; H'0084 sci1_txi -> vec_sci1_txi_BA84 (H'BA84) +; H'0090 ad_adi -> vec_ad_adi_3D99 (H'3D99) + +; Symbols +; mem_E924 H'E924 program_or_external memory r=0 w=1 width=word +; mem_F404 H'F404 program_or_external memory r=1 w=0 width=byte +; ram_F6F6 H'F6F6 on_chip_ram ram r=0 w=2 width=byte +; ram_F732 H'F732 on_chip_ram ram r=1 w=1 width=word +; ram_F734 H'F734 on_chip_ram ram r=0 w=1 width=word +; ram_F791 H'F791 on_chip_ram ram r=1 w=0 width=byte +; ram_FB02 H'FB02 on_chip_ram ram r=0 w=1 width=byte +; ram_FB03 H'FB03 on_chip_ram ram r=1 w=1 width=byte + +; Board Profile +; Board trace ties the H8/536 SCI1 pins to a MAX202 RS232 transceiver. +; H8 pin 66 P95/TXD (TXD) -> MAX202 pin 11 +; H8 pin 67 P96/RXD (RXD) -> MAX202 pin 12 +; SCI2 pin routing is disabled by SYSCR2.P9SCI2E=0 in the observed setup. + +; LCD/Text Scan +; search 'CONNECT': not literal, hits=0 +; LCD text candidates +; ... 1 more LCD text candidates + +26C0: 15 F6 F6 13 CLR.B @H'F6F6 ; refs ram_F6F6 in on_chip_ram; cycles=9 +26C4: 30 FF 0C BRA loc_25D3 ; cycles=7 +26C7: 15 F6 F6 13 CLR.B @H'F6F6 ; refs ram_F6F6 in on_chip_ram; cycles=8 +26CB: 1D E9 24 07 FF 80 MOV:G.W #H'FF80, @H'E924 ; refs mem_E924 in program_or_external; cycles=9 +26D1: 52 80 MOV:E.B #H'80, R2 ; dataflow R2=H'80; cycles=2 +26D3: 5B 00 92 MOV:I.W #H'0092, R3 ; dataflow R3=H'0092; cycles=3 +26D6: 15 F7 91 F7 BTST.B #7, @H'F791 ; refs ram_F791 in on_chip_ram; cycles=7 +26DA: 27 08 BEQ loc_26E4 ; cycles=3/7 nt/t +26DC: 15 F4 04 F4 BTST.B #4, @H'F404 ; refs mem_F404 in program_or_external; cycles=7 +26E0: 27 02 BEQ loc_26E4 ; cycles=3/7 nt/t +26E2: AB CE BSET.W #14, R3 ; cycles=3 + +loc_26E4: +26E4: 1E 17 6D BSR loc_3E54 ; cycles=13 +26E7: 19 RTS ; cycles=13 +26E8: 15 FB 03 C7 BSET.B #7, @H'FB03 ; refs ram_FB03 in on_chip_ram; cycles=9 +26EC: 26 08 BNE loc_26F6 ; cycles=3/7 nt/t +26EE: 1D F7 32 81 MOV:G.W @H'F732, R1 ; refs ram_F732 in on_chip_ram; cycles=7 +26F2: 1D F7 34 91 MOV:G.W R1, @H'F734 ; refs ram_F734 in on_chip_ram; cycles=7 + +loc_26F6: +26F6: 1D F7 32 07 1C 01 MOV:G.W #H'1C01, @H'F732 ; refs ram_F732 in on_chip_ram; cycles=11 +26FC: 15 FB 02 06 14 MOV:G.B #H'14, @H'FB02 ; refs ram_FB02 in on_chip_ram; cycles=9 +2701: 1E 21 F6 BSR loc_48FA ; cycles=14 +2704: 19 RTS ; cycles=12 diff --git a/build/rom_f109_tail.json b/build/rom_f109_tail.json new file mode 100644 index 0000000..3261965 --- /dev/null +++ b/build/rom_f109_tail.json @@ -0,0 +1,2076 @@ +{ + "vectors": [ + { + "address": 0, + "name": "reset", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 4, + "name": "invalid_instruction", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 6, + "name": "zero_divide", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 8, + "name": "trap_vs", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 16, + "name": "address_error", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 18, + "name": "trace", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 22, + "name": "nmi", + "target": 17299, + "target_label": "vec_nmi_4393" + }, + { + "address": 32, + "name": "trapa_0", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 34, + "name": "trapa_1", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 36, + "name": "trapa_2", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 38, + "name": "trapa_3", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 40, + "name": "trapa_4", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 42, + "name": "trapa_5", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 44, + "name": "trapa_6", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 46, + "name": "trapa_7", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 48, + "name": "trapa_8", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 50, + "name": "trapa_9", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 52, + "name": "trapa_a", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 54, + "name": "trapa_b", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 56, + "name": "trapa_c", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 58, + "name": "trapa_d", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 60, + "name": "trapa_e", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 62, + "name": "trapa_f", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 64, + "name": "irq0", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 66, + "name": "interval_timer", + "target": 49092, + "target_label": "vec_interval_timer_BFC4" + }, + { + "address": 72, + "name": "irq1", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 80, + "name": "irq2", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 82, + "name": "irq3", + "target": 15408, + "target_label": "vec_irq3_3C30" + }, + { + "address": 88, + "name": "irq4", + "target": 15047, + "target_label": "vec_irq4_3AC7" + }, + { + "address": 90, + "name": "irq5", + "target": 4096, + "target_label": "vec_reset_1000" + }, + { + "address": 98, + "name": "frt1_ocia", + "target": 48874, + "target_label": "vec_frt1_ocia_BEEA" + }, + { + "address": 106, + "name": "frt2_ocia", + "target": 48931, + "target_label": "vec_frt2_ocia_BF23" + }, + { + "address": 128, + "name": "sci1_eri", + "target": 47959, + "target_label": "vec_sci1_eri_BB57" + }, + { + "address": 130, + "name": "sci1_rxi", + "target": 47975, + "target_label": "vec_sci1_rxi_BB67" + }, + { + "address": 132, + "name": "sci1_txi", + "target": 47748, + "target_label": "vec_sci1_txi_BA84" + }, + { + "address": 144, + "name": "ad_adi", + "target": 15769, + "target_label": "vec_ad_adi_3D99" + } + ], + "dtc_vectors": [], + "memory_regions": [ + { + "name": "exception_vectors", + "start": 0, + "end": 159, + "kind": "vectors", + "manual": "section 2 address space" + }, + { + "name": "dtc_vectors", + "start": 160, + "end": 255, + "kind": "dtc_vectors", + "manual": "section 2 address space" + }, + { + "name": "program_or_external", + "start": 256, + "end": 63103, + "kind": "program", + "manual": "section 2/17 mode-dependent ROM or external space" + }, + { + "name": "on_chip_ram", + "start": 63104, + "end": 65151, + "kind": "ram", + "manual": "section 16 RAM" + }, + { + "name": "register_field", + "start": 65152, + "end": 65535, + "kind": "registers", + "manual": "appendix B register map" + } + ], + "data_candidates": { + "strings": [], + "pointer_tables": [] + }, + "call_graph": { + "nodes": [], + "edges": [] + }, + "timing_summary": { + "blocks": [], + "loops": [] + }, + "sci": { + "clock_hz": null, + "formulas": { + "async": "B = clock_hz / (64 * 2^(2n) * (N + 1))", + "sync": "B = clock_hz / (8 * 2^(2n) * (N + 1))" + }, + "manual_references": [ + "Manual/0900766b802125d0.md:15837 SMR selects SCI mode and CKS1/CKS0 internal clock source", + "Manual/0900766b802125d0.md:16027 SCR.CKE1 selects internal or external clock source", + "Manual/0900766b802125d0.md:16177 BRR and SMR.CKS determine the baud-rate generator", + "Manual/0900766b802125d0.md:16303 asynchronous BRR formula", + "Manual/0900766b802125d0.md:16379 synchronous BRR formula", + "Manual/0900766b802125d0.md:16410 SCI clock source selection tables" + ], + "channels": { + "SCI1": { + "writes": [], + "configurations": [] + }, + "SCI2": { + "writes": [], + "configurations": [] + } + } + }, + "sci_protocol": { + "manual_references": [ + "Manual/0900766b802125d0.md:15748 SCI register map for RDR/TDR/SCR/SSR", + "Manual/0900766b802125d0.md:15794 RDR stores received data and is CPU-readable", + "Manual/0900766b802125d0.md:15823 TDR holds the next byte to transmit", + "Manual/0900766b802125d0.md:15976 SCR.TIE enables/disables TXI on TDRE", + "Manual/0900766b802125d0.md:15993 SCR.RIE enables RXI and ERI", + "Manual/0900766b802125d0.md:16008 SCR.TE enables the transmitter", + "Manual/0900766b802125d0.md:16028 SCR.RE enables the receiver", + "Manual/0900766b802125d0.md:16090 SSR flags are cleared by writing zero", + "Manual/0900766b802125d0.md:16100 SSR.TDRE means TDR can accept the next byte", + "Manual/0900766b802125d0.md:16116 SSR.RDRF means received data reached RDR", + "Manual/0900766b802125d0.md:16127 SSR.ORER reports receive overrun", + "Manual/0900766b802125d0.md:16140 SSR.FER reports framing errors", + "Manual/0900766b802125d0.md:16147 SSR.PER reports parity errors" + ], + "channels": { + "SCI1": { + "events": [] + }, + "SCI2": { + "events": [] + } + }, + "events": [] + }, + "serial_reconstruction": { + "kind": "serial_reconstruction", + "candidates": [], + "ram_roles": [], + "evidence": [], + "required_evidence": { + "tx": [ + "tx_buffer_region", + "tx_checksum_seed", + "checksum_byte", + "xor_checksum_chain", + "initial_send_from_buffer_start", + "tx_index_initialized_to_one", + "tx_isr_indexed_send", + "tx_index_increment", + "tx_index_compare_frame_length" + ], + "rx": [ + "rx_rdr_read", + "rx_indexed_store", + "rx_index_increment_store", + "rx_isr_compare_frame_length", + "rx_complete_timer", + "rx_processor_requires_six_bytes", + "rx_copy_capture_to_frame_buffer", + "rx_checksum_seed", + "rx_xor_checksum_validation" + ] + } + }, + "board_profile": { + "board": "sony_rcp_tx7", + "name": "Sony RCP-TX7", + "summary": "Board trace ties the H8/536 SCI1 pins to a MAX202 RS232 transceiver.", + "manual_references": [ + "Manual/0900766b802125d0.md:2417 FP-80 H8/536 pin 66 is P95/TXD", + "Manual/0900766b802125d0.md:2418 FP-80 H8/536 pin 67 is P96/RXD", + "Manual/0900766b802125d0.md:11192 Port 9 carries SCI1 and SCI2 serial signals", + "Manual/0900766b802125d0.md:11201 P96 is RXD1 input", + "Manual/0900766b802125d0.md:11202 P95 is TXD1 output", + "Manual/0900766b802125d0.md:15725 SCI1 RXD input pin", + "Manual/0900766b802125d0.md:15726 SCI1 TXD output pin", + "Manual/0900766b802125d0.md:15750 SCI register table starts with SCI1 RDR/TDR/SMR/SCR/SSR/BRR", + "Manual/0900766b802125d0.md:15758 SCI register table lists SCI2 RDR/TDR/SMR/SCR/SSR/BRR", + "Manual/0900766b802125d0.md:15794 RDR receive data register", + "Manual/0900766b802125d0.md:15823 TDR transmit data register", + "Manual/0900766b802125d0.md:15969 SCR enables and disables SCI functions", + "Manual/0900766b802125d0.md:16009 SCR.TE makes the TXD pin output", + "Manual/0900766b802125d0.md:16029 SCR.RE makes the RXD pin input", + "Manual/0900766b802125d0.md:16090 SSR contains transmit/receive status flags", + "Manual/0900766b802125d0.md:10560 SYSCR2 controls port 9 pin functions", + "Manual/0900766b802125d0.md:10631 SYSCR2.P9SCI2E controls the SCI2 functions of P92-P94" + ], + "traces": [ + { + "channel": "SCI1", + "signal": "TXD", + "h8_pin": 66, + "h8_pin_name": "P95/TXD", + "h8_function": "TXD1", + "max202_pin": 11, + "evidence": "MAX202 pin 11 traces to H8 pin 66" + }, + { + "channel": "SCI1", + "signal": "RXD", + "h8_pin": 67, + "h8_pin_name": "P96/RXD", + "h8_function": "RXD1", + "max202_pin": 12, + "evidence": "MAX202 pin 12 traces to H8 pin 67" + } + ], + "channels": { + "SCI1": { + "traced_to_max202": true, + "path": "RS232/MAX202", + "pins": [ + { + "channel": "SCI1", + "signal": "TXD", + "h8_pin": 66, + "h8_pin_name": "P95/TXD", + "h8_function": "TXD1", + "max202_pin": 11, + "evidence": "MAX202 pin 11 traces to H8 pin 66" + }, + { + "channel": "SCI1", + "signal": "RXD", + "h8_pin": 67, + "h8_pin_name": "P96/RXD", + "h8_function": "RXD1", + "max202_pin": 12, + "evidence": "MAX202 pin 12 traces to H8 pin 67" + } + ], + "scr": { + "value": 12, + "value_hex": "H'0C", + "tie": false, + "rie": false, + "tx_enabled": false, + "rx_enabled": false + }, + "accesses": [] + }, + "SCI2": { + "traced_to_max202": false, + "path": null, + "note": "Sony RCP-TX7 MAX202 board traces are on SCI1 P95/P96, not SCI2 P92/P93.", + "p9sci2e": false, + "scr": { + "value": 12, + "value_hex": "H'0C", + "tie": false, + "rie": false, + "tx_enabled": false, + "rx_enabled": false + }, + "accesses": [] + } + }, + "instructions": {}, + "state": { + "SYSCR2": { + "value": 128, + "value_hex": "H'80" + }, + "P9SCI2E": false + } + }, + "peripheral_access": { + "manual_references": [ + "Manual/0900766b802125d0.md:12185 FRT FRC/OCRA/OCRB/ICR use TEMP for 16-bit CPU access", + "Manual/0900766b802125d0.md:12193 FRT byte access order is upper byte then lower byte", + "Manual/0900766b802125d0.md:12212 OCRA/OCRB reads are direct; writes still use TEMP", + "Manual/0900766b802125d0.md:17546 A/D ADDRA-ADDRD lower byte is accessed through TEMP", + "Manual/0900766b802125d0.md:17556 A/D full-result byte reads must be upper byte then lower byte" + ], + "warnings": [] + }, + "indirect_flow": { + "sites": [] + }, + "dataflow": { + "blocks": [ + { + "start": 9920, + "instructions": [ + 9920, + 9924 + ], + "end": 9924, + "end_exclusive": 9927 + }, + { + "start": 9927, + "instructions": [ + 9927, + 9931, + 9937, + 9939, + 9942, + 9946 + ], + "end": 9946, + "end_exclusive": 9948 + }, + { + "start": 9948, + "instructions": [ + 9948, + 9952 + ], + "end": 9952, + "end_exclusive": 9954 + }, + { + "start": 9954, + "instructions": [ + 9954 + ], + "end": 9954, + "end_exclusive": 9956 + }, + { + "start": 9956, + "instructions": [ + 9956, + 9959 + ], + "end": 9959, + "end_exclusive": 9960 + }, + { + "start": 9960, + "instructions": [ + 9960, + 9964 + ], + "end": 9964, + "end_exclusive": 9966 + }, + { + "start": 9966, + "instructions": [ + 9966, + 9970 + ], + "end": 9970, + "end_exclusive": 9974 + }, + { + "start": 9974, + "instructions": [ + 9974, + 9980, + 9985, + 9988 + ], + "end": 9988, + "end_exclusive": 9989 + } + ], + "registers": [ + "R0", + "R1", + "R2", + "R3", + "R4", + "R5", + "R6", + "R7" + ], + "control_registers": [ + "CCR", + "BR", + "EP", + "DP", + "TP", + "SR" + ] + }, + "symbols": { + "symbols": [ + { + "address": 59684, + "name": "mem_E924", + "region": "program_or_external", + "kind": "memory", + "access_count": 1, + "read_count": 0, + "write_count": 1, + "unknown_count": 0, + "width_hints": [ + "word" + ], + "width": "word", + "first_access": 9931, + "last_access": 9931, + "accesses": [ + { + "address": 59684, + "instruction_address": 9931, + "instruction": "MOV:G.W #H'FF80, @H'E924", + "mnemonic": "MOV:G.W", + "direction": "write", + "width": "word", + "operand": "@H'E924", + "operand_index": 1 + } + ] + }, + { + "address": 62468, + "name": "mem_F404", + "region": "program_or_external", + "kind": "memory", + "access_count": 1, + "read_count": 1, + "write_count": 0, + "unknown_count": 0, + "width_hints": [ + "byte" + ], + "width": "byte", + "first_access": 9948, + "last_access": 9948, + "accesses": [ + { + "address": 62468, + "instruction_address": 9948, + "instruction": "BTST.B #4, @H'F404", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F404", + "operand_index": 1 + } + ] + }, + { + "address": 63222, + "name": "ram_F6F6", + "region": "on_chip_ram", + "kind": "ram", + "access_count": 2, + "read_count": 0, + "write_count": 2, + "unknown_count": 0, + "width_hints": [ + "byte" + ], + "width": "byte", + "first_access": 9920, + "last_access": 9927, + "accesses": [ + { + "address": 63222, + "instruction_address": 9920, + "instruction": "CLR.B @H'F6F6", + "mnemonic": "CLR.B", + "direction": "write", + "width": "byte", + "operand": "@H'F6F6", + "operand_index": 0 + }, + { + "address": 63222, + "instruction_address": 9927, + "instruction": "CLR.B @H'F6F6", + "mnemonic": "CLR.B", + "direction": "write", + "width": "byte", + "operand": "@H'F6F6", + "operand_index": 0 + } + ] + }, + { + "address": 63282, + "name": "ram_F732", + "region": "on_chip_ram", + "kind": "ram", + "access_count": 2, + "read_count": 1, + "write_count": 1, + "unknown_count": 0, + "width_hints": [ + "word" + ], + "width": "word", + "first_access": 9966, + "last_access": 9974, + "accesses": [ + { + "address": 63282, + "instruction_address": 9966, + "instruction": "MOV:G.W @H'F732, R1", + "mnemonic": "MOV:G.W", + "direction": "read", + "width": "word", + "operand": "@H'F732", + "operand_index": 0 + }, + { + "address": 63282, + "instruction_address": 9974, + "instruction": "MOV:G.W #H'1C01, @H'F732", + "mnemonic": "MOV:G.W", + "direction": "write", + "width": "word", + "operand": "@H'F732", + "operand_index": 1 + } + ] + }, + { + "address": 63284, + "name": "ram_F734", + "region": "on_chip_ram", + "kind": "ram", + "access_count": 1, + "read_count": 0, + "write_count": 1, + "unknown_count": 0, + "width_hints": [ + "word" + ], + "width": "word", + "first_access": 9970, + "last_access": 9970, + "accesses": [ + { + "address": 63284, + "instruction_address": 9970, + "instruction": "MOV:G.W R1, @H'F734", + "mnemonic": "MOV:G.W", + "direction": "write", + "width": "word", + "operand": "@H'F734", + "operand_index": 1 + } + ] + }, + { + "address": 63377, + "name": "ram_F791", + "region": "on_chip_ram", + "kind": "ram", + "access_count": 1, + "read_count": 1, + "write_count": 0, + "unknown_count": 0, + "width_hints": [ + "byte" + ], + "width": "byte", + "first_access": 9942, + "last_access": 9942, + "accesses": [ + { + "address": 63377, + "instruction_address": 9942, + "instruction": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "direction": "read", + "width": "byte", + "operand": "@H'F791", + "operand_index": 1 + } + ] + }, + { + "address": 64258, + "name": "ram_FB02", + "region": "on_chip_ram", + "kind": "ram", + "access_count": 1, + "read_count": 0, + "write_count": 1, + "unknown_count": 0, + "width_hints": [ + "byte" + ], + "width": "byte", + "first_access": 9980, + "last_access": 9980, + "accesses": [ + { + "address": 64258, + "instruction_address": 9980, + "instruction": "MOV:G.B #H'14, @H'FB02", + "mnemonic": "MOV:G.B", + "direction": "write", + "width": "byte", + "operand": "@H'FB02", + "operand_index": 1 + } + ] + }, + { + "address": 64259, + "name": "ram_FB03", + "region": "on_chip_ram", + "kind": "ram", + "access_count": 1, + "read_count": 1, + "write_count": 1, + "unknown_count": 0, + "width_hints": [ + "byte" + ], + "width": "byte", + "first_access": 9960, + "last_access": 9960, + "accesses": [ + { + "address": 64259, + "instruction_address": 9960, + "instruction": "BSET.B #7, @H'FB03", + "mnemonic": "BSET.B", + "direction": "read_write", + "width": "byte", + "operand": "@H'FB03", + "operand_index": 1 + } + ] + } + ], + "by_address": { + "59684": "mem_E924", + "62468": "mem_F404", + "63222": "ram_F6F6", + "63282": "ram_F732", + "63284": "ram_F734", + "63377": "ram_F791", + "64258": "ram_FB02", + "64259": "ram_FB03" + } + }, + "lcd_text": { + "strings": [ + { + "address": 10006, + "length": 5, + "text": "FhG~H", + "trimmed": "FhG~H", + "kind": "printable_run", + "score": 0.67, + "confidence": "low" + } + ], + "regions": [], + "searches": [ + { + "term": "CONNECT", + "literal_hits": [], + "candidate_hits": [], + "near_matches": [], + "status": "not_found" + } + ], + "notes": [ + "LCD text scan is byte-oriented and conservative; strings may be inline script fields.", + "Raw xrefs include MOV:I.W immediates to the string address and nearby record prefixes." + ] + }, + "lcd_driver": { + "addresses": [ + { + "address": 61952, + "name": "lcd_status_control", + "role": "status/control register inferred from busy polling and command writes" + }, + { + "address": 61953, + "name": "lcd_data", + "role": "data register inferred from paired data reads/writes" + } + ], + "accesses": [], + "polling_loops": [], + "routines": [], + "instructions": {} + }, + "instructions": [ + { + "address": 9920, + "address_region": "program_or_external", + "bytes": "15F6F613", + "text": "CLR.B @H'F6F6", + "mnemonic": "CLR.B", + "operands": "@H'F6F6", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 9, + "base_cycles": 8, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63222, + "name": null, + "symbol": "ram_F6F6", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9920, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9924, + "address_region": "program_or_external", + "bytes": "30FF0C", + "text": "BRA loc_25D3", + "mnemonic": "BRA", + "operands": "loc_25D3", + "kind": "jump", + "targets": [ + 9683 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "cycles": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9920, + "changes": [], + "notes": [] + } + }, + { + "address": 9927, + "address_region": "program_or_external", + "bytes": "15F6F613", + "text": "CLR.B @H'F6F6", + "mnemonic": "CLR.B", + "operands": "@H'F6F6", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 8, + "base_cycles": 8, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63222, + "name": null, + "symbol": "ram_F6F6", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9927, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9931, + "address_region": "program_or_external", + "bytes": "1DE92407FF80", + "text": "MOV:G.W #H'FF80, @H'E924", + "mnemonic": "MOV:G.W", + "operands": "#H'FF80, @H'E924", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 9, + "base_cycles": 9, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 59684, + "name": null, + "symbol": "mem_E924", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9927, + "changes": [], + "notes": [] + } + }, + { + "address": 9937, + "address_region": "program_or_external", + "bytes": "5280", + "text": "MOV:E.B #H'80, R2", + "mnemonic": "MOV:E.B", + "operands": "#H'80, R2", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 2, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9927, + "changes": [ + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + } + } + ], + "notes": [ + "R2 = 0x80" + ], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + } + } + } + } + }, + { + "address": 9939, + "address_region": "program_or_external", + "bytes": "5B0092", + "text": "MOV:I.W #H'0092, R3", + "mnemonic": "MOV:I.W", + "operands": "#H'0092, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9927, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": true, + "value": 146, + "hex": "0x0092", + "width": 16, + "source": "MOV:I.W #H'0092, R3" + } + } + ], + "notes": [ + "R3 = 0x0092" + ], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 146, + "hex": "0x0092", + "width": 16, + "source": "MOV:I.W #H'0092, R3" + } + } + } + } + }, + { + "address": 9942, + "address_region": "program_or_external", + "bytes": "15F791F7", + "text": "BTST.B #7, @H'F791", + "mnemonic": "BTST.B", + "operands": "#7, @H'F791", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63377, + "name": null, + "symbol": "ram_F791", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9927, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 146, + "hex": "0x0092", + "width": 16, + "source": "MOV:I.W #H'0092, R3" + } + } + } + } + }, + { + "address": 9946, + "address_region": "program_or_external", + "bytes": "2708", + "text": "BEQ loc_26E4", + "mnemonic": "BEQ", + "operands": "loc_26E4", + "kind": "branch", + "targets": [ + 9956 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9927, + "changes": [], + "notes": [], + "known_after": { + "registers": { + "R2": { + "known": true, + "value": 128, + "hex": "0x80", + "width": 8, + "source": "MOV:E.B #H'80, R2" + }, + "R3": { + "known": true, + "value": 146, + "hex": "0x0092", + "width": 16, + "source": "MOV:I.W #H'0092, R3" + } + } + } + } + }, + { + "address": 9948, + "address_region": "program_or_external", + "bytes": "15F404F4", + "text": "BTST.B #4, @H'F404", + "mnemonic": "BTST.B", + "operands": "#4, @H'F404", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 62468, + "name": null, + "symbol": "mem_F404", + "region": "program_or_external", + "kind": "program" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9948, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9952, + "address_region": "program_or_external", + "bytes": "2702", + "text": "BEQ loc_26E4", + "mnemonic": "BEQ", + "operands": "loc_26E4", + "kind": "branch", + "targets": [ + 9956 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9948, + "changes": [], + "notes": [] + } + }, + { + "address": 9954, + "address_region": "program_or_external", + "bytes": "ABCE", + "text": "BSET.W #14, R3", + "mnemonic": "BSET.W", + "operands": "#14, R3", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 3, + "base_cycles": 3, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9954, + "changes": [ + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "unsupported:BSET.W" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "unsupported operation invalidated R3" + ] + } + }, + { + "address": 9956, + "address_region": "program_or_external", + "bytes": "1E176D", + "text": "BSR loc_3E54", + "mnemonic": "BSR", + "operands": "loc_3E54", + "kind": "call", + "targets": [ + 15956 + ], + "cycles": { + "cycles": 13, + "base_cycles": 9, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9956, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9959, + "address_region": "program_or_external", + "bytes": "19", + "text": "RTS", + "mnemonic": "RTS", + "operands": "", + "kind": "return", + "targets": [], + "cycles": { + "cycles": 13, + "base_cycles": 8, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word pop from stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9956, + "changes": [], + "notes": [] + } + }, + { + "address": 9960, + "address_region": "program_or_external", + "bytes": "15FB03C7", + "text": "BSET.B #7, @H'FB03", + "mnemonic": "BSET.B", + "operands": "#7, @H'FB03", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 9, + "base_cycles": 8, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 64259, + "name": null, + "symbol": "ram_FB03", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9960, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9964, + "address_region": "program_or_external", + "bytes": "2608", + "text": "BNE loc_26F6", + "mnemonic": "BNE", + "operands": "loc_26F6", + "kind": "branch", + "targets": [ + 9974 + ], + "cycles": { + "not_taken": 3, + "taken": 7, + "base_taken": 7, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9960, + "changes": [], + "notes": [] + } + }, + { + "address": 9966, + "address_region": "program_or_external", + "bytes": "1DF73281", + "text": "MOV:G.W @H'F732, R1", + "mnemonic": "MOV:G.W", + "operands": "@H'F732, R1", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63282, + "name": null, + "symbol": "ram_F732", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9966, + "changes": [ + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "memory_load" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [ + "R1 unknown after memory load" + ] + } + }, + { + "address": 9970, + "address_region": "program_or_external", + "bytes": "1DF73491", + "text": "MOV:G.W R1, @H'F734", + "mnemonic": "MOV:G.W", + "operands": "R1, @H'F734", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 7, + "base_cycles": 6, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63284, + "name": null, + "symbol": "ram_F734", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9966, + "changes": [], + "notes": [] + } + }, + { + "address": 9974, + "address_region": "program_or_external", + "bytes": "1DF732071C01", + "text": "MOV:G.W #H'1C01, @H'F732", + "mnemonic": "MOV:G.W", + "operands": "#H'1C01, @H'F732", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 11, + "base_cycles": 9, + "alignment_adjustment": 2, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 63282, + "name": null, + "symbol": "ram_F732", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9974, + "changes": [ + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "flags" + } + } + ], + "notes": [] + } + }, + { + "address": 9980, + "address_region": "program_or_external", + "bytes": "15FB020614", + "text": "MOV:G.B #H'14, @H'FB02", + "mnemonic": "MOV:G.B", + "operands": "#H'14, @H'FB02", + "kind": "normal", + "targets": [], + "cycles": { + "cycles": 9, + "base_cycles": 8, + "alignment_adjustment": 1, + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [ + { + "address": 64258, + "name": null, + "symbol": "ram_FB02", + "region": "on_chip_ram", + "kind": "ram" + } + ], + "comment": "", + "valid": true, + "dataflow": { + "block": 9974, + "changes": [], + "notes": [] + } + }, + { + "address": 9985, + "address_region": "program_or_external", + "bytes": "1E21F6", + "text": "BSR loc_48FA", + "mnemonic": "BSR", + "operands": "loc_48FA", + "kind": "call", + "targets": [ + 18682 + ], + "cycles": { + "cycles": 14, + "base_cycles": 9, + "alignment_adjustment": 1, + "stack_adjustment": 4, + "note": "PC word push to stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9974, + "changes": [ + { + "kind": "register", + "name": "R0", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R1", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R2", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R3", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R4", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R5", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R6", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "register", + "name": "R7", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "CCR", + "before": { + "known": false, + "reason": "flags" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "BR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "EP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "DP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "TP", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + }, + { + "kind": "control", + "name": "SR", + "before": { + "known": false, + "reason": "block_entry" + }, + "after": { + "known": false, + "reason": "call" + } + } + ], + "notes": [ + "call clobbers tracked register state" + ] + } + }, + { + "address": 9988, + "address_region": "program_or_external", + "bytes": "19", + "text": "RTS", + "mnemonic": "RTS", + "operands": "", + "kind": "return", + "targets": [], + "cycles": { + "cycles": 12, + "base_cycles": 8, + "stack_adjustment": 4, + "note": "PC word pop from stack", + "source": "manual Appendix A.4, tables A-7/A-8", + "assumption": "on-chip instruction fetch/operand access, no external wait states" + }, + "references": [], + "comment": "", + "valid": true, + "dataflow": { + "block": 9974, + "changes": [], + "notes": [] + } + } + ], + "decompiler_consistency": { + "kind": "decompiler_pseudocode_consistency", + "summary": "No byte-immediate-to-word destination cases found.", + "checks": [] + }, + "serial_semantics": { + "kind": "serial_semantics", + "protocol_semantics": [], + "fields": [], + "command_dispatch": null, + "commands": [], + "command_effects": [], + "response_candidates": [], + "response_schemas": [], + "response_schema": [], + "logical_table_map_candidates": [], + "table_map_candidates": [], + "state_variable_candidates": [], + "retry_error_model": null, + "gate_queue_model": null, + "tx_report_model": null, + "periodic_resend_model": null, + "timer_interrupt_model": null, + "confidence": "low", + "confidence_score": 0.0, + "caveat": "No protocol semantics are emitted without both RX and TX serial reconstruction candidates." + } +} \ No newline at end of file diff --git a/ccu_emulator/README.md b/ccu_emulator/README.md new file mode 100644 index 0000000..a61e14e --- /dev/null +++ b/ccu_emulator/README.md @@ -0,0 +1,69 @@ +# PT2 Fake CCU + +This folder contains a small modular fake-CCU runner for the Sony RCP PT2-style serial link. + +The first goal is simple: + +1. Open the RCP serial link at `38400 8E1`. +2. Optionally wait for heartbeat. +3. Seed active selector-zero state. +4. Listen for complete RCP report frames. +5. Immediately answer report-looking frames with the neutral command-5 ACK: + +```text +05 00 40 00 00 1F +``` + +ROM and emulator evidence says this consumes the outstanding report cursor without triggering COPY or lamp/display side effects. + +## Run + +Dry-run configuration: + +```powershell +.\.venv\Scripts\python.exe scripts\ccu_emulator.py --dry-run +``` + +Run against the bench RCP on COM5: + +```powershell +.\.venv\Scripts\python.exe scripts\ccu_emulator.py --port COM5 --duration 30 --log captures\ccu-keepalive.txt +``` + +Power-cycle first through the COM6 relay: + +```powershell +.\.venv\Scripts\python.exe scripts\ccu_emulator.py --port COM5 --power-cycle --relay-port COM6 --duration 30 --log captures\ccu-keepalive-powercycle.txt +``` + +Try the older three-frame CONNECT cadence seed instead of the command-0 active seed: + +```powershell +.\.venv\Scripts\python.exe scripts\ccu_emulator.py --seed connect-sequence --seed-gap 0.700 --duration 30 +``` + +Optionally add periodic state refresh traffic: + +```powershell +.\.venv\Scripts\python.exe scripts\ccu_emulator.py --refresh-active --refresh-interval 0.600 --duration 30 +``` + +## Layout + +- `frames.py`: checksums, built-in frames, and simple host-frame builders. +- `policy.py`: decides whether an RCP frame should be ACKed. +- `refresh.py`: optional periodic state-refresh scheduling. +- `serial_link.py`: serial read/write plus checksum-resync frame detection. +- `controller.py`: event loop and stats. +- `cli.py`: command-line entry point. + +## Why Periodic Lamp/Value Writes Help + +Repeated button/lamp/status writes probably do play into the normal CCU flow. The ROM reloads the broad `F9C5` session watchdog on every complete six-byte RX frame, and command-0/command-4/command-6 table writes refresh the selector tables that drive lamps, readouts, and menus. + +So a real CCU likely does both: + +- reactively ACK RCP reports so the report queue advances, and +- stream or refresh panel state so the visible UI remains current. + +The first version keeps those concerns separate: reactive ACKs are always available, while periodic refresh frames are opt-in with `--refresh-frame` or `--refresh-active`. diff --git a/ccu_emulator/__init__.py b/ccu_emulator/__init__.py new file mode 100644 index 0000000..553b632 --- /dev/null +++ b/ccu_emulator/__init__.py @@ -0,0 +1,28 @@ +"""Small fake-CCU helpers for the Sony RCP PT2-style serial link.""" + +from .controller import CcuEmulator, CcuStats +from .frames import ( + ACTIVE_SEED_COMMAND0, + CONNECT_CADENCE_SEQUENCE, + HEARTBEAT_FRAME, + NEUTRAL_ACK_FRAME, + format_frame, + frame_checksum, + frame_checksum_ok, + parse_frame, +) +from .policy import AckPolicy + +__all__ = [ + "ACTIVE_SEED_COMMAND0", + "CONNECT_CADENCE_SEQUENCE", + "CcuEmulator", + "CcuStats", + "HEARTBEAT_FRAME", + "NEUTRAL_ACK_FRAME", + "AckPolicy", + "format_frame", + "frame_checksum", + "frame_checksum_ok", + "parse_frame", +] diff --git a/ccu_emulator/__main__.py b/ccu_emulator/__main__.py new file mode 100644 index 0000000..a049ad7 --- /dev/null +++ b/ccu_emulator/__main__.py @@ -0,0 +1,5 @@ +from .cli import main + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/ccu_emulator/cli.py b/ccu_emulator/cli.py new file mode 100644 index 0000000..8cc532a --- /dev/null +++ b/ccu_emulator/cli.py @@ -0,0 +1,180 @@ +from __future__ import annotations + +import argparse +import sys +import time +from datetime import datetime +from pathlib import Path +from typing import TextIO + +from h8536.bench_connect_lcd import ( + BenchLogger, + _import_serial, + _read_relay_lines, + _relay_command, + _relay_settle, + add_serial_format_args, + open_device_serial, + serial_format_label, +) + +from .controller import CcuConfig, CcuEmulator +from .frames import ACTIVE_SEED_COMMAND0, CONNECT_CADENCE_SEQUENCE, NEUTRAL_ACK_FRAME, format_frame, parse_frame +from .policy import AckPolicy +from .refresh import PeriodicRefresh +from .serial_link import SerialLink + + +def build_arg_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser(description="Run a small fake CCU for the Sony RCP PT2-style serial link.") + parser.add_argument("--port", default="COM5", help="RS232 serial port connected to the RCP") + parser.add_argument("--baud", type=int, default=38400, help="RCP serial baud rate") + add_serial_format_args(parser) + parser.add_argument("--duration", type=float, default=30.0, help="seconds to run the CCU loop") + parser.add_argument("--sync", choices=("checksum", "fixed"), default="checksum", help="RX frame sync strategy") + parser.add_argument("--log", type=Path, help="capture log path") + + parser.add_argument( + "--seed", + choices=("command0", "connect-sequence", "none"), + default="command0", + help="built-in wake-up seed before reactive ACK loop", + ) + parser.add_argument("--seed-frame", action="append", type=parse_frame, help="custom seed frame; repeatable") + parser.add_argument("--seed-gap", type=float, default=0.050, help="seconds to listen after each seed frame") + parser.add_argument("--ready-heartbeats", type=int, default=1, help="heartbeats to observe before seeding") + parser.add_argument("--ready-timeout", type=float, default=10.0, help="seconds to wait for ready heartbeat") + + parser.add_argument("--ack-frame", type=parse_frame, default=NEUTRAL_ACK_FRAME, help="ACK frame to send after RCP reports") + parser.add_argument("--ack-delay", type=float, default=0.0, help="seconds to wait after detecting an RCP frame before ACK") + parser.add_argument("--no-ack-heartbeats", action="store_true", help="do not ACK heartbeat frames") + parser.add_argument("--no-ack-reports", action="store_true", help="do not ACK report-looking frames") + parser.add_argument( + "--no-ack-unlabeled", + action="store_true", + help="do not ACK checksum-valid unlabeled frames outside known report command bytes", + ) + + parser.add_argument("--refresh-frame", action="append", type=parse_frame, help="optional periodic refresh frame") + parser.add_argument( + "--refresh-active", + action="store_true", + help="periodically refresh selector zero with command0 0x8080", + ) + parser.add_argument("--refresh-interval", type=float, default=0.0, help="seconds between optional refresh frames") + parser.add_argument("--loop-poll", type=float, default=0.001, help="sleep between service loop iterations") + + parser.add_argument("--power-cycle", action="store_true", help="power-cycle DUT through relay before starting") + parser.add_argument("--relay-port", default="COM6", help="Pico relay serial port") + parser.add_argument("--relay-baud", type=int, default=115200, help="Pico relay serial baud rate") + parser.add_argument("--power-off-command", default="off", help="relay command used to remove DUT power") + parser.add_argument("--power-on-command", default="on", help="relay command used to apply DUT power") + parser.add_argument("--off-seconds", type=float, default=1.5, help="seconds to hold DUT powered off") + parser.add_argument("--relay-settle", type=float, default=2.0, help="seconds to wait after opening relay port") + + parser.add_argument("--dry-run", action="store_true", help="print configuration without opening serial ports") + return parser + + +def main(argv: list[str] | None = None, *, stdout: TextIO = sys.stdout) -> int: + args = build_arg_parser().parse_args(argv) + seed_frames = _seed_frames(args) + refresh_frames = _refresh_frames(args) + log_path = args.log or _default_log_path() + + if args.dry_run: + _print_dry_run(args, seed_frames, refresh_frames, log_path, stdout) + return 0 + + serial = _import_serial() + logger = BenchLogger(log_path, stdout=stdout) + relay = None + try: + logger.emit("PT2 fake CCU") + logger.emit(f"device={args.port} {args.baud} {serial_format_label(args)} sync={args.sync}") + logger.emit(f"log={log_path}") + logger.emit(f"ack_frame={format_frame(args.ack_frame)}") + logger.emit("seed_frames=" + (" | ".join(format_frame(frame) for frame in seed_frames) or "none")) + if refresh_frames: + logger.emit( + f"refresh_interval={args.refresh_interval:.3f}s frames=" + + " | ".join(format_frame(frame) for frame in refresh_frames) + ) + + with open_device_serial(serial, args) as device: + if args.power_cycle: + relay = serial.Serial(args.relay_port, args.relay_baud, timeout=0.25) + _relay_settle(relay, args.relay_settle, logger) + _relay_command(relay, args.power_off_command, logger) + time.sleep(max(0.0, args.off_seconds)) + device.reset_input_buffer() + _relay_command(relay, args.power_on_command, logger) + else: + device.reset_input_buffer() + + link = SerialLink(device, logger, sync_mode=args.sync) + config = CcuConfig( + seed_frames=tuple(seed_frames), + seed_gap=args.seed_gap, + ack_delay=args.ack_delay, + ready_heartbeats=args.ready_heartbeats, + ready_timeout=args.ready_timeout, + loop_poll=args.loop_poll, + ) + policy = AckPolicy( + ack_frame=args.ack_frame, + ack_reports=not args.no_ack_reports, + ack_heartbeats=not args.no_ack_heartbeats, + ack_unlabeled_checksum_frames=not args.no_ack_unlabeled, + ) + refresh = PeriodicRefresh(frames=refresh_frames, interval=args.refresh_interval) + CcuEmulator(link, logger, config=config, ack_policy=policy, refresh=refresh).run(args.duration) + return 0 + finally: + if relay is not None: + relay.close() + logger.close() + + +def _seed_frames(args: argparse.Namespace) -> list[bytes]: + if args.seed_frame: + return list(args.seed_frame) + if args.seed == "none": + return [] + if args.seed == "connect-sequence": + return list(CONNECT_CADENCE_SEQUENCE) + return [ACTIVE_SEED_COMMAND0] + + +def _refresh_frames(args: argparse.Namespace) -> list[bytes]: + frames = list(args.refresh_frame or []) + if args.refresh_active: + frames.append(ACTIVE_SEED_COMMAND0) + return frames + + +def _print_dry_run( + args: argparse.Namespace, + seed_frames: list[bytes], + refresh_frames: list[bytes], + log_path: Path, + stdout: TextIO, +) -> None: + print(f"device={args.port} {args.baud} {serial_format_label(args)} sync={args.sync}", file=stdout) + print(f"duration={args.duration:.3f}s log={log_path}", file=stdout) + print(f"power_cycle={int(args.power_cycle)} relay={args.relay_port} {args.relay_baud}", file=stdout) + print(f"ack_frame={format_frame(args.ack_frame)}", file=stdout) + print("seed_frames=" + (" | ".join(format_frame(frame) for frame in seed_frames) or "none"), file=stdout) + print( + f"refresh_interval={args.refresh_interval:.3f}s frames=" + + (" | ".join(format_frame(frame) for frame in refresh_frames) or "none"), + file=stdout, + ) + + +def _default_log_path() -> Path: + return Path("captures") / f"ccu-emulator-{datetime.now().strftime('%Y%m%d-%H%M%S')}.txt" + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/ccu_emulator/controller.py b/ccu_emulator/controller.py new file mode 100644 index 0000000..7d4db14 --- /dev/null +++ b/ccu_emulator/controller.py @@ -0,0 +1,149 @@ +from __future__ import annotations + +import time +from dataclasses import dataclass + +from h8536.bench_connect_lcd import BenchLogger, format_frame + +from .frames import ACTIVE_SEED_COMMAND0 +from .policy import AckPolicy +from .refresh import PeriodicRefresh +from .serial_link import RxFrame, SerialLink + + +@dataclass +class CcuStats: + rx_frames: int = 0 + tx_frames: int = 0 + ack_frames: int = 0 + seed_frames: int = 0 + refresh_frames: int = 0 + started_at: float = 0.0 + ended_at: float = 0.0 + + @property + def elapsed(self) -> float: + end = self.ended_at or time.monotonic() + return max(0.0, end - self.started_at) + + +@dataclass(frozen=True) +class CcuConfig: + seed_frames: tuple[bytes, ...] = (ACTIVE_SEED_COMMAND0,) + seed_gap: float = 0.050 + ack_delay: float = 0.0 + ready_heartbeats: int = 1 + ready_timeout: float = 10.0 + loop_poll: float = 0.001 + + +class CcuEmulator: + """Event-driven fake CCU for the PT2-style RCP serial protocol.""" + + def __init__( + self, + link: SerialLink, + logger: BenchLogger, + *, + config: CcuConfig | None = None, + ack_policy: AckPolicy | None = None, + refresh: PeriodicRefresh | None = None, + ) -> None: + self.link = link + self.logger = logger + self.config = config or CcuConfig() + self.ack_policy = ack_policy or AckPolicy() + self.refresh = refresh or PeriodicRefresh() + self.stats = CcuStats() + + def run(self, duration: float) -> CcuStats: + self.stats = CcuStats(started_at=time.monotonic()) + self.logger.event( + "CCU_START " + f"duration={duration:.3f}s seed_frames={len(self.config.seed_frames)} " + f"ack={format_frame(self.ack_policy.ack_frame)}" + ) + self._wait_ready() + self._send_seed_frames() + self.refresh.start() + + deadline = time.monotonic() + max(0.0, duration) + try: + while time.monotonic() < deadline: + self._service_rx() + self._service_refresh() + time.sleep(max(0.0, self.config.loop_poll)) + except KeyboardInterrupt: + self.logger.event("CCU_STOP keyboard_interrupt") + finally: + self.stats.ended_at = time.monotonic() + self._emit_summary() + return self.stats + + def _wait_ready(self) -> None: + if self.config.ready_heartbeats <= 0: + self.logger.event("READY skipped") + return + self.logger.event( + f"READY_WAIT heartbeats={self.config.ready_heartbeats} timeout={self.config.ready_timeout:.3f}s" + ) + start_count = self.link.detector.labels["heartbeat"] + deadline = time.monotonic() + max(0.0, self.config.ready_timeout) + while time.monotonic() < deadline: + for frame in self.link.read_available(): + self._record_rx(frame) + if self.link.detector.labels["heartbeat"] - start_count >= self.config.ready_heartbeats: + self.logger.event(f"READY heartbeat_count={self.link.detector.labels['heartbeat']}") + return + time.sleep(max(0.0, self.config.loop_poll)) + self.logger.event(f"READY_TIMEOUT heartbeat_count={self.link.detector.labels['heartbeat']}") + + def _send_seed_frames(self) -> None: + for index, frame in enumerate(self.config.seed_frames, start=1): + self.link.send(frame, f"seed[{index}]") + self.stats.seed_frames += 1 + self.stats.tx_frames += 1 + self._listen_for(self.config.seed_gap) + + def _listen_for(self, seconds: float) -> None: + deadline = time.monotonic() + max(0.0, seconds) + while time.monotonic() < deadline: + self._service_rx() + self._service_refresh() + time.sleep(max(0.0, self.config.loop_poll)) + + def _service_rx(self) -> None: + for item in self.link.read_available(): + self._record_rx(item) + decision = self.ack_policy.decide(item.frame, item.label) + if not decision.should_ack: + self.logger.event(f"ACK_SKIP reason={decision.reason} frame={format_frame(item.frame)}") + continue + if self.config.ack_delay > 0: + time.sleep(self.config.ack_delay) + self.link.send(decision.frame, f"ack reason={decision.reason}") + self.stats.ack_frames += 1 + self.stats.tx_frames += 1 + + def _service_refresh(self) -> None: + for frame in self.refresh.due_frames(): + self.link.send(frame, "refresh") + self.stats.refresh_frames += 1 + self.stats.tx_frames += 1 + + def _record_rx(self, item: RxFrame) -> None: + self.stats.rx_frames += 1 + + def _emit_summary(self) -> None: + self.logger.emit() + self.logger.emit("CCU Summary") + self.logger.emit(f"elapsed={self.stats.elapsed:.3f}s") + self.logger.emit(f"rx_frames={self.stats.rx_frames}") + self.logger.emit(f"tx_frames={self.stats.tx_frames}") + self.logger.emit(f"ack_frames={self.stats.ack_frames}") + self.logger.emit(f"seed_frames={self.stats.seed_frames}") + self.logger.emit(f"refresh_frames={self.stats.refresh_frames}") + self.logger.emit(f"resync_events={self.link.detector.resync_events}") + self.logger.emit(f"dropped_bytes={self.link.detector.dropped_bytes}") + for label, count in sorted(self.link.detector.labels.items()): + self.logger.emit(f"{label}={count}") diff --git a/ccu_emulator/frames.py b/ccu_emulator/frames.py new file mode 100644 index 0000000..af6705a --- /dev/null +++ b/ccu_emulator/frames.py @@ -0,0 +1,59 @@ +from __future__ import annotations + +from h8536.bench_connect_lcd import format_frame, frame_checksum, frame_checksum_ok, parse_frame + + +FRAME_LENGTH = 6 + +HEARTBEAT_FRAME = bytes.fromhex("0000000080DA") + +# Command 0, selector 0, value 0x8080. This seeds E000/E800 selector zero. +ACTIVE_SEED_COMMAND0 = bytes.fromhex("00000080805A") + +# The older bench cadence sequence. It is still useful as an optional wake-up +# strategy because the real panel proved timing-sensitive around these frames. +CONNECT_CADENCE_SEQUENCE = ( + bytes.fromhex("04000040001E"), + bytes.fromhex("0400008000DE"), + bytes.fromhex("040000C0009E"), +) + +# Command 5, selector 0x0040, value ignored. ROM trace shows this is the safest +# neutral report-consume candidate. +NEUTRAL_ACK_FRAME = bytes.fromhex("05004000001F") + + +def build_frame(command: int, selector: int, value: int) -> bytes: + """Build a six-byte host frame for simple page-0/page-1 selectors. + + This helper covers the selector encodings we currently use in fake-CCU + probes. Keep more exotic mapping in one place when we learn it. + """ + + if not 0 <= command <= 0xFF: + raise ValueError("command byte out of range") + if not 0 <= selector <= 0x01FF: + raise ValueError("selector out of supported range 0x000-0x1FF") + if not 0 <= value <= 0xFFFF: + raise ValueError("value out of range") + + if selector <= 0x007F: + byte1 = 0x00 + byte2 = selector + elif selector <= 0x017F: + byte1 = 0x01 + byte2 = selector - 0x0080 + else: + byte1 = 0x02 + byte2 = selector - 0x0180 + + frame = bytes( + [ + command & 0xFF, + byte1 & 0xFF, + byte2 & 0xFF, + (value >> 8) & 0xFF, + value & 0xFF, + ] + ) + return frame + bytes([frame_checksum(frame)]) diff --git a/ccu_emulator/policy.py b/ccu_emulator/policy.py new file mode 100644 index 0000000..0810762 --- /dev/null +++ b/ccu_emulator/policy.py @@ -0,0 +1,44 @@ +from __future__ import annotations + +from dataclasses import dataclass + +from .frames import HEARTBEAT_FRAME, NEUTRAL_ACK_FRAME, frame_checksum_ok + + +REPORT_COMMAND_BYTES = frozenset({0x00, 0x01, 0x02}) + + +@dataclass(frozen=True) +class AckDecision: + should_ack: bool + frame: bytes = NEUTRAL_ACK_FRAME + reason: str = "" + + +@dataclass(frozen=True) +class AckPolicy: + """Decides whether an RCP-origin frame should get a continuation ACK.""" + + ack_frame: bytes = NEUTRAL_ACK_FRAME + ack_reports: bool = True + ack_heartbeats: bool = True + ack_unlabeled_checksum_frames: bool = True + + def decide(self, frame: bytes, label: str = "") -> AckDecision: + if not frame_checksum_ok(frame): + return AckDecision(False, self.ack_frame, "checksum_bad") + + if frame == HEARTBEAT_FRAME: + if self.ack_heartbeats: + return AckDecision(True, self.ack_frame, "heartbeat_report") + return AckDecision(False, self.ack_frame, "heartbeat_ignored") + + if frame[0] in REPORT_COMMAND_BYTES: + if self.ack_reports: + return AckDecision(True, self.ack_frame, f"report_cmd_{frame[0]:02X}") + return AckDecision(False, self.ack_frame, "reports_disabled") + + if label == "checksum_ok_unlabeled" and self.ack_unlabeled_checksum_frames: + return AckDecision(True, self.ack_frame, "unlabeled_checksum_ok") + + return AckDecision(False, self.ack_frame, f"non_report_cmd_{frame[0]:02X}") diff --git a/ccu_emulator/refresh.py b/ccu_emulator/refresh.py new file mode 100644 index 0000000..dadfe95 --- /dev/null +++ b/ccu_emulator/refresh.py @@ -0,0 +1,41 @@ +from __future__ import annotations + +import time +from dataclasses import dataclass, field + + +@dataclass +class PeriodicRefresh: + """Small scheduler for optional CCU state-refresh frames.""" + + frames: list[bytes] = field(default_factory=list) + interval: float = 0.0 + _next_due: float | None = None + _index: int = 0 + + @property + def enabled(self) -> bool: + return bool(self.frames) and self.interval > 0 + + def start(self, now: float | None = None) -> None: + if not self.enabled: + self._next_due = None + return + self._next_due = (time.monotonic() if now is None else now) + self.interval + + def due_frames(self, now: float | None = None) -> list[bytes]: + if not self.enabled: + return [] + current = time.monotonic() if now is None else now + if self._next_due is None: + self._next_due = current + self.interval + return [] + if current < self._next_due: + return [] + + frame = self.frames[self._index % len(self.frames)] + self._index += 1 + + while self._next_due <= current: + self._next_due += self.interval + return [frame] diff --git a/ccu_emulator/serial_link.py b/ccu_emulator/serial_link.py new file mode 100644 index 0000000..935db73 --- /dev/null +++ b/ccu_emulator/serial_link.py @@ -0,0 +1,67 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import Any, Iterable + +from h8536.bench_connect_lcd import BenchLogger, FrameDetector, format_frame, label_frame + + +@dataclass(frozen=True) +class RxFrame: + frame: bytes + label: str + + +class SerialLink: + """Thin serial-port wrapper with checksum-resync frame detection.""" + + def __init__( + self, + device: Any, + logger: BenchLogger, + *, + sync_mode: str = "checksum", + ) -> None: + self.device = device + self.logger = logger + self.detector = FrameDetector(sync_mode=sync_mode) + + def reset_input(self) -> None: + self.device.reset_input_buffer() + self.detector = FrameDetector(sync_mode=self.detector.sync_mode) + + def read_available(self) -> list[RxFrame]: + waiting = getattr(self.device, "in_waiting", 0) + data = self.device.read(waiting or 1) + if not data: + return [] + + dropped_before = self.detector.dropped_bytes + self.logger.chunk("RX", data) + frames = [RxFrame(frame, label) for frame, label in self.detector.feed(data)] + for item in frames: + self.logger.event(f"DETECT {item.label} {format_frame(item.frame)}") + dropped_now = self.detector.dropped_bytes - dropped_before + if dropped_now: + self.logger.event( + f"RESYNC dropped_bytes={dropped_now} total_dropped={self.detector.dropped_bytes} " + f"buffered={len(self.detector.buffer)}" + ) + return frames + + def send(self, frame: bytes, label: str) -> None: + self.device.write(frame) + self.device.flush() + self.logger.chunk("TX", frame) + self.logger.event(f"SENT {label} {format_frame(frame)}") + + def labels(self) -> dict[str, int]: + return dict(self.detector.labels) + + +def label_for_frame(frame: bytes) -> str: + return label_frame(frame) + + +def format_frames(frames: Iterable[bytes]) -> str: + return " | ".join(format_frame(frame) for frame in frames) diff --git a/docs/pt2-button-report-bench-plan.md b/docs/pt2-button-report-bench-plan.md new file mode 100644 index 0000000..21e3cba --- /dev/null +++ b/docs/pt2-button-report-bench-plan.md @@ -0,0 +1,101 @@ +# PT2 Button Report Bench Plan + +Date: 2026-05-26 + +## Question + +After the SHUTTER ON/OFF test exposed queued frames: + +```text +02 01 0F 80 00 D6 +01 01 0F 80 00 D5 +``` + +the next bench question is whether other buttons share the same common queue-service gate, or whether each button/selector needs its own feature gate. + +## Current ROM Model + +The known button ROM trace says many physical buttons share this front-door path: + +```text +panel byte snapshot -> shadow byte -> dirty bit -> loc_1C0E jump table -> handler -> loc_3E54 report builder +``` + +CALL and CAM POWER use this path, and SHUTTER ON/OFF now appears to use it too once the CCU side services the queued report stream. + +The handlers diverge after the front door. Some directly build reports. Others depend on session/menu/feature state, especially secondary-table `E400` bits. + +## Test Method + +Run a no-button baseline first: + +```powershell +.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\button-report-common-gate-baseline.json --parity E --quiet-console --log captures\button-common-baseline.txt --result-json captures\button-common-baseline-result.json +``` + +Then run one physical button candidate through the same common gate: + +```powershell +.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\button-report-common-gate-press.json --parity E --quiet-console --log captures\button-common-SHORTNAME.txt --result-json captures\button-common-SHORTNAME-result.json +``` + +Compare the result JSONs: + +```powershell +.\.venv\Scripts\python.exe scripts\serial_scenario_compare.py captures\button-common-baseline-result.json captures\button-common-SHORTNAME-result.json --show-labels +``` + +If the candidate run has extra ACK-target frames, decode their selector/value. That suggests the button shares the common queue-service gate. + +## Broad-Gate Fallback + +If common-gate produces no extra selector for a button that should plausibly report, try the broader secondary-gate run: + +```powershell +.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\button-report-broad-gates-press.json --parity E --quiet-console --log captures\button-broad-SHORTNAME.txt --result-json captures\button-broad-SHORTNAME-result.json +``` + +Compare it against the same baseline: + +```powershell +.\.venv\Scripts\python.exe scripts\serial_scenario_compare.py captures\button-common-baseline-result.json captures\button-broad-SHORTNAME-result.json --show-labels +``` + +If a button only emits in the broad-gate run, it likely needs a selector-specific feature/report gate rather than only the common queue-service gate. + +## Practical Candidate Order + +Start with known or visually obvious controls: + +- SHUTTER ON/OFF: positive control, should reproduce selector `0x008F` value `0x8000`. +- CAM POWER: known direct selector `0x0007`, useful sanity check. +- CALL: known direct selector `0x0015`, but it can emit outside active state so treat it as a control. +- KNEE AUTO, DETAIL, BARS, WHITE BALANCE, BLACK/FLARE, and OTHER: useful unknowns because prior display/lamp tests suggest nearby ROM handlers and selector state. + +Run one physical button per capture. The queue emits background reports, so button identity is much easier to recover by comparing against the no-button baseline than by reading one log in isolation. + +## First Common-Gate Results + +The first common-gate bench set compared each one-button run against `button-common-baseline`. + +Positive results: + +| Button | Extra queued report(s) | Current meaning | +| --- | --- | --- | +| BARS | `01/02 00 17 80 00`, `01/02 00 18 80 00` | BARS shares the common queue-service gate. This matches the ROM handler that emits selectors `0x0017` and `0x0018`. | +| IRIS AUTO | `01/02 01 1A 08 00` | IRIS AUTO shares the common queue-service gate. This matches selector `0x009A` in the ROM button trace. | + +No extra ACK-target frames were found in these common-gate runs: + +- STANDARD +- MASTER +- SLAVE +- KNEE AUTO +- BLACK/FLARE FLARE +- OTHERS + +Interpretation: at least some local controls use the same queue-service gate as SHUTTER ON/OFF, but not every physical button emits through this simple state. The silent candidates may need a different secondary/menu/session gate, may be display-only in this mode, or may not have been captured as a single edge event. + +OTHERS is now treated separately in `pt2-menu-state-machine.md` because the ROM evidence points to a local menu/display key rather than a simple report button. + +Note: the result JSONs preserved the per-button summaries, but the test log path was reused as `button-common-SHORTNAME.txt` for the candidate runs. For future runs, replace `SHORTNAME` in both `--log` and `--result-json` so the full timeline is preserved per button. diff --git a/docs/pt2-continuation-command-trace.md b/docs/pt2-continuation-command-trace.md new file mode 100644 index 0000000..1374e86 --- /dev/null +++ b/docs/pt2-continuation-command-trace.md @@ -0,0 +1,209 @@ +# PT2 Continuation Command Trace + +This note enumerates the command paths that are active after the ROM sees `FAA2 != 0`. + +## Dispatcher Shape + +RX command dispatch starts after six-byte frame validation at `H'BBD6-H'BC67`. + +Important gates: + +- `F9C3 == 6`. +- SCI/RX physical error latch `FAA4.7 == 0`. +- Checksum matches `0x5A ^ F860 ^ F861 ^ F862 ^ F863 ^ F864 == F865`. +- Command number is `F860 & 0x07`. +- `F861.7` rejects normal command handling. +- `FAA2 == 0` enters the initial dispatcher. +- `FAA2 != 0` enters the continuation dispatcher. + +Continuation split: + +| Incoming command bits | Path | Meaning | +| --- | --- | --- | +| `command & 0x04 != 0` | `H'BC3A-H'BC56` | explicit continuation commands `4/5/6/7` | +| `command & 0x04 == 0`, `FAA2.3 == 0` | `H'BC5C -> H'BE6F` | ignored/returns | +| `command & 0x04 == 0`, `FAA2.3 == 1` | `H'BC5C-H'BC67 -> H'BC15` | clears queued-report continuation bit and re-enters initial command handling | + +That last row is easy to miss: command `0/1/2/3` can consume the report-continuation latch when `FAA2.3` was set by an autonomous report, then command `0/1/2` can run as an initial command. Command `3` still has no recognized initial handler and falls to the clear/return path. + +Selector bytes are packed from `F861:F862`, mapped by `loc_622B`, then doubled into `R4 = selector * 2` before the command handlers use the selector as a word-table offset. + +## Explicit Continuation Commands + +| Command | Handler | Table writes | Queue/report behavior | Cleanup | +| --- | --- | --- | --- | --- | +| `4` | `H'BD0E` | writes `E000`; selector zero also writes `E800`; sets `EC00.7` | calls `BE70` to append selector to `F970`; if `FAA2.3` set, advances `F9B5` | clears `FAA3`, clears `FAA2` | +| `5` | `H'BD80` | none | special selectors may append to `F970` or clear latches; if `FAA2.3` set, advances `F9B5` | clears `FAA3`, clears `FAA2` | +| `6` | `H'BDDB` | writes `E400`; sets `EC00.6` | does not append to `F970`; if `FAA2.3` set, advances `F9B5` | clears `FAA3`, clears `FAA2` | +| `7` | `H'BE05` | none | copies previous finalized TX frame from `F858-F85C` to `F850-F854` and retransmits | does not clear `FAA2/FAA3` in this handler | + +## `BE70`: Selector Processing Queue Append + +`BE70` is the shared helper used by command `0`, command `4`, and selected command-`5` cases. + +Path `H'BE70-H'BE9D`: + +- Scans the `F970` word ring from consumer cursor `F9B9` to producer cursor `F9B4`. +- If the selector is already present, returns without appending a duplicate. +- If absent, writes the selector to `F970 + 2*F9B4`. +- Increments `F9B4` and clears bit 5, making the queue a 32-entry ring. + +Practical meaning: + +- `F970` means "process this selector internally". +- It is separate from the serial-visible report queue at `F870`. +- Re-sending the same selector may refresh table values without creating another queued selector entry if the old entry has not been consumed yet. + +## Command 4: Continuation Primary Write + +Selector zero branch: + +- `H'BD12-H'BD18`: builds value from `F863` and forces low byte `0x80`. +- `H'BD1A`: writes `E000[0]`. +- `H'BD1E`: writes `E800[0]`. +- `H'BD22`: sets `EC00[0].7`. +- `H'BD26`: calls `BE70`, appending selector zero to `F970`. + +Nonzero selector branch: + +- `H'BD2B-H'BD35`: builds value from `F863/F864` and writes `E000[selector]`. +- `H'BD39`: sets `EC00[selector].7`. +- `H'BD3D-H'BD45`: if the selector has a mapped shadow slot, writes the value into the `F400` shadow area. +- `H'BD49-H'BD5F`: if `F76E.7` is set, uses the mapped shadow offset plus the `F76E` page nibble and calls `BFE0`, the EEPROM/persistent-write path. +- `H'BD64`: calls `BE70`, appending the selector to `F970`. + +Persistent-write detail: + +- If the selector-to-shadow map entry is zero, the mirror/persist path is skipped. +- `BFE0` seeds retry timer `F840=0x0A`, writes via the P9/X24164 helper path, reads back for verification, and sets `F841.7` on timeout/failure. + +Report consumption: + +- `H'BD67-H'BD71`: if `FAA2.3` was set by a queued report, increments `F9B5` and clears `F9B5.7`. +- `H'BD75-H'BD79`: clears `FAA3` and `FAA2`. + +Practical meaning: + +- Command `4` is a continuation write/update, not a generic always-live command. +- Command `4` selector zero can refresh both the primary/current table and queue the CONNECT selector. +- Nonzero command `4` does not directly refresh `E800`; autonomous report values still come from the older/current `E800` value unless another path updates it. + +## Command 5: ACK-Like / Special Selector Command + +Command `5` reaches `H'BD80` only from the continuation dispatcher: + +- `FAA2 != 0`. +- `command & 0x04 != 0`. +- `F861.7 == 0`. +- `F860 & 0x07 == 5`. + +Special enqueue selectors: + +| Selector | Branch | Later selector dispatch | Current meaning | +| --- | --- | --- | --- | +| `0x006C` | `H'BD80 -> H'BDBF` | `H'2FAF` | COPY completion/exit sibling when copy flags are live | +| `0x006D` | `H'BD85 -> H'BDBF` | `H'3015` | COPY in-progress/start refresh | +| `0x006E` | `H'BD8A/H'BD8F -> H'BDBF` | `H'2CA6` | special-accepted but selector dispatch is currently no-op | + +The duplicate `0x006E` compare at `H'BD8A` and `H'BD8F` appears redundant in the current decode. + +Selector-table math for the special group: + +- Table base is `H'28A6`. +- `0x006C` indexes `H'297E`, whose pointer is `H'2FAF`. +- `0x006D` indexes `H'2980`, whose pointer is `H'3015`. +- `0x006E` indexes `H'2982`, whose pointer is `H'2CA6`. +- `H'2CA6` clears `F769.7` and returns. + +Latch-clear selectors: + +| Selector | Gate | Effect | +| --- | --- | --- | +| `0x006B` | only if `F731.7` set | clears `F731.7` and `F790.7` | +| `0x0096` | only if `F731.7` set | clears `F731.7` and `F790.7` | +| `0x0097` | only if `F731.7` set | clears `F731.7` and `F790.7` | +| `0x00C6` | only if `F731.7` set | clears `F731.7` and `F790.7` | +| `0x00F8` | only if `F731.7` set | clears `F731.7` and `F790.7` | + +Report consumption and cleanup: + +- `H'BDC2-H'BDCC`: if `FAA2.3` was set by a queued report, increments `F9B5` and clears `F9B5.7`. +- `H'BDD0-H'BDD4`: clears `FAA3` and `FAA2`. + +Practical meaning: + +- Command `5` is the closest thing to an ACK, but only inside the continuation side. +- Most command-5 selectors do not have selector-specific meaning; they just consume/clear the continuation state if one is live. +- `0x006C/0x006D/0x006E` are command-5 special cases because they enter the `F970` selector-processing queue. +- `0x006E` is accepted as special by the command handler, but its current selector-table target is `2CA6`, the no-op return path. + +## Command 6: Continuation Secondary Write + +Path `H'BDDB-H'BE03`: + +- `H'BDDB-H'BDE5`: builds value from `F863/F864` and writes `E400[selector]`. +- `H'BDE9`: sets `EC00[selector].6`. +- `H'BDED-H'BDF7`: if `FAA2.3` was set by a queued report, increments `F9B5` and clears `F9B5.7`. +- `H'BDFB-H'BDFF`: clears `FAA3` and `FAA2`. + +Practical meaning: + +- Command `6` is the secondary feature/status table write used by menu visibility and gate code. +- It does not append the selector to `F970`, so it changes later decisions but does not itself force immediate selector dispatch. + +## Command 7: Retransmit + +Path `H'BE05-H'BE25`: + +- Copies previous finalized TX bytes `F858-F85C` into staging bytes `F850-F854`. +- Loads `F9C0=0x1F`. +- Calls `BA26` to finalize/send again. +- `BA26` then waits for `F9C0 == 0`, reloads `F9C0=0x64`, reloads `F9C4=0x07`, copies staging bytes back to `F858-F85C`, recomputes the checksum into `F85D`, and starts SCI1 TX. + +Practical meaning: + +- Command `7` repeats the previous finalized TX frame. +- It is valid from both initial and continuation dispatch. +- It does not acknowledge/consume `F870` report queue entries by itself and does not clear `FAA2/FAA3` in this handler. +- The copied old checksum byte is not trusted; `BA26` recomputes the checksum. + +## Distinct `07` Error Echo Path + +The ROM also emits `07...` frames from an error/retry path that is separate from explicit command `7`. + +Triggers: + +- SCI/RX physical error latched in `FAA4.7`. +- Checksum mismatch at `H'BBF0`. + +Path `H'BE29-H'BE6A`: + +- Clears `FAA4.7`. +- Requires `FAA5.7`; if the session gate is absent, no echo is sent. +- Increments retry counter `FAA6`. +- For the first two retry attempts, stages: + +```text +byte0 = 0x07 +byte1 = RX[1] +byte2 = RX[2] +byte3 = RX[3] +byte4 = RX[4] +``` + +- Calls `BA26` to send the error echo. +- After too many retries, loads `F9C0=0x1F` and clears `FAA3/FAA2` instead of sending another echo. + +Practical meaning: + +- A `07 ...` frame is not automatically a normal command-7 retransmit. +- Old captures made with the wrong serial parity can easily be retry/error echoes. +- Valid frames clear `FAA6` at `H'BBF3`. + +## Bench Implications + +- To update active selector state during a report window, use command `4` or `6` while `FAA2 != 0`. +- To consume a queued report without changing tables, command `5` is the cleanest continuation ACK shape. +- To trigger COPY side effects, command `5` with `0x006D` starts/refreshes `COPY IN PROGRESS`, and command `5` with `0x006C` completes/exits only while the copy flags are live. +- Do not treat command `7` as an ACK. It is a repeat probe. +- A low command `0/1/2` sent while `FAA2.3` is live may clear the report continuation and then run as an initial command, which can make timing-sensitive bench traces look like an ACK plus a new command in one frame. diff --git a/docs/pt2-copy-state-machine.md b/docs/pt2-copy-state-machine.md index 4058f0a..de17531 100644 --- a/docs/pt2-copy-state-machine.md +++ b/docs/pt2-copy-state-machine.md @@ -10,6 +10,7 @@ Frame: ```text 05 00 6D 00 00 32 +00 00 6D 00 00 37 ; family-00 set/queue form to test ``` ROM path: @@ -40,6 +41,7 @@ Frame: ```text 05 00 6C 00 00 33 +00 00 6C 00 00 36 ; family-00 set/queue form observed during active report drain ``` ROM path: @@ -110,10 +112,27 @@ Observed on the real panel: 006D repeated without 006C -> COPY IN PROGRESS -> CONNECT NOT ACT ``` +Family-00 comparison run on 2026-05-27: + +```text +00 00 6D 00 00 37 -> 00 00 6C 00 00 36 + -> immediate 04 00 6D / 04 00 6C table readbacks + -> no command-5-like 01 00 02 / 02 00 04 response rhythm + +05 00 6D 00 00 32 -> 05 00 6C 00 00 33 + -> 01 00 02 responses after 006D + -> 02 00 04 responses after 006C +``` + +This suggests the family-00 forms update/read back selector values but should not +be treated as equivalent to the command-5 COPY side-effect selectors unless an +LCD observation proves otherwise. + Current interpretation: - `0x006D` is a copy-start/progress-window refresh selector. - `0x006C` is a completion/exit selector that only behaves cleanly while the copy window is live. +- The observed `00 00 6C 00 00 36` frame is copy-related, but should not be read as "COPY COMPLETED" by itself. - The copy window is transient and timer-controlled. - The panel does not treat `0x006C` as a stateless "show completed" command. diff --git a/docs/pt2-known-button-rom-trace.md b/docs/pt2-known-button-rom-trace.md new file mode 100644 index 0000000..9732f2d --- /dev/null +++ b/docs/pt2-known-button-rom-trace.md @@ -0,0 +1,157 @@ +# 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` = selector `0x0007`, value `0x8000`, observed CAM POWER report. +- `00 00 15 80 00 CF` = selector `0x0015`, value `0x8000`, observed CALL active report. +- `00 00 15 00 00 4F` = selector `0x0015`, value `0x0000`, observed CALL inactive report. + +## Shared Button Path + +CALL and CAM POWER both use the same general panel edge machinery: + +```text +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: + +```text +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: + +```text +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: + +```text +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: + +```text +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 immediate `RTS`, so that matrix position is ignored. +- Some handlers only change local menu/page state such as `F731`, `F732`, `FB03`, or `F798`. +- Some handlers queue reports, but only if session/menu gates like `F731`, `F730`, `F791`, or selector bits in `E000/E400` allow 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'6EE4` consumes `F770.0/F770.1` for OTHERS/SHUTTER local actions. +- `H'6FF0` consumes `F770.2` for 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: + +```powershell +.\.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: + +```powershell +.\.venv\Scripts\python.exe h8536_panel_button_trace.py +``` + +Outputs: + +- `build/panel_button_trace.md` +- `build/panel_button_trace.json` diff --git a/docs/pt2-menu-state-machine.md b/docs/pt2-menu-state-machine.md index ceebbb4..e91befa 100644 --- a/docs/pt2-menu-state-machine.md +++ b/docs/pt2-menu-state-machine.md @@ -102,6 +102,52 @@ Relevant ROM behavior: - 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: @@ -191,3 +237,40 @@ Manual correlation: - 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. diff --git a/docs/pt2-protocol.md b/docs/pt2-protocol.md index bc2ad12..73cf9fb 100644 --- a/docs/pt2-protocol.md +++ b/docs/pt2-protocol.md @@ -8,7 +8,11 @@ Focused companion notes: - [PT2 Copy State Machine](pt2-copy-state-machine.md) - [PT2 Menu State Machine](pt2-menu-state-machine.md) +- [PT2 Session Rhythm ROM Trace](pt2-session-rhythm-trace.md) +- [PT2 Continuation Command Trace](pt2-continuation-command-trace.md) +- [PT2 Report Aftermath ROM Trace](pt2-report-aftermath-trace.md) - [PT2 Shutter Display Trace](pt2-shutter-display-trace.md) +- [PT2 Button Report Bench Plan](pt2-button-report-bench-plan.md) ## Current High-Confidence Facts @@ -434,6 +438,9 @@ ROM report-source update: - The active `02/01 ...` frames seen during CONNECT OK attempts are best modeled as `F870 -> BAF2 -> BA26` report-queue transmissions. - `BAF2` dequeues a report word, encodes the first three TX bytes, reads the payload from `E800 + 2*selector`, and `BA26` appends the `0x5A` XOR checksum. - After sending a queued report, the ROM sets `FAA2.3` and `FAA3.7`; command `4`, `5`, or `6` can then consume/advance the report only while that continuation latch is live. +- The emitted report does not appear to encode a required ACK selector. The ROM consume test is `FAA2.3`, so a generic command-5 continuation ACK such as `05 00 40 00 00 1F` is the cleanest report-cursor consume candidate. +- Low commands `0/1/2` during the report wait can clear the continuation latch and re-enter initial dispatch, but they do not advance `F9B5`. Command `7` retransmits and also does not advance `F9B5`. +- Emulator testing now supports the reactive ACK model: waiting for a finished RCP report frame, then sending `05 00 40 00 00 1F`, repeatedly advanced `F9B5`, cleared `FAA2/FAA3`, and kept the emulated LCD at `CONNECT: OK`. - This makes a reactive fake-CCU test more valuable than another blind fixed-delay matrix: recover to OK, wait for the first active report, then send one candidate continuation/ACK frame. ## Candidate CCU Seed Values @@ -578,6 +585,8 @@ RCP-side OTHERS/COPY menu trace: - The OTHERS menu is page `0x01`: `493E[0x01] -> H'631C`, local table `H'632E`. - Local table entry 1 points to `H'6FF0`, the page that renders `OTHERS` / `COPY TO SLAVES`. - The entry descriptor immediately before `H'6FF0` requires selector `0x0015` in the secondary table: `E400[0x0015] != 0`. Because command 6 writes `E400`, this is probably a CCU-provided feature/visibility bit, and command 6 must be sent in a live continuation/report window to have an effect. +- The root OTHERS/SHUTTER page `H'6EE4` consumes `F770.0/F770.1`; the COPY page `H'6FF0` consumes `F770.2`. Both handlers read `F770`, clear it, and then act on those low bits. +- The only decoded direct writers to `F770` found so far write high bits `0x80`, `0x40`, and `0x20` from value/dial redraw paths. No direct decoded write to `F770=0x01/0x02/0x04` has been found yet, so the physical OTHERS/COPY action probably arrives through an indirect panel-key latch or page-local mechanism. - When the page sees `F770.2` set, it only follows the local copy-start branch if `F791.7` is already set. That branch sets `F76E.6`, `F795.7`, `F731.7`, `F798=H'C8`, `F711.7`, `F726=H'64`, calls `loc_5500`, then displays `COPY TO SLAVES`. This is the RCP-side equivalent of the serial `0x006D` copy-start effect. - If `F770.2` is set while `F791.7` is clear, the ROM diverts through `H'704C` to a `SET RCP` / `MASTER` display path instead of starting copy. That makes `F791.7` a second, likely master/link/session gate for the physical COPY operation. - The OTHERS root handler at `H'6EE4` also tests primary selector `E000[0x008F]` (`H'E11E`) bits 11 and 12, and uses them to set `F711.6` and `F711.4`. Bench isolation shows this selector is broader than an OTHERS gate: bit 11 makes the SHUTTER seven-segment display show observed `EUS`, probably the manual's `EVS` display, and bit 12 makes it show the literal letters `OFF`; either bit also illuminates the iris AUTO lamp. diff --git a/docs/pt2-report-aftermath-trace.md b/docs/pt2-report-aftermath-trace.md new file mode 100644 index 0000000..4be0b23 --- /dev/null +++ b/docs/pt2-report-aftermath-trace.md @@ -0,0 +1,215 @@ +# PT2 Report Aftermath ROM Trace + +This note tracks what the ROM does after the RCP emits an autonomous serial report from the `F870` report queue. + +## Core Model + +The RCP report path is: + +```text +3E54 / 4046 enqueue selector into F870 +3FD3 checks send gates +BAF2 dequeues/stages a report from F870 and E800 +BA26 sends the six-byte SCI1 frame +BB46-BB51 arms the continuation/resend aftermath +``` + +The important consequence is that `BAF2` does not advance the report consumer cursor. The emitted report remains outstanding until the host sends a valid continuation command. + +## Report Queue + +| RAM | Role | +| --- | --- | +| `F870` | autonomous serial-report word ring | +| `F9B0` | producer cursor | +| `F9B5` | consumer/outstanding cursor | + +Producer paths: + +- `H'3E54`: when `R2.7` is set, deduplicates and appends `R3` to `F870`, then advances `F9B0`. +- `H'4046-H'4070`: when heartbeat/report cadence expires and the report queue is empty, appends selector `0x0000` to `F870`. + +Consumer path: + +- `H'BAF2` compares `F9B5` against `F9B0`. +- If equal, no report is pending. +- If different, it reads selector `F870[ F9B5 ]`, reads the report value from `E800[selector]`, stages the outgoing frame, and calls `BA26`. +- `BAF2` leaves `F9B5` unchanged. + +Only continuation command `4`, `5`, or `6` advances `F9B5`, and only when `FAA2.3` is still set. + +## Report Send Gates + +`H'3FD3` allows `BAF2` only when: + +- `FAA2 == 0`. +- `F9C0 == 0`. +- If `FAA5.7` is set, `F9C3 == 0`, meaning no partial RX frame is currently being assembled. + +This means host RX traffic can block report sending while a session is active. + +## Aftermath Window + +After `BA26` sends the report frame, `H'BB46-H'BB51` arms the report aftermath: + +| Address | Write | Meaning | +| --- | --- | --- | +| `H'BB00` | set `FAA2.3` | queued report needs continuation | +| `H'BB46` | `F9C6 = 0x01F4` | resend spacing countdown | +| `H'BB4C` | `F9C8 = 0x14` | resend/retry budget | +| `H'BB51` | `FAA3 = 0x80` | live resend/window marker | + +While this is live, valid RX frames enter the continuation dispatcher because `FAA2 != 0`. + +## Clean Continuation Consume + +Commands `4`, `5`, and `6` all share the same report-consume pattern: + +```text +if FAA2.3 set: + F9B5 += 1 + clear F9B5.7 +clear FAA3 +clear FAA2 +``` + +Handler addresses: + +| Command | Handler | Consume block | +| --- | --- | --- | +| `4` | `H'BD0E` | `H'BD67-H'BD79` | +| `5` | `H'BD80` | `H'BDC2-H'BDD4` | +| `6` | `H'BDDB` | `H'BDED-H'BDFF` | + +The ROM does not appear to require the continuation ACK selector to match the emitted report selector. The consume test is `FAA2.3`, not selector equality. + +## Non-Clean Paths + +Low commands `0/1/2/3` while `FAA2.3` is live: + +- `H'BC5C` clears `FAA2.3`. +- If the bit was set, `H'BC63` clears `FAA3`. +- `H'BC67` re-enters initial dispatch. +- This does not advance `F9B5`. + +Command `7`: + +- Retransmits the previous finalized TX frame through `H'BE05-H'BE25`. +- Does not clear `FAA2/FAA3`. +- Does not advance `F9B5`. + +TX/RX overlap interlock: + +- At `H'BA84-H'BAA7`, TXI checks `FAA2.3 && FAA5.7 && F9C3 != 0`. +- If true, it clears `FAA2.3`, clears `FAA3`, disables TXI, and loads `F9C0=0x1F`. +- This collapses the report window without consuming `F9B5`. +- Bench implication: starting a host frame before the RCP has finished TX can destroy the very continuation window being targeted. + +## Resend And Expiry + +`H'BE9E-H'BEE8` manages the unconsumed report aftermath: + +- Masks `FAA3` with `FAA5.7`. +- If the session gate is gone, `FAA3` becomes zero and `FAA2` is cleared. +- If `FAA3.7` is live and `F9C6 != 0`, it waits. +- If `F9C6 == 0` and `F9C8 != 0`, it decrements `F9C8`, reloads `F9C6=0x01F4`, clears `F9C3`, and calls `BA26` to resend the same finalized frame. +- If `F9C8 == 0`, it clears `F9C5`, forcing the broader session timeout path. + +So an unconsumed report can be resent repeatedly, then eventually force the session watchdog to expire. + +## Session Timeout + +`F9C5` is the broad active-session watchdog: + +- A complete six-byte RX frame reloads `F9C5=0x14` at `H'BB9E`. +- FRT2 decrements `F9C5` at `H'BF31-H'BF37`. +- `H'3FEF` observes expiry, clears `F9B5/F9B0`, clears `FAA5.7`, and if the gate was previously live calls `H'400C`. +- `H'400C -> H'4075 -> H'4217` clears broad session/display state and redraws `CONNECT:NOT ACT`. + +Related timers: + +| RAM | Role | +| --- | --- | +| `F9C0` | post-TX/report-send gate; decremented by FRT1 | +| `F9C1` | RX inter-byte timer; partial-frame timeout | +| `F9C4` | heartbeat/report enqueue cadence | +| `F9C5` | active serial-session watchdog | +| `F9C6/F9C8` | unconsumed report resend spacing/budget | + +## Fake-CCU Implications + +Best pure report ACK: + +```text +05 00 40 00 00 1F +``` + +Rationale: + +- Command `5` consumes the report cursor when `FAA2.3` is live. +- Selector `0x0040` is not one of the known command-5 special side-effect selectors. +- Value bytes are ignored by the generic command-5 consume path. + +Same-selector command-5 ACKs are plausible for human readability, but not ROM-required: + +```text +05 00 00 00 00 5F ; ACK selector 0x0000 +05 00 02 00 00 5D ; ACK selector 0x0002 +05 00 07 00 00 58 ; ACK selector 0x0007 +05 00 15 00 00 4A ; ACK selector 0x0015 +05 01 0F 00 00 51 ; ACK selector 0x008F +``` + +Use command `4` only when the host intentionally wants to refresh primary/current state while consuming: + +```text +04 00 00 80 00 DE ; selector-zero active refresh +``` + +Use command `6` only when the host intentionally wants to refresh secondary feature gates while consuming: + +```text +06 00 15 00 01 48 ; E400[0x0015] = 1 +06 01 0F 18 00 4A ; E400[0x008F] = 0x1800 +``` + +Avoid command-5 special selectors as generic ACKs unless the side effect is desired: + +```text +05 00 6C 00 00 33 ; COPY completion/exit sibling +05 00 6D 00 00 32 ; COPY IN PROGRESS/start +05 00 6E 00 00 31 ; special accepted, later handler is cleanup/no-op-like +``` + +## Proposed Normal Loop + +A plausible fake-CCU report loop is: + +1. Keep the serial format at `38400 8E1`. +2. Seed active state, especially selector zero. +3. Listen for a complete RCP TX frame. +4. Wait until the RCP frame is fully transmitted. +5. Quickly send a command-5 generic ACK before `F9C6/F9C8` resend handling starts. +6. Continue sending enough valid six-byte frames to reload `F9C5` before session expiry. +7. Add command-4/command-6 state refreshes only when we intentionally want to update lamps, displays, or menu gates. + +This is the current best ROM-supported path for maintaining `CONNECT: OK` without accidentally consuming the report incorrectly or triggering COPY/menu side effects. + +## Emulator Check + +Reactive emulator testing supports this model: + +- Seeded active state with command `0`, selector zero value `0x8080`. +- Waited for a report window where `FAA2.3` and `FAA3.7` were set and SCI1 TXI was idle. +- Sent `05 00 40 00 00 1F`. +- The ACK path reached the command-5 consume block and advanced `F9B5`, then cleared `FAA3` and `FAA2`. +- Repeating that reactive loop 12 times kept the emulated LCD at `CONNECT: OK`. + +Observed clean consume shape after each ACK: + +```text +before: FAA2=08 FAA3=80 F9B5=N +after: FAA2=00 FAA3=00 F9B5=N+1 +``` + +A fixed-delay or extra-guard strategy was less reliable. In one run, waiting an additional 1 ms after TX idle before sending the ACK only consumed two reports before falling back to `CONNECT:NOT ACT`. That result should not be overfit as an exact real-device limit, but it reinforces the ROM timing lesson: ACK as a reaction to a finished frame, not as a loose periodic delay. diff --git a/docs/pt2-session-rhythm-trace.md b/docs/pt2-session-rhythm-trace.md new file mode 100644 index 0000000..c1cc2fa --- /dev/null +++ b/docs/pt2-session-rhythm-trace.md @@ -0,0 +1,186 @@ +# PT2 Session Rhythm ROM Trace + +This note tracks ROM evidence for the CCU/RCP "session rhythm": which received commands update selector state, which internal queues process those selectors, and which timers expire visible states back toward `CONNECT: NOT ACT`. + +## RX Command Front Door + +The serial command dispatcher reads `F860 & 0x07` at `H'BC08-H'BC0C`. + +Dispatch is split by `FAA2`: + +| Command | Dispatcher state | Handler | Main effect | +| --- | --- | --- | --- | +| `0` | initial/idle, `FAA2 == 0` | `H'BC69` | writes primary `E000` and current/report `E800`, sets `EC00` dirty bit 7, appends selector to `F970`, replies with command-4 style echo | +| `1` | initial/idle, `FAA2 == 0`, `F861.7 == 0` | `H'BCD7` | reads primary `E000` and replies | +| `2` | initial/idle, `FAA2 == 0` | `H'BD04` | clears `FAA2.7`, likely abort/clear | +| `4` | continuation, `FAA2 != 0` | `H'BD0E` | writes primary `E000`, sets `EC00` dirty bit 7, appends selector to `F970`; selector zero also writes `E800`; no immediate reply | +| `5` | continuation, `FAA2 != 0` | `H'BD80` | ACK/selector side-effect path; special selectors can append to `F970` or clear latches | +| `6` | continuation, `FAA2 != 0` | `H'BDDB` | writes secondary `E400`, sets `EC00` dirty bit 6; no immediate reply | +| `7` | both states | `H'BE05` | retransmits previous frame or emits retry/error echo | + +Practical meaning: + +- The normal active link is stateful. Commands `4/5/6` only do their intended work in the continuation side where `FAA2 != 0`. +- Command `0` is both a value update and a continuation opener because it sets `FAA2.7`, writes tables, appends the selector to `F970`, and emits a reply. +- Command `4` is not identical to command `0`: for nonzero selectors it updates `E000` but does not directly update `E800` in this handler. That matters because autonomous reports read values from `E800`. +- Command `6` does not directly display anything. It changes the secondary feature/visibility table consumed later by local page code such as `5FD2`. + +## Serial Session Timeout + +The broad CCU-traffic watchdog is `F9C5`. + +RXI frame capture path: + +- `H'BB90-H'BB96` stores received bytes into `F868-F86D` and increments `F9C3`. +- When `F9C3 == 6`, `H'BB9E` loads `F9C5=0x14`. +- Main-loop handler `H'BBAB` only validates/dispatches a frame once `F9C3 == 6`. + +FRT2 OCIA timer path: + +- `H'BF31-H'BF37` decrements `F9C5` when nonzero. +- `H'3FEF` observes `F9C5`; once it is zero, the main loop can clear `F9B5/F9B0`, clear `FAA5.7`, then call `H'400C`. +- `H'400C` clears the broad session/display state and calls `H'4217`, which redraws `CONNECT:NOT ACT`. + +Practical meaning: + +- Any complete six-byte RX frame refreshes the short serial-session watchdog, independent of whether it ultimately produces the desired command-side effect. +- This is probably the main `CONNECT: OK -> CONNECT:NOT ACT` timer when CCU-like traffic stops. +- Separate display overlays still use `FB02`, so a page can expire even while serial traffic is otherwise alive. + +## Selector Queue + +`H'BE70` appends selectors to the processing queue at `F970`. `H'3E54` can also append to this queue when its mode byte has `R2.6` set. + +Important queue RAM: + +| RAM | Role | +| --- | --- | +| `F970` | selector-processing ring | +| `F9B4` | queue write cursor | +| `F9B9` | queue read cursor | + +Queue processing happens at `H'2806` during the main loop: + +1. If `F9B9 == F9B4`, no selector is pending. +2. Otherwise it reads the next selector from `F970`, increments `F9B9`, and masks the selector to `0x01FF`. +3. If the selector matches any active display slot (`F736/F738/F73A/F73C/F73E/F740/F742/F754`), it calls `H'48FA` before the selector-specific dispatch. +4. It then jumps through the selector handler table at `H'28A6`. + +This explains why the same incoming selector can either look inert or redraw the LCD: the selector must match the current active display/page slots before `48FA` is called from the queue bridge. + +## Autonomous Report Queue + +The report queue is separate from the selector-processing queue. + +| RAM | Role | +| --- | --- | +| `F870` | autonomous outbound report queue | +| `F9B0` | report producer cursor | +| `F9B5` | report consumer cursor | + +Important report path: + +- `H'3E54` appends report selectors to `F870` when its mode byte has `R2.7` set. +- `H'3FD3` sends reports only when `FAA2 == 0`, `F9C0 == 0`, and if `FAA5.7` is set then `F9C3 == 0`. +- `H'BAF2` drains `F870`, reads the report value from `E800 + 2*selector`, stages a six-byte TX frame, and sends it through `H'BA26`. +- `H'BB00` sets `FAA2.3` when a queued report is sent. +- After a report send, the ROM creates a continuation window with `F9C6=0x01F4`, `F9C8=0x14`, and `FAA3=0x80`. +- Continuation commands `4`, `5`, or `6` advance `F9B5` when `FAA2.3` was set, then clear `FAA3/FAA2`. + +Practical meaning: + +- A fake CCU probably needs to consume autonomous reports, not only stream status words. +- If a report is sent and the CCU does not answer during the continuation window, the RCP can repeat, retry, or let the broader session gates decay. +- Because report values come from `E800`, command `0` and local RCP report handlers are stronger report-value refreshes than nonzero command `4` writes. + +## TX / Heartbeat Timing Gates + +`H'BA26` is the common TX-finalize helper. + +Observed reloads: + +- `BA26` sets `F9C0=0x64` and `F9C4=0x07` after send finalization. +- TX completion later sets `F9C0=0x09`, or `F9C0=0xF0` when `F795.6` is set. +- The FRT2 path decrements `F9C4`; `H'4046` can enqueue heartbeat/report selector `0x0000` when the queue is empty and the gate is open. + +Practical meaning: + +- The roughly 700 ms heartbeat cadence is the `F9C4=0x07` post-send countdown with the current FRT2 tick model. +- COPY state can slow or alter TX pacing through `F795.6 -> F9C0=0xF0`. + +## Display Restore Timer + +`FB03.7` marks a temporary/timed display override. `FB02` is its countdown. + +Writers that start timed display overrides: + +| Address | State written | Visible candidate | +| --- | --- | --- | +| `H'1726` | `F732=0x1C07`, `FB02=0x14`, `FB03.7=1` | DETAIL/KNEE-style timed page | +| `H'176E` | `F732=0x1C06`, `FB02=0x14`, `FB03.7=1` | DETAIL/KNEE-style timed page | +| `H'2135` | `F732=0x1C03`, `FB02=0x14`, `FB03.7=1` | KNEE page seen in bench probes | +| `H'26F6` | `F732=0x1C01`, `FB02=0x14`, `FB03.7=1` | adjacent local menu overlay | +| `H'3004` | `F732=0x1904`, `FB02=0x14`, `FB03.7=1` | `COPY COMPLETED` | +| `H'3038` | `F732=0x1903`, `FB02=0x64`, `FB03.7=1` | `COPY IN PROGRESS` | +| `H'7092` | `FB03.7=1`, `FB02=0x14` | `SET RCP` / `MASTER` fallback from local COPY gate | + +FRT2 OCIA timer path `H'BF50-H'BF6B`: + +- If `FB03.7` is clear, nothing happens. +- If `FB02 != 0`, the timer decrements `FB02`. +- If `FB02 == 0`, it clears `FB03.7` and calls `H'48EF`. +- `H'48EF` restores `F732` from `F734`, then calls `H'48FA`. + +Practical meaning: + +- Many visible pages are deliberate timed overlays, not durable states. +- A scenario can appear to "drop to NOT ACT" simply because the overlay expires and restores the saved page. + +## COPY / Activity Latch Timers + +COPY-related selectors are handled through command 5 and the `F970` selector queue: + +| Selector | Handler | Timer/latch effect | +| --- | --- | --- | +| `0x006C` | `H'2FAF` | completion/exit sibling; can clear `F731.7`, load `F797=0x1E` or `0x14`, and display `COPY COMPLETED` | +| `0x006D` | `H'3015` | start/progress; sets `F731.7`, `F795.6`, `F795.7`, `F798=0xC8`, displays `COPY IN PROGRESS` | +| `0x006E` | via command-5 special path | appended to `F970`; exact selector handler still needs labeling | + +FRT2 OCIA timeout path: + +- `H'BFA3-H'BFAF`: if `F797` is nonzero, decrement it; when it reaches zero, clear `F731.7`. +- `H'BFB3-H'BFBF`: if `F798` is nonzero, decrement it; when it reaches zero, clear `F731.7`. + +Practical meaning: + +- `F731.7` is an activity/copy/session latch with explicit timeout clear paths. +- `0x006D` refreshes the long progress window (`F798=0xC8` and `FB02=0x64`). +- `0x006C` only makes sense as a completion/exit frame when the copy/progress flags are live. + +## Reset / NOT ACT Baseline + +`H'400C` clears broad session/display state: + +- clears `F732`, `FB03`, `F791`, `F795`, `F76E` +- calls `H'4217` + +`H'4217`: + +- clears `F798` +- sets `F731.7` +- clears output masks and writes the LCD text `CONNECT:NOT ACT` + +This looks like the firmware's explicit inactive-session baseline. + +## Current Rhythm Hypothesis + +The session rhythm is probably not one magic keepalive frame. The ROM suggests a loop with three layers: + +1. **Any complete six-byte RX frame** refreshes the broad `F9C5` session watchdog. +2. **Command-0 primary selector updates** keep both `E000` and `E800` current, append active selectors to `F970`, and reply. +3. **Command-4 continuation primary updates** keep `E000` current and append selectors to `F970`, but only selector zero directly refreshes `E800`. +4. **Autonomous reports from `F870`** must be consumed by continuation commands so the report cursor advances. +5. **Command-6 secondary selector updates** advertise which features/menu entries are valid through `E400`. +6. **Command-5 ACK/special selectors** advance report windows and drive side-effect selectors such as `0x006C/0x006D`. + +The panel stays active when enough selector updates hit the right active slots and refresh the timed/latch counters before FRT2 expires them. diff --git a/docs/pt2-shutter-display-trace.md b/docs/pt2-shutter-display-trace.md index 3383d41..0533e9c 100644 --- a/docs/pt2-shutter-display-trace.md +++ b/docs/pt2-shutter-display-trace.md @@ -72,6 +72,19 @@ Practical meaning: - The CCU can force the display state by writing `E000[0x008F]`. - The RCP can also try to report local EVS/OFF changes through selector `0x008F`, but only when the secondary-table feature bits `E400[0x008F].11/.12` allow it. +Additional local-key trace: + +- `F109 -> F6D0.7` handler `H'24E8` writes `E800[0x008F]=0x8000` or `0x0000`, then queues selector `0x008F`. +- `F109 -> F6D0.6` handler `H'252E` writes `E800[0x008F]=0x2000` or `0x0000`, then queues selector `0x008F`. +- Both handlers first check the current session/page gate (`F731 <= 2`) and both can divert to timed page `F732=0x1C01` when `E000[0x0088].14` is set. + +This splits selector `0x008F` into at least two roles: + +- CCU-visible display/status bits `0x0800` and `0x1000`, bench-mapped to `EVS` and `OFF`. +- Local key/report bits `0x8000` and `0x2000`, emitted by the physical panel path when gates allow. + +So the display bits that light `EVS/OFF` are not necessarily the same bits the local SHUTTER/OTHERS-adjacent buttons emit. + ## Adjacent Shutter Value Family The periodic/control-change scanner at `H'15E0` processes changed input words collected by IRQ3 from the external panel chips. Around the shutter path it calls `H'19A2`, which compares a local delta against the current primary table value and, if changed, writes the `E800` current table and calls `H'3E54`. diff --git a/h8536/bench_connect_lcd.py b/h8536/bench_connect_lcd.py index 36d1165..71dfde6 100644 --- a/h8536/bench_connect_lcd.py +++ b/h8536/bench_connect_lcd.py @@ -141,6 +141,9 @@ def format_frame(data: bytes) -> str: def label_frame(frame: bytes) -> str: labels = { bytes.fromhex("0000000080DA"): "heartbeat", + bytes.fromhex("00000080805A"): "active_selector0_keepalive_report", + bytes.fromhex("00006C000036"): "copy_completion_exit_selector_006c_candidate", + bytes.fromhex("00006D000037"): "copy_in_progress_selector_006d_candidate", bytes.fromhex("02000200005A"): "connect_ok_path_response_candidate", bytes.fromhex("010002000059"): "connect_c0_path_response_candidate", bytes.fromhex("07804040A07D"): "visible_40A0_family_40", @@ -151,6 +154,21 @@ def label_frame(frame: bytes) -> str: bytes.fromhex("0000158000CF"): "known_call_button_active_report", bytes.fromhex("00001500004F"): "known_call_button_inactive_report", bytes.fromhex("0000078000DD"): "known_cam_power_button_report", + bytes.fromhex("00010F8000D4"): "known_shutter_onoff_bit7_report_candidate", + bytes.fromhex("00010F200074"): "known_shutter_onoff_bit6_report_candidate", + bytes.fromhex("00010F000054"): "known_shutter_onoff_clear_report_candidate", + bytes.fromhex("01010F8000D5"): "queued_shutter_onoff_bit7_report_candidate", + bytes.fromhex("02010F8000D6"): "queued_shutter_onoff_bit7_report_candidate", + bytes.fromhex("01010F200075"): "queued_shutter_onoff_bit6_report_candidate", + bytes.fromhex("02010F200076"): "queued_shutter_onoff_bit6_report_candidate", + bytes.fromhex("01010F000055"): "queued_shutter_onoff_clear_report_candidate", + bytes.fromhex("02010F000056"): "queued_shutter_onoff_clear_report_candidate", + bytes.fromhex("0100178000CC"): "queued_bars_button_selector_0017_active_candidate", + bytes.fromhex("0200178000CF"): "queued_bars_button_selector_0017_active_candidate", + bytes.fromhex("0100188000C3"): "queued_bars_button_selector_0018_active_candidate", + bytes.fromhex("0200188000C0"): "queued_bars_button_selector_0018_active_candidate", + bytes.fromhex("01011A080048"): "queued_iris_auto_button_selector_009a_active_candidate", + bytes.fromhex("02011A08004B"): "queued_iris_auto_button_selector_009a_active_candidate", bytes.fromhex("01000400005F"): "gated_active_0004_response_candidate", bytes.fromhex("02000400005C"): "gated_active_0004_transition_candidate", } diff --git a/h8536/emulator/__init__.py b/h8536/emulator/__init__.py index 3a5db5d..6f3dd02 100644 --- a/h8536/emulator/__init__.py +++ b/h8536/emulator/__init__.py @@ -57,6 +57,7 @@ from .cpu import CPUState from .errors import EmulatorError, UnsupportedInstruction from .fast_paths import P9FastPath, P9FastPathConfig, P9FastPathEvent from .memory import MemoryAccess, MemoryMap, describe_regions +from .panel import PanelAction, PanelInjection, PanelInput, parse_panel_action, resolve_panel_input from .peripherals import LCD, P9TraceEvent, X24164Bus, X24164Device, X24164TraceEvent, factory_default_words_from_rom from .runner import H8536Emulator, RunReport from .sci import SCI1, SciTxEvent @@ -97,6 +98,9 @@ __all__ = [ "P9FastPath", "P9FastPathConfig", "P9FastPathEvent", + "PanelAction", + "PanelInjection", + "PanelInput", "P9TraceEvent", "RAMCR", "REGISTER_FIELD_END", @@ -137,4 +141,6 @@ __all__ = [ "factory_default_words_from_rom", "load_rom", "main", + "parse_panel_action", + "resolve_panel_input", ] diff --git a/h8536/emulator/panel.py b/h8536/emulator/panel.py new file mode 100644 index 0000000..c1cdc03 --- /dev/null +++ b/h8536/emulator/panel.py @@ -0,0 +1,203 @@ +from __future__ import annotations + +from dataclasses import dataclass + +from ..formatting import h16 + + +@dataclass(frozen=True) +class PanelInput: + name: str + source: int + shadow: int + previous: int + bit: int + dirty: int + dirty_bit: int + selector: int | None = None + note: str = "" + + @property + def spec(self) -> str: + return f"{h16(self.shadow)}.{self.bit}" + + @property + def dirty_spec(self) -> str: + return f"{h16(self.dirty)}.{self.dirty_bit}" + + +@dataclass(frozen=True) +class PanelAction: + panel_input: PanelInput + pressed: bool + raw: str = "" + + @property + def label(self) -> str: + state = "press" if self.pressed else "release" + return f"{self.panel_input.name}:{state}" + + +@dataclass(frozen=True) +class PanelInjection: + action: PanelAction + source_before: int + source_after: int + shadow_before: int + shadow_after: int + previous_before: int + previous_after: int + dirty_before: int + dirty_after: int + + def summary(self) -> str: + panel_input = self.action.panel_input + selector = "" if panel_input.selector is None else f" selector=0x{panel_input.selector:04X}" + return ( + f"{self.action.label} source={h16(panel_input.source)} " + f"shadow={panel_input.spec} previous={h16(panel_input.previous)} " + f"dirty={panel_input.dirty_spec}{selector}" + ) + + +PANEL_LANES: tuple[tuple[int, int, int, int, int], ...] = ( + (0xF102, 0xF6D7, 0xF6E7, 0xF6F2, 7), + (0xF103, 0xF6D6, 0xF6E6, 0xF6F2, 6), + (0xF104, 0xF6D5, 0xF6E5, 0xF6F2, 5), + (0xF105, 0xF6D4, 0xF6E4, 0xF6F2, 4), + (0xF106, 0xF6D3, 0xF6E3, 0xF6F2, 3), + (0xF107, 0xF6D2, 0xF6E2, 0xF6F2, 2), + (0xF108, 0xF6D1, 0xF6E1, 0xF6F2, 1), + (0xF109, 0xF6D0, 0xF6E0, 0xF6F2, 0), + (0xF005, 0xF6DC, 0xF6EC, 0xF6F3, 4), + (0xF006, 0xF6DB, 0xF6EB, 0xF6F3, 3), +) + +KNOWN_PANEL_INPUTS: dict[str, PanelInput] = { + "cam-power": PanelInput( + name="cam-power", + source=0xF105, + shadow=0xF6D4, + previous=0xF6E4, + bit=3, + dirty=0xF6F2, + dirty_bit=4, + selector=0x0007, + note="CAM POWER button; queues selector 0x0007 when gates allow", + ), + "call": PanelInput( + name="call", + source=0xF006, + shadow=0xF6DB, + previous=0xF6EB, + bit=5, + dirty=0xF6F3, + dirty_bit=3, + selector=0x0015, + note="CALL button; queues selector 0x0015 active/inactive reports", + ), +} + +PANEL_ALIASES: dict[str, str] = { + "cam": "cam-power", + "camera-power": "cam-power", + "camera_power": "cam-power", + "cam_power": "cam-power", + "campower": "cam-power", + "power": "cam-power", +} + + +def resolve_panel_input(text: str) -> PanelInput: + token = _normalize_token(text) + token = PANEL_ALIASES.get(token, token) + if token in KNOWN_PANEL_INPUTS: + return KNOWN_PANEL_INPUTS[token] + if "." not in token: + raise ValueError(f"unknown panel input {text!r}; use cam-power, call, or an address bit like F6D4.3") + address_text, bit_text = token.split(".", 1) + address = _parse_address(address_text) + try: + bit = int(bit_text, 0) + except ValueError as exc: + raise ValueError(f"invalid panel bit in {text!r}") from exc + if not 0 <= bit <= 7: + raise ValueError(f"panel bit out of range in {text!r}") + for source, shadow, previous, dirty, dirty_bit in PANEL_LANES: + if address in {source, shadow}: + return PanelInput( + name=f"{h16(shadow)}.{bit}", + source=source, + shadow=shadow, + previous=previous, + bit=bit, + dirty=dirty, + dirty_bit=dirty_bit, + note="raw panel matrix input inferred from ROM shadow/dirty lane", + ) + raise ValueError(f"{h16(address)} is not a known A8 panel byte shadow/source") + + +def parse_panel_action(text: str, *, default_pressed: bool = True) -> PanelAction: + raw = text.strip() + spec = raw + pressed = default_pressed + for separator in ("=", ":"): + if separator not in raw: + continue + left, right = raw.rsplit(separator, 1) + state = _parse_state(right) + if state is None: + continue + spec = left + pressed = state + break + return PanelAction(resolve_panel_input(spec), pressed=pressed, raw=raw) + + +def _parse_state(text: str) -> bool | None: + token = _normalize_token(text) + if token in {"press", "pressed", "on", "down", "1", "true", "active"}: + return True + if token in {"release", "released", "off", "up", "0", "false", "inactive"}: + return False + return None + + +def _normalize_token(text: str) -> str: + return text.strip().lower().replace("_", "-") + + +def _parse_address(text: str) -> int: + token = text.strip().upper() + if token.startswith("H'"): + token = token[2:] + elif token.startswith("$"): + token = token[1:] + elif token.startswith("0X"): + token = token[2:] + try: + value = int(token, 16) + except ValueError as exc: + raise ValueError(f"invalid panel address {text!r}") from exc + if not 0 <= value <= 0xFFFF: + raise ValueError(f"panel address out of range {text!r}") + return value + + +def set_bit(value: int, bit: int, enabled: bool) -> int: + mask = 1 << bit + return (value | mask) & 0xFF if enabled else (value & ~mask) & 0xFF + + +__all__ = [ + "KNOWN_PANEL_INPUTS", + "PANEL_ALIASES", + "PANEL_LANES", + "PanelAction", + "PanelInjection", + "PanelInput", + "parse_panel_action", + "resolve_panel_input", + "set_bit", +] diff --git a/h8536/emulator/runner.py b/h8536/emulator/runner.py index dc18df2..af81927 100644 --- a/h8536/emulator/runner.py +++ b/h8536/emulator/runner.py @@ -39,6 +39,7 @@ from .cpu import CPUState, mask, s8, s16, sign_bit from .errors import EmulatorError, UnsupportedInstruction from .fast_paths import P9FastPath, P9FastPathConfig from .memory import MemoryMap +from .panel import PanelAction, PanelInjection, PanelInput, resolve_panel_input, set_bit from .sci import SCI1 from .timers import FrtOciaScheduler, FrtRegisters from .uart import UartTiming @@ -134,6 +135,38 @@ class H8536Emulator: def inject_sci1_rx_byte(self, value: int) -> None: self.memory.inject_sci1_rx_byte(value) + def inject_panel_input(self, panel_input: PanelInput | str, *, pressed: bool = True) -> PanelInjection: + resolved = resolve_panel_input(panel_input) if isinstance(panel_input, str) else panel_input + action = PanelAction(resolved, pressed=pressed) + shadow_before = self.memory.read8(resolved.shadow) + source_before = self.memory.external.get(resolved.source, shadow_before) + previous_before = self.memory.read8(resolved.previous) + dirty_before = self.memory.read8(resolved.dirty) + + source_after = set_bit(source_before, resolved.bit, pressed) + shadow_after = set_bit(shadow_before, resolved.bit, pressed) + previous_after = set_bit(previous_before, resolved.bit, not pressed) + dirty_after = dirty_before | (1 << resolved.dirty_bit) + + self.memory.write8(resolved.source, source_after) + self.memory.write8(resolved.shadow, shadow_after) + # The ROM's loc_1Bxx dispatchers act on shadow XOR previous-shadow. + # Force the previous sample opposite at this bit so the main loop sees one clean edge. + self.memory.write8(resolved.previous, previous_after) + self.memory.write8(resolved.dirty, dirty_after) + + return PanelInjection( + action=action, + source_before=source_before, + source_after=source_after, + shadow_before=shadow_before, + shadow_after=shadow_after, + previous_before=previous_before, + previous_after=previous_after, + dirty_before=dirty_before, + dirty_after=dirty_after, + ) + def step(self) -> str: pc = self.cpu.pc cycles_before = self.cpu.cycles diff --git a/h8536/emulator/rx_probe.py b/h8536/emulator/rx_probe.py index 6c31158..625ad4c 100644 --- a/h8536/emulator/rx_probe.py +++ b/h8536/emulator/rx_probe.py @@ -18,6 +18,7 @@ from .constants import ( from .eeprom_image import write_eeprom_snapshot from .errors import UnsupportedInstruction from .memory import MemoryAccess +from .panel import PanelAction, parse_panel_action, resolve_panel_input from .runner import H8536Emulator from .uart import UartTiming @@ -33,6 +34,13 @@ CONNECT_LCD_FRAMES = ( ) WATCH_PCS = { + 0x15E0: "main_panel_scanner", + 0x1BA0: "panel_f6d4_edge_dispatch", + 0x1BF8: "panel_f6db_edge_dispatch", + 0x1C0E: "panel_bit_dispatch", + 0x1F40: "cam_power_handler", + 0x20A1: "call_handler", + 0x3E54: "report_queue_enqueue", 0xBB57: "sci1_eri_entry", 0xBB67: "sci1_rxi_entry", 0xBBD6: "rx_checksum_seed", @@ -56,6 +64,10 @@ WATCH_RANGES = ( ) ACCESS_RANGES = ( + (0xF000, 0xF10F, "panel_external_bytes"), + (0xF6D0, 0xF6DF, "panel_shadow_bytes"), + (0xF6E0, 0xF6EF, "panel_previous_shadow_bytes"), + (0xF6F0, 0xF6F3, "panel_dirty_bytes"), (0xF850, 0xF85D, "tx_staging_or_frame"), (0xF860, 0xF86D, "rx_validation_or_capture"), (0xF870, 0xF96F, "report_queue"), @@ -64,8 +76,12 @@ ACCESS_RANGES = ( (0xFAA2, 0xFAA6, "serial_latches"), (0xFAF0, 0xFAFF, "lcd_line_buffer"), (0xE000, 0xE001, "primary_table_index_0000"), + (0xE00E, 0xE00F, "primary_cam_power_index_0007"), + (0xE02A, 0xE02B, "primary_call_index_0015"), (0xE400, 0xE401, "secondary_table_index_0000"), (0xE800, 0xE801, "current_table_index_0000"), + (0xE80E, 0xE80F, "current_cam_power_index_0007"), + (0xE82A, 0xE82B, "current_call_index_0015"), (0xEC00, 0xEC01, "flag_table_index_0000"), (0xE000, 0xE3FF, "primary_table_E000"), (0xE400, 0xE7FF, "secondary_table_E400"), @@ -77,6 +93,12 @@ ACCESS_RANGES = ( ) STATE_BYTES = { + 0xF6D4: "panel_shadow_F6D4_cam_lane", + 0xF6DB: "panel_shadow_F6DB_call_lane", + 0xF6E4: "panel_previous_F6E4_cam_lane", + 0xF6EB: "panel_previous_F6EB_call_lane", + 0xF6F2: "panel_dirty_F6F2", + 0xF6F3: "panel_dirty_F6F3", 0xF9B0: "queue_head", 0xF9B5: "queue_tail", 0xF9C0: "tx_gate", @@ -104,12 +126,14 @@ STATE_WORDS = { 0xE000: "E000_index_0000_primary", 0xE004: "E000_index_0002_primary", 0xE008: "E000_index_0004_primary", + 0xE00E: "E000_index_0007_cam_power_primary", 0xE024: "E000_index_0012_primary", 0xE026: "E000_index_0013_primary", 0xE02A: "E000_index_0015_primary", 0xE104: "E000_index_0082_primary", 0xE400: "E400_index_0000_secondary", 0xE800: "E800_index_0000_current", + 0xE80E: "E800_index_0007_cam_power_current", 0xE804: "E800_index_0002_current", 0xE808: "E800_index_0004_current", 0xE824: "E800_index_0012_current", @@ -189,6 +213,50 @@ class FrameResult: return lines +@dataclass(frozen=True) +class PanelActionResult: + action: PanelAction + injection_summary: str + steps: int + stopped_reason: str + new_tx_bytes: bytes + new_tx_frames: list[bytes] + state_before: dict[str, int | str] + state_after: dict[str, int | str] + accesses: list[MemoryAccess] + context: RunContext + + def lines(self, index: int) -> list[str]: + lines = [ + f"panel_action[{index}]={self.action.label} input={self.action.panel_input.spec}", + f" injection={self.injection_summary}", + f" stopped={self.stopped_reason} steps={self.steps}", + f" new_tx_bytes={format_frame(self.new_tx_bytes) if self.new_tx_bytes else 'none'}", + ] + if self.new_tx_frames: + lines.append(" new_tx_frames=" + " | ".join(format_frame(frame) for frame in self.new_tx_frames)) + else: + lines.append(" new_tx_frames=none") + lcd_display = self.state_after.get("lcd_display_ascii") + if isinstance(lcd_display, str): + lines.append(f" lcd_display={lcd_display!r}") + state_changes = _state_change_lines(self.state_before, self.state_after) + if state_changes: + lines.append(" state_changes:") + lines.extend(f" {line}" for line in state_changes) + pc_lines = _pc_hit_lines(self.context) + if pc_lines: + lines.append(" pc_hits:") + lines.extend(f" {line}" for line in pc_lines) + access_lines = _access_lines(self.accesses) + if access_lines: + lines.append(" interesting_accesses:") + lines.extend(f" {line}" for line in access_lines) + if self.context.unsupported: + lines.append(f" unsupported={self.context.unsupported}") + return lines + + def parse_frame(text: str) -> bytes: normalized = text.strip().replace(",", " ").replace(":", " ").replace("-", " ").replace("_", " ") parts = normalized.split() @@ -209,6 +277,27 @@ def parse_frame(text: str) -> bytes: return bytes(values) +def parse_panel_action_arg(text: str) -> PanelAction: + try: + return parse_panel_action(text) + except ValueError as exc: + raise argparse.ArgumentTypeError(str(exc)) from exc + + +def parse_panel_press_arg(text: str) -> PanelAction: + try: + return PanelAction(resolve_panel_input(text), pressed=True, raw=text) + except ValueError as exc: + raise argparse.ArgumentTypeError(str(exc)) from exc + + +def parse_panel_release_arg(text: str) -> PanelAction: + try: + return PanelAction(resolve_panel_input(text), pressed=False, raw=text) + except ValueError as exc: + raise argparse.ArgumentTypeError(str(exc)) from exc + + def frame_checksum(data: bytes) -> int: checksum = CHECKSUM_SEED for value in data[: FRAME_LENGTH - 1]: @@ -318,6 +407,11 @@ def build_arg_parser() -> argparse.ArgumentParser: parser.add_argument("--per-byte-steps", type=int, default=5_000, help="polite mode byte-consume limit, or UART mode step limit between byte arrivals") parser.add_argument("--post-frame-steps", type=int, default=80_000, help="maximum steps after a full injected frame") parser.add_argument("--post-frame-ms", type=int, help="run this many emulated milliseconds after each injected frame") + parser.add_argument("--panel", action="append", type=parse_panel_action_arg, default=[], help="synthetic panel action, e.g. cam-power, call=release, or F6D4.3=press; preserves order across repeated --panel uses") + parser.add_argument("--panel-press", action="append", type=parse_panel_press_arg, default=[], help="synthetic panel press alias/spec, e.g. cam-power, call, or F6D4.3") + parser.add_argument("--panel-release", action="append", type=parse_panel_release_arg, default=[], help="synthetic panel release alias/spec, e.g. call or F6DB.5") + parser.add_argument("--post-panel-steps", type=int, default=120_000, help="maximum steps after each synthetic panel action") + parser.add_argument("--post-panel-ms", type=int, help="run this many emulated milliseconds after each synthetic panel action") parser.add_argument("--wait-heartbeats", type=int, default=0, help="wait for this many heartbeat frames before injecting the first host frame") parser.add_argument("--wait-heartbeat-steps", type=int, default=1_500_000, help="maximum steps while waiting for pre-injection heartbeat frames") parser.add_argument("--uart-timing", action="store_true", help="inject frame bytes at real UART inter-byte timing instead of waiting for RDRF consumption") @@ -347,8 +441,9 @@ def main(argv: list[str] | None = None) -> int: frames = list(args.frames) if args.preset == "connect-lcd": frames.extend(CONNECT_LCD_FRAMES) - if not frames: - raise SystemExit("pass at least one frame or use --preset connect-lcd") + panel_actions = [*args.panel, *args.panel_press, *args.panel_release] + if not frames and not panel_actions: + raise SystemExit("pass at least one frame, use --preset connect-lcd, or add --panel/--panel-press") rom_path, emulator, boot_summary, results = run_rx_probe( frames, @@ -384,6 +479,19 @@ def main(argv: list[str] | None = None) -> int: for index, result in enumerate(results): for line in result.lines(index): print(line) + panel_results = [ + _run_panel_action( + emulator, + action, + post_panel_steps=args.post_panel_steps, + post_panel_ms=args.post_panel_ms, + stop_after_tx_frame=not args.keep_listening, + ) + for action in panel_actions + ] + for index, result in enumerate(panel_results): + for line in result.lines(index): + print(line) print("total_tx_frames=" + " | ".join(format_frame(frame) for frame in emulator.sci1.tx_frames)) eeprom_writes = emulator.memory.p9_bus.x24164_bus.write_log_lines(limit=80) if eeprom_writes: @@ -484,6 +592,49 @@ def _run_frame( ) +def _run_panel_action( + emulator: H8536Emulator, + action: PanelAction, + *, + post_panel_steps: int, + post_panel_ms: int | None, + stop_after_tx_frame: bool, +) -> PanelActionResult: + state_before = _state_snapshot(emulator) + log_start = len(emulator.memory.access_log) + tx_byte_start = len(emulator.sci1.tx_bytes) + tx_frame_start = len(emulator.sci1.tx_frames) + injection = emulator.inject_panel_input(action.panel_input, pressed=action.pressed) + context = RunContext() + + def post_predicate(inner: H8536Emulator) -> bool: + if not stop_after_tx_frame: + return False + return any(frame != HEARTBEAT_FRAME for frame in inner.sci1.tx_frames[tx_frame_start:]) + + if post_panel_ms is not None: + steps, reason = _run_cycles_for_ms(emulator, post_panel_ms, context) + stopped_reason = reason + else: + steps, reason = _run_until(emulator, post_panel_steps, post_predicate, context) + stopped_reason = "non_heartbeat_tx_frame" if reason == "predicate" and stop_after_tx_frame else reason + + log_end = len(emulator.memory.access_log) + state_after = _state_snapshot(emulator) + return PanelActionResult( + action=action, + injection_summary=injection.summary(), + steps=steps, + stopped_reason=stopped_reason, + new_tx_bytes=bytes(emulator.sci1.tx_bytes[tx_byte_start:]), + new_tx_frames=list(emulator.sci1.tx_frames[tx_frame_start:]), + state_before=state_before, + state_after=state_after, + accesses=emulator.memory.access_log[log_start:log_end], + context=context, + ) + + def _inject_frame_uart_timed( emulator: H8536Emulator, frame: bytes, @@ -672,11 +823,15 @@ def _parse_byte(text: str) -> int: __all__ = [ "CONNECT_LCD_FRAMES", + "PanelActionResult", "format_frame", "frame_checksum", "frame_checksum_ok", "main", "parse_frame", + "parse_panel_action_arg", + "parse_panel_press_arg", + "parse_panel_release_arg", "run_rx_probe", "UartTiming", ] diff --git a/h8536/panel_button_trace.py b/h8536/panel_button_trace.py new file mode 100644 index 0000000..a258b3e --- /dev/null +++ b/h8536/panel_button_trace.py @@ -0,0 +1,306 @@ +from __future__ import annotations + +import argparse +import json +import re +from collections import defaultdict +from pathlib import Path +from typing import Any + +from .decoder import H8536Decoder +from .formatting import h16 +from .rom import Rom + + +DEFAULT_ROM = Path("ROM/M27C512@DIP28_1.BIN") +DEFAULT_TEXT_OUTPUT = Path("build/panel_button_trace.md") +DEFAULT_JSON_OUTPUT = Path("build/panel_button_trace.json") + +BUTTON_TABLE_BASE = 0x2706 +NOOP_HANDLER = 0x1C25 +QUEUE_FUNCTION = 0x3E54 + +INPUT_BYTES = [ + { + "shadow": "F6D7", + "source": "F102", + "dirty": "F6F2.7", + "dispatcher": "1B2D", + "initial_r5": 0x7E, + "bank": "IRQ4 A8 panel byte path", + }, + { + "shadow": "F6D6", + "source": "F103", + "dirty": "F6F2.6", + "dispatcher": "1B44", + "initial_r5": 0x6E, + "bank": "IRQ4 A8 panel byte path", + }, + { + "shadow": "F6D5", + "source": "F104", + "dirty": "F6F2.5", + "dispatcher": "1B5B", + "initial_r5": 0x5E, + "bank": "IRQ4 A8 panel byte path", + }, + { + "shadow": "F6D4", + "source": "F105", + "dirty": "F6F2.4", + "dispatcher": "1BA0", + "initial_r5": 0x4E, + "bank": "IRQ4 A8 panel byte path", + }, + { + "shadow": "F6D3", + "source": "F106", + "dirty": "F6F2.3", + "dispatcher": "1BB6", + "initial_r5": 0x3E, + "bank": "IRQ4 A8 panel byte path", + }, + { + "shadow": "F6D2", + "source": "F107", + "dirty": "F6F2.2", + "dispatcher": "1BCC", + "initial_r5": 0x2E, + "bank": "IRQ4 A8 panel byte path", + }, + { + "shadow": "F6D1", + "source": "F108", + "dirty": "F6F2.1", + "dispatcher": "1B72", + "initial_r5": 0x1E, + "bank": "IRQ4 A8 panel byte path", + }, + { + "shadow": "F6D0", + "source": "F109", + "dirty": "F6F2.0", + "dispatcher": "1B89", + "initial_r5": 0x0E, + "bank": "IRQ4 A8 panel byte path", + }, + { + "shadow": "F6DC", + "source": "F005", + "dirty": "F6F3.4", + "dispatcher": "1BE2", + "initial_r5": 0xCE, + "bank": "IRQ3 A8 panel byte path", + }, + { + "shadow": "F6DB", + "source": "F006", + "dirty": "F6F3.3", + "dispatcher": "1BF8", + "initial_r5": 0xBE, + "bank": "IRQ3 A8 panel byte path", + }, +] + +KNOWN_REPORTS = { + 0x0007: "CAM POWER", + 0x0015: "CALL", +} + + +def analyze_panel_buttons(rom_bytes: bytes) -> dict[str, Any]: + rom = Rom(rom_bytes) + entries = _table_entries(rom) + handler_summaries = { + target: _summarize_handler(rom, target) + for target in sorted({entry["handler"] for entry in entries if entry["handler"] != NOOP_HANDLER}) + } + for entry in entries: + entry["handler_summary"] = handler_summaries.get(entry["handler"], {}) + selectors = entry["handler_summary"].get("report_selectors", []) + entry["known_report"] = ", ".join( + KNOWN_REPORTS.get(int(selector), f"0x{int(selector):04X}") for selector in selectors + ) + return { + "kind": "panel_button_trace", + "button_table_base": BUTTON_TABLE_BASE, + "button_table_base_hex": h16(BUTTON_TABLE_BASE), + "noop_handler": NOOP_HANDLER, + "noop_handler_hex": h16(NOOP_HANDLER), + "entries": entries, + "known_paths": _known_paths(entries), + "handler_summaries": [ + {"handler": handler, "handler_hex": h16(handler), **summary} + for handler, summary in sorted(handler_summaries.items()) + ], + } + + +def format_markdown(analysis: dict[str, Any]) -> str: + lines = [ + "# PT2 Known Button ROM Trace", + "", + "This report follows the panel button edge path from the serial-visible reports back into the ROM input scanner.", + "The key table is the indirect handler table at `H'2706`, used by `loc_1C0E` after byte-level panel input changes are detected.", + "", + "## Known Anchors", + "", + ] + for path in analysis["known_paths"]: + lines.extend( + [ + f"### {path['name']}", + "", + f"- Emitted selector: `0x{path['selector']:04X}`", + f"- Handler: `H'{path['handler']:04X}`", + f"- Edge source: `{path['source']} -> {path['shadow']}` via `{path['dirty']}`", + f"- Trigger bit: `{path['shadow']}.{path['bit']}`", + f"- Table slot: `H'{path['table_address']:04X}` -> `H'{path['handler']:04X}`", + f"- Current-level tests: {', '.join(path['handler_summary'].get('level_tests', [])) or 'none found'}", + f"- State writes: {', '.join(path['handler_summary'].get('state_writes', [])) or 'none found'}", + "", + ] + ) + lines.extend( + [ + "## Button Matrix Entries With Serial Reports", + "", + "| Source | Shadow bit | Dirty | Handler | Selector(s) | State writes |", + "| --- | --- | --- | --- | --- | --- |", + ] + ) + for entry in analysis["entries"]: + selectors = entry["handler_summary"].get("report_selectors", []) + if not selectors: + continue + selector_text = ", ".join(f"`0x{int(selector):04X}`" for selector in selectors) + writes = ", ".join(f"`{write}`" for write in entry["handler_summary"].get("state_writes", [])[:4]) + lines.append( + f"| `{entry['source']}` | `{entry['shadow']}.{entry['bit']}` | `{entry['dirty']}` | " + f"`H'{entry['handler']:04X}` | {selector_text} | {writes} |" + ) + lines.extend( + [ + "", + "## Practical Read", + "", + "- CALL and CAM POWER do share the general panel edge path with many other buttons.", + "- The shared path is: panel byte snapshot -> shadow byte -> dirty bit -> `loc_1C0E` jump table -> handler -> `loc_3E54` report.", + "- Other buttons diverge in their handlers: many require `F731/F730/F791` session/menu gates, mutate page state, or emit different selectors.", + "- Some table entries are `H'1C25`, an immediate `RTS`, so those physical matrix positions are intentionally ignored in this firmware context.", + "", + ] + ) + return "\n".join(lines) + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser(description="Trace panel button matrix handlers and known CALL/CAM report sources.") + parser.add_argument("rom", nargs="?", type=Path, default=DEFAULT_ROM) + parser.add_argument("--out", type=Path, default=DEFAULT_TEXT_OUTPUT) + parser.add_argument("--json-out", type=Path, default=DEFAULT_JSON_OUTPUT) + args = parser.parse_args(argv) + + analysis = analyze_panel_buttons(args.rom.read_bytes()) + args.out.parent.mkdir(parents=True, exist_ok=True) + args.out.write_text(format_markdown(analysis), encoding="utf-8") + args.json_out.parent.mkdir(parents=True, exist_ok=True) + args.json_out.write_text(json.dumps(analysis, indent=2, sort_keys=True) + "\n", encoding="utf-8") + print(f"wrote {args.out}") + print(f"wrote {args.json_out}") + return 0 + + +def _table_entries(rom: Rom) -> list[dict[str, Any]]: + rows: list[dict[str, Any]] = [] + for lane in INPUT_BYTES: + initial_r5 = int(lane["initial_r5"]) + for bit in range(7, -1, -1): + table_offset = initial_r5 - (2 * (7 - bit)) + table_address = BUTTON_TABLE_BASE + table_offset + handler = rom.u16(table_address) + rows.append( + { + "source": lane["source"], + "shadow": lane["shadow"], + "dirty": lane["dirty"], + "dispatcher": lane["dispatcher"], + "bank": lane["bank"], + "bit": bit, + "table_offset": table_offset, + "table_address": table_address, + "table_address_hex": h16(table_address), + "handler": handler, + "handler_hex": h16(handler), + "is_noop": handler == NOOP_HANDLER, + } + ) + return rows + + +def _known_paths(entries: list[dict[str, Any]]) -> list[dict[str, Any]]: + paths: list[dict[str, Any]] = [] + for entry in entries: + selectors = entry["handler_summary"].get("report_selectors", []) + for selector in selectors: + name = KNOWN_REPORTS.get(int(selector)) + if not name: + continue + paths.append({"name": name, "selector": int(selector), **entry}) + return paths + + +def _summarize_handler(rom: Rom, address: int) -> dict[str, Any]: + instructions = _decode_linear_handler(rom, address) + report_selectors: list[int] = [] + last_r3: int | None = None + level_tests: list[str] = [] + state_writes: list[str] = [] + for ins in instructions: + text = ins.text + if match := re.search(r"MOV:[^#]+#H'([0-9A-F]{4}), R3", text): + last_r3 = int(match.group(1), 16) + if QUEUE_FUNCTION in ins.targets and last_r3 is not None: + if last_r3 not in report_selectors: + report_selectors.append(last_r3) + if match := re.search(r"BTST\.B #([0-7]), @H'(F6[0-9A-F]{2})", text): + test = f"{match.group(2)}.{match.group(1)}" + if test not in level_tests: + level_tests.append(test) + if match := re.search(r"@H'(E[89][0-9A-F]{2})", text): + write = match.group(1) + if _looks_like_write(text) and write not in state_writes: + state_writes.append(write) + return { + "report_selectors": report_selectors, + "report_selectors_hex": [f"0x{selector:04X}" for selector in report_selectors], + "level_tests": level_tests, + "state_writes": state_writes, + "instruction_count_scanned": len(instructions), + } + + +def _decode_linear_handler(rom: Rom, address: int, *, max_bytes: int = 0x90) -> list[Any]: + decoder = H8536Decoder(rom, labels={QUEUE_FUNCTION: "loc_3E54"}) + instructions: list[Any] = [] + pc = address + end = min(len(rom.data), address + max_bytes) + while pc < end: + ins = decoder.decode(pc) + instructions.append(ins) + pc += max(1, ins.size) + if ins.mnemonic == "RTS": + break + return instructions + + +def _looks_like_write(text: str) -> bool: + return text.startswith("MOV") or text.startswith("BSET") or text.startswith("BCLR") or text.startswith("CLR") + + +__all__ = ["analyze_panel_buttons", "format_markdown", "main"] + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/h8536/serial_scenario.py b/h8536/serial_scenario.py index d1f3ebe..632e0a9 100644 --- a/h8536/serial_scenario.py +++ b/h8536/serial_scenario.py @@ -7,7 +7,7 @@ import time from dataclasses import dataclass, field from datetime import datetime from pathlib import Path -from typing import Any, TextIO +from typing import Any, Callable, TextIO from .bench_connect_lcd import ( BenchLogger, @@ -21,6 +21,7 @@ from .bench_connect_lcd import ( _send_frame, _wait_for_ready, format_frame, + frame_checksum, frame_checksum_ok, parse_frame, serial_format_label, @@ -30,6 +31,7 @@ from .serial_table_dump import build_read_frame, decode_table_read_response DEFAULT_ACK_TARGET = bytes.fromhex("07804020902D") DEFAULT_ACK_FRAME = bytes.fromhex("05004000001F") +HEARTBEAT_FRAME = bytes.fromhex("0000000080DA") @dataclass @@ -69,6 +71,11 @@ def build_arg_parser() -> argparse.ArgumentParser: parser.add_argument("--sync", choices=("checksum", "fixed"), default="checksum", help="RX frame sync strategy") parser.add_argument("--log", type=Path, help="capture log path") parser.add_argument("--result-json", type=Path, help="write machine-readable scenario summary") + parser.add_argument( + "--quiet-console", + action="store_true", + help="keep full logs in --log but suppress RX/DETECT chatter on the console", + ) parser.add_argument("--dry-run", action="store_true", help="print the plan without opening serial ports") return parser @@ -83,7 +90,8 @@ def main(argv: list[str] | None = None, *, stdout: TextIO = sys.stdout) -> int: return 0 serial = _import_serial() - logger = BenchLogger(log_path, stdout=stdout) + console = _FilteredStdout(stdout, _quiet_console_line) if args.quiet_console else stdout + logger = BenchLogger(log_path, stdout=console) detector = FrameDetector(sync_mode=args.sync) try: logger.emit("Serial bench scenario") @@ -165,6 +173,8 @@ def _run_step(ctx: ScenarioContext, action: str, spec: dict[str, Any]) -> None: raise SystemExit(2) elif action in {"drain", "listen", "wait"}: _listen(ctx, float(spec.get("seconds", spec.get("value", 0.0)))) + elif action == "listen_ack": + _step_listen_ack(ctx, spec) elif action == "send": frame = _parse_required_frame(spec.get("frame")) label = str(spec.get("label", "send")) @@ -173,6 +183,10 @@ def _run_step(ctx: ScenarioContext, action: str, spec: dict[str, Any]) -> None: _listen(ctx, float(spec.get("listen", 0.0))) elif action == "wait_for": _step_wait_for(ctx, spec) + elif action == "prompt": + _step_prompt(ctx, spec) + elif action == "note": + _step_note(ctx, spec) elif action == "table_sweep": _step_table_sweep(ctx, spec) elif action == "repeat": @@ -214,6 +228,24 @@ def _step_wait_for(ctx: ScenarioContext, spec: dict[str, Any]) -> None: raise SystemExit(3) +def _step_prompt(ctx: ScenarioContext, spec: dict[str, Any]) -> None: + message = str(spec.get("message", spec.get("value", "Press Enter to continue."))) + ctx.logger.event(f"PROMPT {message}") + input(message + " ") + + +def _step_note(ctx: ScenarioContext, spec: dict[str, Any]) -> None: + message = str(spec.get("message", spec.get("value", ""))) + if bool(spec.get("banner", False)): + ctx.logger.emit("") + ctx.logger.emit("NOTE " + "=" * 68) + ctx.logger.event(f"NOTE {message}") + ctx.logger.emit("NOTE " + "=" * 68) + ctx.logger.emit("") + else: + ctx.logger.event(f"NOTE {message}") + + def _step_repeat(ctx: ScenarioContext, spec: dict[str, Any]) -> None: count = max(0, int(spec.get("count", 1))) steps = spec.get("steps", []) @@ -248,10 +280,52 @@ def _step_table_sweep(ctx: ScenarioContext, spec: dict[str, Any]) -> None: _listen_with_ack(ctx, gap, selector, ack) +def _step_listen_ack(ctx: ScenarioContext, spec: dict[str, Any]) -> None: + seconds = float(spec.get("seconds", spec.get("value", 1.0))) + ack = _ack_config( + { + "enabled": spec.get("enabled", True), + "frames": spec.get("frames", spec.get("frame")), + "ack_frame": spec.get("ack_frame"), + "ack_guard": spec.get("ack_guard", 0.020), + "poll_interval": spec.get("poll_interval", 0.005), + "post_ack_read": spec.get("post_ack_read", 0.250), + "once_per_selector": spec.get("once_per_frame", False), + "max_acks": spec.get("max_acks"), + "max_target_hits": spec.get("max_target_hits"), + "abort_on_limit": spec.get("abort_on_limit", False), + "ack_mode": spec.get("ack_mode", spec.get("mode", "fixed")), + "target_mode": spec.get("target_mode", spec.get("match", "explicit")), + "limit_scope": spec.get("limit_scope", spec.get("scope", "local")), + } + ) + ack_text = ( + f"ack_frame={format_frame(ack['frame'])}" + if ack["ack_mode"] == "fixed" + else f"ack_mode={ack['ack_mode']}" + ) + ctx.logger.event( + f"LISTEN_ACK seconds={seconds:.3f} target_mode={ack['target_mode']} targets={len(ack['targets'])} " + f"{ack_text} limit_scope={ack['limit_scope']} max_acks={ack['max_acks']}" + ) + _listen_with_ack(ctx, seconds, None, ack) + + def _ack_config(raw: Any) -> dict[str, Any]: spec = raw if isinstance(raw, dict) else {} enabled = bool(spec.get("enabled", True)) - targets = _parse_frame_list(spec.get("frames", spec.get("frame", DEFAULT_ACK_TARGET))) + ack_mode = str(spec.get("ack_mode", spec.get("mode", "fixed"))).strip().lower().replace("-", "_") + if ack_mode not in {"fixed", "cmd5_selector"}: + raise SystemExit(f"unknown ack_mode {ack_mode!r}") + target_mode = str(spec.get("target_mode", spec.get("match", "explicit"))).strip().lower().replace("-", "_") + if target_mode == "queued_report": + target_mode = "queued_reports" + if target_mode not in {"explicit", "queued_reports"}: + raise SystemExit(f"unknown target_mode {target_mode!r}") + limit_scope = str(spec.get("limit_scope", spec.get("scope", "global"))).strip().lower().replace("-", "_") + if limit_scope not in {"global", "local"}: + raise SystemExit(f"unknown limit_scope {limit_scope!r}") + targets = set() if target_mode == "queued_reports" else _parse_frame_list(spec.get("frames", spec.get("frame", DEFAULT_ACK_TARGET))) if not enabled: targets = set() return { @@ -265,9 +339,29 @@ def _ack_config(raw: Any) -> dict[str, Any]: "max_acks": _optional_int(spec.get("max_acks")), "max_target_hits": _optional_int(spec.get("max_target_hits")), "abort_on_limit": bool(spec.get("abort_on_limit", True)), + "ack_mode": ack_mode, + "target_mode": target_mode, + "limit_scope": limit_scope, } +def _ack_frame_for_target(target: bytes, ack: dict[str, Any]) -> bytes: + if ack["ack_mode"] == "fixed": + return ack["frame"] + if len(target) != 6: + raise SystemExit(f"cannot build selector ACK for malformed target {target!r}") + body = bytes([0x05, target[1] & 0x7F, target[2], 0x00, 0x00]) + return body + bytes([frame_checksum(body)]) + + +def _ack_matches(frame: bytes, ack: dict[str, Any]) -> bool: + if ack["target_mode"] == "explicit": + return frame in ack["targets"] + if frame == HEARTBEAT_FRAME or not frame_checksum_ok(frame): + return False + return frame[0] in {0x00, 0x01, 0x02} and not (frame[1] & 0x80) + + def _listen_with_ack( ctx: ScenarioContext, seconds: float, @@ -277,6 +371,8 @@ def _listen_with_ack( deadline = time.monotonic() + max(0.0, seconds) observed: list[bytes] = [] acked_targets: set[bytes] = set() + ack_start = ctx.ack_sent + target_start = sum(ctx.target_counts.values()) while time.monotonic() < deadline: frames = _read_available(ctx, selector=selector) observed.extend(frames) @@ -288,10 +384,10 @@ def _listen_with_ack( if not ack["enabled"]: continue for frame in frames: - if frame not in ack["targets"]: + if not _ack_matches(frame, ack): continue _count_target(ctx, frame) - if _ack_limit_reached(ctx, ack): + if _ack_limit_reached(ctx, ack, ack_start=ack_start, target_start=target_start): ctx.logger.event("ACK_LIMIT reached before ACK send") if ack["abort_on_limit"]: ctx.abort_requested = True @@ -302,9 +398,9 @@ def _listen_with_ack( acked_targets.add(frame) if ack["guard"] > 0: observed.extend(_listen(ctx, ack["guard"], selector=selector)) - _send_and_record(ctx, ack["frame"], "ack") + _send_and_record(ctx, _ack_frame_for_target(frame, ack), "ack") ctx.ack_sent += 1 - if _ack_limit_reached(ctx, ack): + if _ack_limit_reached(ctx, ack, ack_start=ack_start, target_start=target_start): ctx.logger.event("ACK_LIMIT reached after ACK send") if ack["abort_on_limit"]: ctx.abort_requested = True @@ -440,12 +536,24 @@ def _optional_int(raw: Any) -> int | None: return _int_value(raw) -def _ack_limit_reached(ctx: ScenarioContext, ack: dict[str, Any]) -> bool: +def _ack_limit_reached( + ctx: ScenarioContext, + ack: dict[str, Any], + *, + ack_start: int = 0, + target_start: int = 0, +) -> bool: + if ack.get("limit_scope") == "local": + ack_count = ctx.ack_sent - ack_start + target_count = sum(ctx.target_counts.values()) - target_start + else: + ack_count = ctx.ack_sent + target_count = sum(ctx.target_counts.values()) max_acks = ack.get("max_acks") - if max_acks is not None and ctx.ack_sent >= max_acks: + if max_acks is not None and ack_count >= max_acks: return True max_target_hits = ack.get("max_target_hits") - if max_target_hits is not None and sum(ctx.target_counts.values()) >= max_target_hits: + if max_target_hits is not None and target_count >= max_target_hits: return True return False @@ -462,6 +570,51 @@ def _print_dry_run(args: argparse.Namespace, scenario: dict[str, Any], log_path: _print_step_dry_run(action, spec, stdout) +class _FilteredStdout: + def __init__(self, stdout: TextIO, predicate: Callable[[str], bool]) -> None: + self.stdout = stdout + self.predicate = predicate + self.buffer = "" + + def write(self, text: str) -> int: + self.buffer += text + while "\n" in self.buffer: + line, self.buffer = self.buffer.split("\n", 1) + if self.predicate(line): + self.stdout.write(line + "\n") + self.stdout.flush() + return len(text) + + def flush(self) -> None: + if self.buffer: + if self.predicate(self.buffer): + self.stdout.write(self.buffer) + self.buffer = "" + self.stdout.flush() + + +def _quiet_console_line(line: str) -> bool: + if not line.strip(): + return True + keep_fragments = ( + "Serial bench scenario", + "name=", + "device=", + "log=", + "STEP ", + "PROMPT ", + "NOTE ", + "Summary", + "rx_frames=", + "resync_events=", + "tx_frames=", + "abort_requested=", + "known_shutter", + "queued_shutter", + ) + return any(fragment in line for fragment in keep_fragments) + + def _print_step_dry_run(action: str, spec: dict[str, Any], stdout: TextIO, *, indent: str = " ") -> None: if action == "send": frame = _parse_required_frame(spec.get("frame")) @@ -470,6 +623,42 @@ def _print_step_dry_run(action: str, spec: dict[str, Any], stdout: TextIO, *, in print(f"{indent}listen={float(spec.get('listen', 0.0)):.3f}s", file=stdout) elif action in {"drain", "listen", "wait"}: print(f"{indent}seconds={float(spec.get('seconds', spec.get('value', 0.0))):.3f}", file=stdout) + elif action == "listen_ack": + ack = _ack_config( + { + "enabled": spec.get("enabled", True), + "frames": spec.get("frames", spec.get("frame")), + "ack_frame": spec.get("ack_frame"), + "ack_guard": spec.get("ack_guard", 0.020), + "poll_interval": spec.get("poll_interval", 0.005), + "post_ack_read": spec.get("post_ack_read", 0.250), + "once_per_selector": spec.get("once_per_frame", False), + "max_acks": spec.get("max_acks"), + "max_target_hits": spec.get("max_target_hits"), + "abort_on_limit": spec.get("abort_on_limit", False), + "ack_mode": spec.get("ack_mode", spec.get("mode", "fixed")), + "target_mode": spec.get("target_mode", spec.get("match", "explicit")), + "limit_scope": spec.get("limit_scope", spec.get("scope", "local")), + } + ) + print(f"{indent}seconds={float(spec.get('seconds', spec.get('value', 1.0))):.3f}", file=stdout) + if not ack["enabled"]: + print(f"{indent}ack=disabled", file=stdout) + else: + print(f"{indent}target_mode={ack['target_mode']}", file=stdout) + for target in sorted(ack["targets"]): + print(f"{indent}ack_target={format_frame(target)}", file=stdout) + print(f"{indent}ack_mode={ack['ack_mode']}", file=stdout) + if ack["ack_mode"] == "fixed": + print(f"{indent}ack_frame={format_frame(ack['frame'])}", file=stdout) + print( + f"{indent}limit_scope={ack['limit_scope']} max_acks={ack['max_acks']} " + f"max_target_hits={ack['max_target_hits']}", + file=stdout, + ) + elif action in {"prompt", "note"}: + message = str(spec.get("message", spec.get("value", "Press Enter to continue."))) + print(f"{indent}message={message}", file=stdout) elif action == "wait_ready": print( f"{indent}heartbeats={int(spec.get('heartbeats', 2))} " @@ -493,7 +682,11 @@ def _print_step_dry_run(action: str, spec: dict[str, Any], stdout: TextIO, *, in for target in sorted(ack["targets"]): print(f"{indent}ack_target={format_frame(target)}", file=stdout) print(f"{indent}ack_frame={format_frame(ack['frame'])}", file=stdout) - print(f"{indent}max_acks={ack['max_acks']} max_target_hits={ack['max_target_hits']}", file=stdout) + print( + f"{indent}limit_scope={ack['limit_scope']} max_acks={ack['max_acks']} " + f"max_target_hits={ack['max_target_hits']}", + file=stdout, + ) elif action == "repeat": count = max(0, int(spec.get("count", 1))) steps = spec.get("steps", []) diff --git a/h8536/serial_scenario_compare.py b/h8536/serial_scenario_compare.py new file mode 100644 index 0000000..a49e209 --- /dev/null +++ b/h8536/serial_scenario_compare.py @@ -0,0 +1,121 @@ +from __future__ import annotations + +import argparse +import json +import sys +from collections import Counter +from pathlib import Path +from typing import Any, TextIO + +from .bench_connect_lcd import format_frame, label_frame, parse_frame + + +def build_arg_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser( + description="Compare two serial_scenario result JSON files and highlight extra button/report traffic." + ) + parser.add_argument("baseline", type=Path, help="baseline result JSON, usually a no-button run") + parser.add_argument("candidate", type=Path, help="candidate result JSON, usually a one-button run") + parser.add_argument("--show-labels", action="store_true", help="also show label count deltas") + return parser + + +def main(argv: list[str] | None = None, *, stdout: TextIO = sys.stdout) -> int: + args = build_arg_parser().parse_args(argv) + baseline = _load_result(args.baseline) + candidate = _load_result(args.candidate) + print(format_comparison(baseline, candidate, show_labels=args.show_labels), file=stdout) + return 0 + + +def _load_result(path: Path) -> dict[str, Any]: + with path.open("r", encoding="utf-8") as handle: + result = json.load(handle) + if not isinstance(result, dict): + raise SystemExit(f"{path} is not a result JSON object") + result["_path"] = str(path) + return result + + +def format_comparison( + baseline: dict[str, Any], + candidate: dict[str, Any], + *, + show_labels: bool = False, +) -> str: + base_targets = Counter(_string_int_mapping(baseline.get("ack_targets", {}))) + candidate_targets = Counter(_string_int_mapping(candidate.get("ack_targets", {}))) + target_delta = candidate_targets - base_targets + + lines = [ + "Serial scenario comparison", + f"baseline={baseline.get('_path', '')}", + f"candidate={candidate.get('_path', '')}", + f"baseline_log={baseline.get('log', '')}", + f"candidate_log={candidate.get('log', '')}", + f"baseline_rx_frames={baseline.get('rx_frames', 0)} candidate_rx_frames={candidate.get('rx_frames', 0)}", + f"baseline_ack_sent={baseline.get('ack_sent', 0)} candidate_ack_sent={candidate.get('ack_sent', 0)}", + ] + + if target_delta: + lines.append("extra ACK-target frames in candidate:") + for frame_text, count in sorted(target_delta.items(), key=_frame_sort_key): + lines.append(f" +{count:3d} {frame_text} {_describe_frame(frame_text)}") + else: + lines.append("no extra ACK-target frames found in candidate") + + missing = base_targets - candidate_targets + if missing: + lines.append("baseline ACK-target frames missing/decreased in candidate:") + for frame_text, count in sorted(missing.items(), key=_frame_sort_key): + lines.append(f" -{count:3d} {frame_text} {_describe_frame(frame_text)}") + + if show_labels: + base_labels = Counter(_string_int_mapping(baseline.get("labels", {}))) + candidate_labels = Counter(_string_int_mapping(candidate.get("labels", {}))) + label_delta = candidate_labels - base_labels + lines.append("label count increases:") + if label_delta: + for label, count in sorted(label_delta.items()): + lines.append(f" +{count:3d} {label}") + else: + lines.append(" none") + return "\n".join(lines) + + +def _string_int_mapping(raw: Any) -> dict[str, int]: + if not isinstance(raw, dict): + return {} + output: dict[str, int] = {} + for key, value in raw.items(): + try: + output[str(key)] = int(value) + except (TypeError, ValueError): + continue + return output + + +def _describe_frame(frame_text: str) -> str: + frame = parse_frame(frame_text) + selector = ((frame[1] & 0x7F) << 7) | frame[2] + value = (frame[3] << 8) | frame[4] + label = label_frame(frame) or "checksum_ok_unlabeled" + return f"cmd=0x{frame[0]:02X} selector=0x{selector:04X} value=0x{value:04X} label={label}" + + +def _frame_sort_key(item: tuple[str, int]) -> tuple[int, int, int, str]: + frame_text, _count = item + try: + frame = parse_frame(frame_text) + except argparse.ArgumentTypeError: + return (0xFFFF, 0xFFFF, 0xFFFF, frame_text) + selector = ((frame[1] & 0x7F) << 7) | frame[2] + value = (frame[3] << 8) | frame[4] + return (selector, frame[0], value, frame_text) + + +__all__ = [ + "build_arg_parser", + "format_comparison", + "main", +] diff --git a/h8536/serial_scenario_unexpected.py b/h8536/serial_scenario_unexpected.py index 3632bce..dca6f61 100644 --- a/h8536/serial_scenario_unexpected.py +++ b/h8536/serial_scenario_unexpected.py @@ -19,14 +19,24 @@ DEFAULT_IGNORED_LABELS = { "connect_ok_path_response_candidate", "connect_c0_path_response_candidate", "table_readback_candidate", + "active_selector0_keepalive_report", "gated_active_0004_response_candidate", "gated_active_0004_transition_candidate", } KNOWN_FRAME_LABELS = { + "00 00 00 80 80 5A": "active_selector0_keepalive_report", + "00 00 6C 00 00 36": "copy_completion_exit_selector_006c_candidate", + "00 00 6D 00 00 37": "copy_in_progress_selector_006d_candidate", "00 00 15 80 00 CF": "known_call_button_active_report", "00 00 15 00 00 4F": "known_call_button_inactive_report", "00 00 07 80 00 DD": "known_cam_power_button_report", + "01 00 17 80 00 CC": "queued_bars_button_selector_0017_active_candidate", + "02 00 17 80 00 CF": "queued_bars_button_selector_0017_active_candidate", + "01 00 18 80 00 C3": "queued_bars_button_selector_0018_active_candidate", + "02 00 18 80 00 C0": "queued_bars_button_selector_0018_active_candidate", + "01 01 1A 08 00 48": "queued_iris_auto_button_selector_009a_active_candidate", + "02 01 1A 08 00 4B": "queued_iris_auto_button_selector_009a_active_candidate", "01 00 04 00 00 5F": "gated_active_0004_response_candidate", "02 00 04 00 00 5C": "gated_active_0004_transition_candidate", } diff --git a/h8536_panel_button_trace.py b/h8536_panel_button_trace.py new file mode 100644 index 0000000..37cff5c --- /dev/null +++ b/h8536_panel_button_trace.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 +"""Compatibility wrapper for the H8/536 panel button trace CLI.""" + +from h8536.panel_button_trace import main + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scenarios/button-report-broad-gates-press.json b/scenarios/button-report-broad-gates-press.json new file mode 100644 index 0000000..5325a02 --- /dev/null +++ b/scenarios/button-report-broad-gates-press.json @@ -0,0 +1,208 @@ +{ + "name": "button-report-broad-gates-press", + "notes": [ + "One-button candidate test with broad secondary E400 gates enabled for ROM-observed report selectors.", + "Run this only after the common-gate press test fails to produce a clear extra selector.", + "If a button only emits here, it probably needs a selector-specific feature/report gate rather than only the common queue-service gate." + ], + "steps": [ + { + "action": "prompt", + "message": "Broad-gate run: pick one physical button. When the NOTE banner appears, press it once. Press Enter to start." + }, + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "heartbeats": 2, + "timeout": 10.0, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "selector_zero_connect_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.40 + }, + { + "action": "send", + "label": "secondary_gate_0007", + "frame": "06 00 07 FF FF 5B", + "listen": 0.04 + }, + { + "action": "send", + "label": "secondary_gate_0013", + "frame": "06 00 13 FF FF 4F", + "listen": 0.04 + }, + { + "action": "send", + "label": "secondary_gate_0015", + "frame": "06 00 15 FF FF 49", + "listen": 0.04 + }, + { + "action": "send", + "label": "secondary_gate_0017", + "frame": "06 00 17 FF FF 4B", + "listen": 0.04 + }, + { + "action": "send", + "label": "secondary_gate_0018", + "frame": "06 00 18 FF FF 44", + "listen": 0.04 + }, + { + "action": "send", + "label": "secondary_gate_001a", + "frame": "06 00 1A FF FF 46", + "listen": 0.04 + }, + { + "action": "send", + "label": "secondary_gate_006b", + "frame": "06 01 6B FF FF 36", + "listen": 0.04 + }, + { + "action": "send", + "label": "secondary_gate_0083", + "frame": "06 01 03 FF FF 5E", + "listen": 0.04 + }, + { + "action": "send", + "label": "secondary_gate_008f", + "frame": "06 01 0F FF FF 52", + "listen": 0.04 + }, + { + "action": "send", + "label": "secondary_gate_0093", + "frame": "06 01 13 FF FF 4E", + "listen": 0.04 + }, + { + "action": "send", + "label": "secondary_gate_0096", + "frame": "06 01 16 FF FF 4B", + "listen": 0.04 + }, + { + "action": "send", + "label": "secondary_gate_0097", + "frame": "06 01 17 FF FF 4A", + "listen": 0.04 + }, + { + "action": "send", + "label": "secondary_gate_009a", + "frame": "06 01 1A FF FF 47", + "listen": 0.04 + }, + { + "action": "send", + "label": "secondary_gate_00b7", + "frame": "06 01 37 FF FF 6A", + "listen": 0.04 + }, + { + "action": "send", + "label": "secondary_gate_00b9", + "frame": "06 01 39 FF FF 64", + "listen": 0.04 + }, + { + "action": "send", + "label": "secondary_gate_00c4", + "frame": "06 02 44 FF FF 1A", + "listen": 0.04 + }, + { + "action": "send", + "label": "secondary_gate_00c6", + "frame": "06 02 46 FF FF 18", + "listen": 0.04 + }, + { + "action": "send", + "label": "secondary_gate_00f8", + "frame": "06 02 78 FF FF 26", + "listen": 0.04 + }, + { + "action": "send", + "label": "cmd5_latch_clear_0096", + "frame": "05 01 16 00 00 48", + "listen": 0.05 + }, + { + "action": "listen_ack", + "seconds": 3.20, + "target_mode": "queued_reports", + "ack_mode": "cmd5_selector", + "ack_guard": 0.010, + "post_ack_read": 0.070, + "poll_interval": 0.004, + "once_per_frame": false, + "limit_scope": "local", + "max_acks": 48, + "abort_on_limit": false + }, + { + "action": "send", + "label": "recover_connect_ok_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.45 + }, + { + "action": "listen_ack", + "seconds": 1.20, + "target_mode": "queued_reports", + "ack_mode": "cmd5_selector", + "ack_guard": 0.010, + "post_ack_read": 0.070, + "poll_interval": 0.004, + "once_per_frame": false, + "limit_scope": "local", + "max_acks": 32, + "abort_on_limit": false + }, + { + "action": "note", + "message": "PRESS THE ONE TEST BUTTON NOW; broad secondary gates are enabled.", + "banner": true + }, + { + "action": "listen_ack", + "seconds": 16.00, + "target_mode": "queued_reports", + "ack_mode": "cmd5_selector", + "ack_guard": 0.010, + "post_ack_read": 0.070, + "poll_interval": 0.004, + "once_per_frame": false, + "limit_scope": "local", + "max_acks": 96, + "abort_on_limit": false + }, + { + "action": "send", + "label": "repeat_last_for_hidden_report_check", + "frame": "07 00 00 00 00 5D", + "listen": 0.80 + }, + { + "action": "listen", + "seconds": 1.50 + } + ] +} diff --git a/scenarios/button-report-common-gate-baseline.json b/scenarios/button-report-common-gate-baseline.json new file mode 100644 index 0000000..4b264f4 --- /dev/null +++ b/scenarios/button-report-common-gate-baseline.json @@ -0,0 +1,100 @@ +{ + "name": "button-report-common-gate-baseline", + "notes": [ + "No-button baseline for queued local-control report tests.", + "Do not press or turn controls during the NOTE window. Compare this result JSON against one-button candidate runs.", + "This uses the same common queue-service gate that exposed SHUTTER ON/OFF as selector 0x010F." + ], + "steps": [ + { + "action": "prompt", + "message": "Baseline run: do not touch the panel during the NOTE window. Press Enter to start." + }, + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "heartbeats": 2, + "timeout": 10.0, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "selector_zero_connect_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.60 + }, + { + "action": "send", + "label": "cmd5_latch_clear_0096", + "frame": "05 01 16 00 00 48", + "listen": 0.05 + }, + { + "action": "listen_ack", + "seconds": 3.20, + "target_mode": "queued_reports", + "ack_mode": "cmd5_selector", + "ack_guard": 0.010, + "post_ack_read": 0.070, + "poll_interval": 0.004, + "once_per_frame": false, + "limit_scope": "local", + "max_acks": 48, + "abort_on_limit": false + }, + { + "action": "send", + "label": "recover_connect_ok_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.45 + }, + { + "action": "listen_ack", + "seconds": 1.20, + "target_mode": "queued_reports", + "ack_mode": "cmd5_selector", + "ack_guard": 0.010, + "post_ack_read": 0.070, + "poll_interval": 0.004, + "once_per_frame": false, + "limit_scope": "local", + "max_acks": 32, + "abort_on_limit": false + }, + { + "action": "note", + "message": "NO BUTTONS NOW; baseline queued-report ACK window is running.", + "banner": true + }, + { + "action": "listen_ack", + "seconds": 16.00, + "target_mode": "queued_reports", + "ack_mode": "cmd5_selector", + "ack_guard": 0.010, + "post_ack_read": 0.070, + "poll_interval": 0.004, + "once_per_frame": false, + "limit_scope": "local", + "max_acks": 96, + "abort_on_limit": false + }, + { + "action": "send", + "label": "repeat_last_for_hidden_report_check", + "frame": "07 00 00 00 00 5D", + "listen": 0.80 + }, + { + "action": "listen", + "seconds": 1.50 + } + ] +} diff --git a/scenarios/button-report-common-gate-press.json b/scenarios/button-report-common-gate-press.json new file mode 100644 index 0000000..59ad7a3 --- /dev/null +++ b/scenarios/button-report-common-gate-press.json @@ -0,0 +1,100 @@ +{ + "name": "button-report-common-gate-press", + "notes": [ + "One-button candidate test for queued local-control reports.", + "Run the common-gate baseline first, then run this once per physical button candidate and compare result JSON files.", + "If a button produces an extra selector here, it probably shares the same common queue-service gate as SHUTTER ON/OFF." + ], + "steps": [ + { + "action": "prompt", + "message": "Pick one physical button for this run. When the NOTE banner appears, press it once. Press Enter to start." + }, + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "heartbeats": 2, + "timeout": 10.0, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "selector_zero_connect_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.60 + }, + { + "action": "send", + "label": "cmd5_latch_clear_0096", + "frame": "05 01 16 00 00 48", + "listen": 0.05 + }, + { + "action": "listen_ack", + "seconds": 3.20, + "target_mode": "queued_reports", + "ack_mode": "cmd5_selector", + "ack_guard": 0.010, + "post_ack_read": 0.070, + "poll_interval": 0.004, + "once_per_frame": false, + "limit_scope": "local", + "max_acks": 48, + "abort_on_limit": false + }, + { + "action": "send", + "label": "recover_connect_ok_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.45 + }, + { + "action": "listen_ack", + "seconds": 1.20, + "target_mode": "queued_reports", + "ack_mode": "cmd5_selector", + "ack_guard": 0.010, + "post_ack_read": 0.070, + "poll_interval": 0.004, + "once_per_frame": false, + "limit_scope": "local", + "max_acks": 32, + "abort_on_limit": false + }, + { + "action": "note", + "message": "PRESS THE ONE TEST BUTTON NOW; live queued-report ACK window is running.", + "banner": true + }, + { + "action": "listen_ack", + "seconds": 16.00, + "target_mode": "queued_reports", + "ack_mode": "cmd5_selector", + "ack_guard": 0.010, + "post_ack_read": 0.070, + "poll_interval": 0.004, + "once_per_frame": false, + "limit_scope": "local", + "max_acks": 96, + "abort_on_limit": false + }, + { + "action": "send", + "label": "repeat_last_for_hidden_report_check", + "frame": "07 00 00 00 00 5D", + "listen": 0.80 + }, + { + "action": "listen", + "seconds": 1.50 + } + ] +} diff --git a/scenarios/copy-family00-006d-006c-1000ms.json b/scenarios/copy-family00-006d-006c-1000ms.json new file mode 100644 index 0000000..34163c9 --- /dev/null +++ b/scenarios/copy-family00-006d-006c-1000ms.json @@ -0,0 +1,47 @@ +{ + "name": "copy-family00-006d-006c-1000ms", + "notes": [ + "Recover to CONNECT OK, send family-00 selector 0x006D, then family-00 selector 0x006C 1 second later.", + "Gives the LCD time to visibly enter COPY IN PROGRESS if family-00 0x006D drives the same queue path as command 5." + ], + "steps": [ + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "timeout": 10.0, + "heartbeats": 2, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "ok_baseline_1", + "frame": "04 00 00 80 00 DE", + "listen": 0.7 + }, + { + "action": "send", + "label": "ok_baseline_2", + "frame": "04 00 00 80 00 DE", + "listen": 1.0 + }, + { + "action": "send", + "label": "family00_copy_start_006d", + "frame": "00 00 6D 00 00 37", + "listen": 1.0 + }, + { + "action": "send", + "label": "family00_copy_complete_candidate_006c", + "frame": "00 00 6C 00 00 36", + "listen": 10.0 + } + ] +} diff --git a/scenarios/copy-family00-006d-006c-250ms.json b/scenarios/copy-family00-006d-006c-250ms.json new file mode 100644 index 0000000..3adce09 --- /dev/null +++ b/scenarios/copy-family00-006d-006c-250ms.json @@ -0,0 +1,47 @@ +{ + "name": "copy-family00-006d-006c-250ms", + "notes": [ + "Recover to CONNECT OK, send family-00 selector 0x006D, then family-00 selector 0x006C 250 ms later.", + "Compares family-00 set/queue behavior against the known command-5 COPY start/complete pair." + ], + "steps": [ + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "timeout": 10.0, + "heartbeats": 2, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "ok_baseline_1", + "frame": "04 00 00 80 00 DE", + "listen": 0.7 + }, + { + "action": "send", + "label": "ok_baseline_2", + "frame": "04 00 00 80 00 DE", + "listen": 1.0 + }, + { + "action": "send", + "label": "family00_copy_start_006d", + "frame": "00 00 6D 00 00 37", + "listen": 0.25 + }, + { + "action": "send", + "label": "family00_copy_complete_candidate_006c", + "frame": "00 00 6C 00 00 36", + "listen": 10.0 + } + ] +} diff --git a/scenarios/others-menu-gated-baseline.json b/scenarios/others-menu-gated-baseline.json new file mode 100644 index 0000000..a9f2187 --- /dev/null +++ b/scenarios/others-menu-gated-baseline.json @@ -0,0 +1,124 @@ +{ + "name": "others-menu-gated-baseline", + "notes": [ + "No-button baseline for OTHERS/menu testing.", + "Seeds the known OTHERS-adjacent state: E000[0x008F]=0x1800 and E400[0x0015]=0x0001.", + "Compare this against others-menu-gated-press before assigning any OTHERS button meaning." + ], + "steps": [ + { + "action": "prompt", + "message": "OTHERS gated baseline: do not touch the panel during the NOTE window. Press Enter to start." + }, + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "heartbeats": 2, + "timeout": 10.0, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "selector_zero_connect_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.45 + }, + { + "action": "send", + "label": "others_root_008f_bits_11_12", + "frame": "00 01 0F 18 00 4C", + "listen": 0.30 + }, + { + "action": "send", + "label": "others_secondary_gate_0015_low", + "frame": "06 00 15 00 01 48", + "listen": 0.10 + }, + { + "action": "send", + "label": "cmd5_latch_clear_0096", + "frame": "05 01 16 00 00 48", + "listen": 0.05 + }, + { + "action": "listen_ack", + "seconds": 3.20, + "target_mode": "queued_reports", + "ack_mode": "cmd5_selector", + "ack_guard": 0.010, + "post_ack_read": 0.070, + "poll_interval": 0.004, + "once_per_frame": false, + "limit_scope": "local", + "max_acks": 64, + "abort_on_limit": false + }, + { + "action": "send", + "label": "recover_connect_ok_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.35 + }, + { + "action": "send", + "label": "refresh_others_root_008f_bits_11_12", + "frame": "00 01 0F 18 00 4C", + "listen": 0.15 + }, + { + "action": "send", + "label": "refresh_others_secondary_gate_0015_low", + "frame": "06 00 15 00 01 48", + "listen": 0.05 + }, + { + "action": "listen_ack", + "seconds": 1.20, + "target_mode": "queued_reports", + "ack_mode": "cmd5_selector", + "ack_guard": 0.010, + "post_ack_read": 0.070, + "poll_interval": 0.004, + "once_per_frame": false, + "limit_scope": "local", + "max_acks": 32, + "abort_on_limit": false + }, + { + "action": "note", + "message": "NO BUTTONS NOW; OTHERS-gated queued-report ACK window is running.", + "banner": true + }, + { + "action": "listen_ack", + "seconds": 16.00, + "target_mode": "queued_reports", + "ack_mode": "cmd5_selector", + "ack_guard": 0.010, + "post_ack_read": 0.070, + "poll_interval": 0.004, + "once_per_frame": false, + "limit_scope": "local", + "max_acks": 128, + "abort_on_limit": false + }, + { + "action": "send", + "label": "repeat_last_for_hidden_report_check", + "frame": "07 00 00 00 00 5D", + "listen": 0.80 + }, + { + "action": "listen", + "seconds": 1.50 + } + ] +} diff --git a/scenarios/others-menu-gated-press.json b/scenarios/others-menu-gated-press.json new file mode 100644 index 0000000..04d2252 --- /dev/null +++ b/scenarios/others-menu-gated-press.json @@ -0,0 +1,124 @@ +{ + "name": "others-menu-gated-press", + "notes": [ + "Press-run for OTHERS/menu testing.", + "Seeds the known OTHERS-adjacent state: E000[0x008F]=0x1800 and E400[0x0015]=0x0001.", + "Press the OTHERS button once at the NOTE banner, then compare against others-menu-gated-baseline." + ], + "steps": [ + { + "action": "prompt", + "message": "OTHERS gated press run: when the NOTE banner appears, press OTHERS once. Press Enter to start." + }, + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "heartbeats": 2, + "timeout": 10.0, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "selector_zero_connect_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.45 + }, + { + "action": "send", + "label": "others_root_008f_bits_11_12", + "frame": "00 01 0F 18 00 4C", + "listen": 0.30 + }, + { + "action": "send", + "label": "others_secondary_gate_0015_low", + "frame": "06 00 15 00 01 48", + "listen": 0.10 + }, + { + "action": "send", + "label": "cmd5_latch_clear_0096", + "frame": "05 01 16 00 00 48", + "listen": 0.05 + }, + { + "action": "listen_ack", + "seconds": 3.20, + "target_mode": "queued_reports", + "ack_mode": "cmd5_selector", + "ack_guard": 0.010, + "post_ack_read": 0.070, + "poll_interval": 0.004, + "once_per_frame": false, + "limit_scope": "local", + "max_acks": 64, + "abort_on_limit": false + }, + { + "action": "send", + "label": "recover_connect_ok_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.35 + }, + { + "action": "send", + "label": "refresh_others_root_008f_bits_11_12", + "frame": "00 01 0F 18 00 4C", + "listen": 0.15 + }, + { + "action": "send", + "label": "refresh_others_secondary_gate_0015_low", + "frame": "06 00 15 00 01 48", + "listen": 0.05 + }, + { + "action": "listen_ack", + "seconds": 1.20, + "target_mode": "queued_reports", + "ack_mode": "cmd5_selector", + "ack_guard": 0.010, + "post_ack_read": 0.070, + "poll_interval": 0.004, + "once_per_frame": false, + "limit_scope": "local", + "max_acks": 32, + "abort_on_limit": false + }, + { + "action": "note", + "message": "PRESS OTHERS NOW; OTHERS-gated queued-report ACK window is running.", + "banner": true + }, + { + "action": "listen_ack", + "seconds": 16.00, + "target_mode": "queued_reports", + "ack_mode": "cmd5_selector", + "ack_guard": 0.010, + "post_ack_read": 0.070, + "poll_interval": 0.004, + "once_per_frame": false, + "limit_scope": "local", + "max_acks": 128, + "abort_on_limit": false + }, + { + "action": "send", + "label": "repeat_last_for_hidden_report_check", + "frame": "07 00 00 00 00 5D", + "listen": 0.80 + }, + { + "action": "listen", + "seconds": 1.50 + } + ] +} diff --git a/scenarios/shutter-onoff-report-ack-c0-recover-ok-0096-prompt.json b/scenarios/shutter-onoff-report-ack-c0-recover-ok-0096-prompt.json new file mode 100644 index 0000000..a2b1804 --- /dev/null +++ b/scenarios/shutter-onoff-report-ack-c0-recover-ok-0096-prompt.json @@ -0,0 +1,116 @@ +{ + "name": "shutter-onoff-report-ack-c0-recover-ok-0096-prompt", + "notes": [ + "Second-pass SHUTTER ON/OFF report test based on the latest captures.", + "Bench evidence: after command-5 selector 0x0096, the RCP emits repeated 01 00 02 00 00 59 frames. This scenario ACKs that stream before trying to recover CONNECT OK.", + "When prompted, press SHUTTER ON/OFF during the active refresh/ACK loop. Desired report candidates are 00 01 0F 80 00 D4 or 00 01 0F 20 00 74." + ], + "steps": [ + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "heartbeats": 2, + "timeout": 10.0, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "selector_zero_connect_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.60 + }, + { + "action": "send", + "label": "cmd5_latch_clear_0096", + "frame": "05 01 16 00 00 48", + "listen": 0.05 + }, + { + "action": "listen_ack", + "seconds": 1.80, + "frames": [ + "01 00 02 00 00 59", + "02 00 02 00 00 5A" + ], + "ack_frame": "05 00 02 00 00 5D", + "ack_guard": 0.015, + "post_ack_read": 0.120, + "poll_interval": 0.005, + "max_acks": 8, + "abort_on_limit": false + }, + { + "action": "drain", + "seconds": 0.10 + }, + { + "action": "send", + "label": "recover_connect_ok_seed_1", + "frame": "00 00 00 80 00 DA", + "listen": 0.70 + }, + { + "action": "send", + "label": "recover_connect_ok_seed_2", + "frame": "00 00 00 80 00 DA", + "listen": 0.70 + }, + { + "action": "send", + "label": "quiet_active_refresh_0093_9020", + "frame": "00 01 13 90 20 F8", + "listen": 0.35 + }, + { + "action": "prompt", + "message": "Press Enter, then press SHUTTER ON/OFF during the next refresh/ACK loop. Note LCD state and time." + }, + { + "action": "drain", + "seconds": 0.05 + }, + { + "action": "repeat", + "count": 12, + "steps": [ + { + "action": "send", + "label": "maintain_ok_0093_9020", + "frame": "00 01 13 90 20 F8", + "listen": 0.15 + }, + { + "action": "listen_ack", + "seconds": 0.30, + "frames": [ + "01 00 02 00 00 59", + "02 00 02 00 00 5A" + ], + "ack_frame": "05 00 02 00 00 5D", + "ack_guard": 0.010, + "post_ack_read": 0.060, + "poll_interval": 0.005, + "max_acks": 1, + "abort_on_limit": false + } + ] + }, + { + "action": "send", + "label": "repeat_last_for_hidden_report_check", + "frame": "07 00 00 00 00 5D", + "listen": 0.80 + }, + { + "action": "listen", + "seconds": 1.50 + } + ] +} diff --git a/scenarios/shutter-onoff-report-dynamic-queue-ack-0096-prompt.json b/scenarios/shutter-onoff-report-dynamic-queue-ack-0096-prompt.json new file mode 100644 index 0000000..f97ddbb --- /dev/null +++ b/scenarios/shutter-onoff-report-dynamic-queue-ack-0096-prompt.json @@ -0,0 +1,105 @@ +{ + "name": "shutter-onoff-report-dynamic-queue-ack-0096-prompt", + "notes": [ + "Third-pass SHUTTER ON/OFF report test. The prior capture proved the first ACK advanced 01 00 02 to a repeated 02 00 04 stream.", + "This scenario dynamically ACKs queued report selectors with command 5, so 02 00 04 gets ACKed as 05 00 04 00 00 5B, 02 00 12 as 05 00 12 00 00 4D, and so on.", + "Do not treat CONNECT OK as required here. The target is a clean 0x008F local-control report: 00 01 0F 80 00 D4 or 00 01 0F 20 00 74.", + "The only blocking prompt is before power cycle. The in-window SHUTTER cue is a non-blocking note so RX/TX traffic does not pause and drop the panel out of CONNECT OK." + ], + "steps": [ + { + "action": "prompt", + "message": "Get ready. After the queue drain the script will print NOTE PRESS SHUTTER ON/OFF NOW; press the button once immediately. Press Enter to start." + }, + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "heartbeats": 2, + "timeout": 10.0, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "selector_zero_connect_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.60 + }, + { + "action": "send", + "label": "cmd5_latch_clear_0096", + "frame": "05 01 16 00 00 48", + "listen": 0.05 + }, + { + "action": "listen_ack", + "seconds": 3.20, + "target_mode": "queued_reports", + "ack_mode": "cmd5_selector", + "ack_guard": 0.010, + "post_ack_read": 0.090, + "poll_interval": 0.004, + "once_per_frame": false, + "limit_scope": "local", + "max_acks": 32, + "abort_on_limit": false + }, + { + "action": "drain", + "seconds": 0.15 + }, + { + "action": "send", + "label": "recover_connect_ok_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.45 + }, + { + "action": "listen_ack", + "seconds": 1.20, + "target_mode": "queued_reports", + "ack_mode": "cmd5_selector", + "ack_guard": 0.010, + "post_ack_read": 0.070, + "poll_interval": 0.004, + "once_per_frame": false, + "limit_scope": "local", + "max_acks": 24, + "abort_on_limit": false + }, + { + "action": "note", + "message": "PRESS SHUTTER ON/OFF NOW; live queued-report ACK window continues without pausing.", + "banner": true + }, + { + "action": "listen_ack", + "seconds": 8.00, + "target_mode": "queued_reports", + "ack_mode": "cmd5_selector", + "ack_guard": 0.010, + "post_ack_read": 0.070, + "poll_interval": 0.004, + "once_per_frame": false, + "limit_scope": "local", + "max_acks": 48, + "abort_on_limit": false + }, + { + "action": "send", + "label": "repeat_last_for_hidden_report_check", + "frame": "07 00 00 00 00 5D", + "listen": 0.80 + }, + { + "action": "listen", + "seconds": 1.50 + } + ] +} diff --git a/scenarios/shutter-onoff-report-latch-open-0096-prompt.json b/scenarios/shutter-onoff-report-latch-open-0096-prompt.json new file mode 100644 index 0000000..ab17480 --- /dev/null +++ b/scenarios/shutter-onoff-report-latch-open-0096-prompt.json @@ -0,0 +1,58 @@ +{ + "name": "shutter-onoff-report-latch-open-0096-prompt", + "notes": [ + "This is the cleaner emulator-derived SHUTTER ON/OFF report test.", + "Important: the emulator expects CONNECT OK to fall back to CONNECT NOT ACT just as the report gate opens.", + "After the prompt, press SHUTTER ON/OFF during the listen window even if the LCD says CONNECT NOT ACT." + ], + "steps": [ + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "heartbeats": 2, + "timeout": 10.0, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "selector_zero_connect_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.60 + }, + { + "action": "send", + "label": "cmd5_latch_clear_0096", + "frame": "05 01 16 00 00 48", + "listen": 1.30 + }, + { + "action": "prompt", + "message": "Press Enter, then press SHUTTER ON/OFF once or twice during the next 6 seconds, even if the LCD is CONNECT NOT ACT." + }, + { + "action": "drain", + "seconds": 0.05 + }, + { + "action": "listen", + "seconds": 6.0 + }, + { + "action": "send", + "label": "repeat_last_for_hidden_report_check", + "frame": "07 00 00 00 00 5D", + "listen": 0.80 + }, + { + "action": "listen", + "seconds": 1.50 + } + ] +} diff --git a/scenarios/shutter-onoff-report-recover-ok-after-clear-0096-prompt.json b/scenarios/shutter-onoff-report-recover-ok-after-clear-0096-prompt.json new file mode 100644 index 0000000..d8afe18 --- /dev/null +++ b/scenarios/shutter-onoff-report-recover-ok-after-clear-0096-prompt.json @@ -0,0 +1,78 @@ +{ + "name": "shutter-onoff-report-recover-ok-after-clear-0096-prompt", + "notes": [ + "Friendlier visual test: clear the SHUTTER report gate, then re-light CONNECT OK before the manual button window.", + "This is noisier than the latch-open test because the OK refresh stream can queue other active reports ahead of the button report.", + "After the prompt, press SHUTTER ON/OFF while CONNECT OK is visible or during the following refresh window." + ], + "steps": [ + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "heartbeats": 2, + "timeout": 10.0, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "selector_zero_connect_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.60 + }, + { + "action": "send", + "label": "cmd5_latch_clear_0096", + "frame": "05 01 16 00 00 48", + "listen": 1.25 + }, + { + "action": "send", + "label": "recover_connect_ok_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.35 + }, + { + "action": "send", + "label": "quiet_active_refresh_0093_9020", + "frame": "00 01 13 90 20 F8", + "listen": 0.35 + }, + { + "action": "prompt", + "message": "Press Enter, then press SHUTTER ON/OFF during the refresh loop. Watch for 00 01 0F 80 00 D4 or 00 01 0F 20 00 74." + }, + { + "action": "drain", + "seconds": 0.05 + }, + { + "action": "repeat", + "count": 16, + "steps": [ + { + "action": "send", + "label": "maintain_ok_0093_9020", + "frame": "00 01 13 90 20 F8", + "listen": 0.45 + } + ] + }, + { + "action": "send", + "label": "repeat_last_for_hidden_report_check", + "frame": "07 00 00 00 00 5D", + "listen": 0.80 + }, + { + "action": "listen", + "seconds": 1.50 + } + ] +} diff --git a/scenarios/shutter-onoff-report-unlock-0096-watch.json b/scenarios/shutter-onoff-report-unlock-0096-watch.json new file mode 100644 index 0000000..c7a2dc5 --- /dev/null +++ b/scenarios/shutter-onoff-report-unlock-0096-watch.json @@ -0,0 +1,50 @@ +{ + "name": "shutter-onoff-report-unlock-0096-watch", + "notes": [ + "Bench check for the SHUTTER ON/OFF-style report path found in the emulator.", + "Emulator model: selector-zero OK seed, command-5 selector 0x0096, wait for the F731 latch to clear, then F6D0.7 emits 00 01 0F 80 00 D4 and F6D0.6 emits 00 01 0F 20 00 74.", + "When the final listen window starts, press SHUTTER ON/OFF once or twice and note the time/LCD state." + ], + "steps": [ + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "heartbeats": 2, + "timeout": 10.0, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "selector_zero_connect_ok_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.60 + }, + { + "action": "send", + "label": "cmd5_latch_clear_0096", + "frame": "05 01 16 00 00 48", + "listen": 1.60 + }, + { + "action": "listen", + "seconds": 8.0 + }, + { + "action": "send", + "label": "repeat_last_for_hidden_report_check", + "frame": "07 00 00 00 00 5D", + "listen": 0.80 + }, + { + "action": "listen", + "seconds": 1.50 + } + ] +} diff --git a/scenarios/shutter-onoff-report-unlock-00f8-watch.json b/scenarios/shutter-onoff-report-unlock-00f8-watch.json new file mode 100644 index 0000000..b1dee85 --- /dev/null +++ b/scenarios/shutter-onoff-report-unlock-00f8-watch.json @@ -0,0 +1,50 @@ +{ + "name": "shutter-onoff-report-unlock-00f8-watch", + "notes": [ + "Sibling latch-clear bench check for the SHUTTER ON/OFF-style report path.", + "Emulator model: selector-zero OK seed, command-5 selector 0x00F8, wait for the F731 latch to clear, then F6D0.7 can emit 00 01 0F 80 00 D4.", + "When the final listen window starts, press SHUTTER ON/OFF once or twice and note the time/LCD state." + ], + "steps": [ + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "heartbeats": 2, + "timeout": 10.0, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "selector_zero_connect_ok_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.60 + }, + { + "action": "send", + "label": "cmd5_latch_clear_00f8", + "frame": "05 01 78 00 00 26", + "listen": 1.60 + }, + { + "action": "listen", + "seconds": 8.0 + }, + { + "action": "send", + "label": "repeat_last_for_hidden_report_check", + "frame": "07 00 00 00 00 5D", + "listen": 0.80 + }, + { + "action": "listen", + "seconds": 1.50 + } + ] +} diff --git a/scripts/ccu_emulator.py b/scripts/ccu_emulator.py new file mode 100644 index 0000000..c4ee7c7 --- /dev/null +++ b/scripts/ccu_emulator.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +"""Run the modular fake CCU.""" + +import sys +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +if str(ROOT) not in sys.path: + sys.path.insert(0, str(ROOT)) + +from ccu_emulator.cli import main + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/serial_scenario_compare.py b/scripts/serial_scenario_compare.py new file mode 100644 index 0000000..ebe9dc0 --- /dev/null +++ b/scripts/serial_scenario_compare.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python +"""Compare two serial_scenario result JSON files.""" + +from __future__ import annotations + +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parents[1])) + +from h8536.serial_scenario_compare import main + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/test_bench_connect_lcd.py b/tests/test_bench_connect_lcd.py index d6866b6..b039221 100644 --- a/tests/test_bench_connect_lcd.py +++ b/tests/test_bench_connect_lcd.py @@ -77,6 +77,15 @@ class BenchConnectLcdTest(unittest.TestCase): def test_label_frame_marks_visible_retry_ack_target(self): self.assertEqual(label_frame(bytes.fromhex("07804020902D")), "visible_retry_0040_2090_candidate") + def test_label_frame_marks_active_selector0_keepalive_report(self): + self.assertEqual(label_frame(bytes.fromhex("00000080805A")), "active_selector0_keepalive_report") + + def test_label_frame_marks_copy_completion_exit_selector_006c_candidate(self): + self.assertEqual(label_frame(bytes.fromhex("00006C000036")), "copy_completion_exit_selector_006c_candidate") + + def test_label_frame_marks_copy_in_progress_selector_006d_candidate(self): + self.assertEqual(label_frame(bytes.fromhex("00006D000037")), "copy_in_progress_selector_006d_candidate") + if __name__ == "__main__": unittest.main() diff --git a/tests/test_ccu_emulator.py b/tests/test_ccu_emulator.py new file mode 100644 index 0000000..c1b95ac --- /dev/null +++ b/tests/test_ccu_emulator.py @@ -0,0 +1,33 @@ +import unittest + +from ccu_emulator.frames import ACTIVE_SEED_COMMAND0, NEUTRAL_ACK_FRAME, build_frame, frame_checksum_ok +from ccu_emulator.policy import AckPolicy +from ccu_emulator.refresh import PeriodicRefresh + + +class CcuEmulatorFrameTests(unittest.TestCase): + def test_build_frame_adds_checksum(self): + self.assertEqual(build_frame(0x00, 0x0000, 0x8080), ACTIVE_SEED_COMMAND0) + self.assertTrue(frame_checksum_ok(build_frame(0x06, 0x0015, 0x0001))) + + def test_ack_policy_acknowledges_reports_with_neutral_ack(self): + decision = AckPolicy().decide(bytes.fromhex("02000200005A"), "connect_ok_path_response_candidate") + self.assertTrue(decision.should_ack) + self.assertEqual(decision.frame, NEUTRAL_ACK_FRAME) + + def test_ack_policy_skips_table_readback(self): + decision = AckPolicy().decide(bytes.fromhex("04000080805E"), "table_readback_candidate") + self.assertFalse(decision.should_ack) + + +class PeriodicRefreshTests(unittest.TestCase): + def test_periodic_refresh_returns_due_frames(self): + refresh = PeriodicRefresh(frames=[ACTIVE_SEED_COMMAND0], interval=0.5) + refresh.start(now=10.0) + self.assertEqual(refresh.due_frames(now=10.4), []) + self.assertEqual(refresh.due_frames(now=10.5), [ACTIVE_SEED_COMMAND0]) + self.assertEqual(refresh.due_frames(now=10.6), []) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_emulator.py b/tests/test_emulator.py index 56e1f7d..253f131 100644 --- a/tests/test_emulator.py +++ b/tests/test_emulator.py @@ -191,6 +191,28 @@ class EmulatorHarnessTest(unittest.TestCase): self.assertEqual(writes[-1].value, 0x77) self.assertEqual(writes[-1].pc, 0x1000) + def test_panel_input_injection_sets_source_shadow_previous_and_dirty_edge(self): + emulator = H8536Emulator(bytes(rom_with_reset())) + + injection = emulator.inject_panel_input("cam-power", pressed=True) + + self.assertEqual(injection.action.panel_input.selector, 0x0007) + self.assertEqual(emulator.memory.read8(0xF105) & 0x08, 0x08) + self.assertEqual(emulator.memory.read8(0xF6D4) & 0x08, 0x08) + self.assertEqual(emulator.memory.read8(0xF6E4) & 0x08, 0x00) + self.assertEqual(emulator.memory.read8(0xF6F2) & 0x10, 0x10) + + def test_panel_input_release_forces_opposite_previous_sample(self): + emulator = H8536Emulator(bytes(rom_with_reset())) + + injection = emulator.inject_panel_input("call", pressed=False) + + self.assertEqual(injection.action.panel_input.selector, 0x0015) + self.assertEqual(emulator.memory.read8(0xF006) & 0x20, 0x00) + self.assertEqual(emulator.memory.read8(0xF6DB) & 0x20, 0x00) + self.assertEqual(emulator.memory.read8(0xF6EB) & 0x20, 0x20) + self.assertEqual(emulator.memory.read8(0xF6F3) & 0x08, 0x08) + if __name__ == "__main__": unittest.main() diff --git a/tests/test_emulator_rx_probe.py b/tests/test_emulator_rx_probe.py index 7546cae..1fd12c1 100644 --- a/tests/test_emulator_rx_probe.py +++ b/tests/test_emulator_rx_probe.py @@ -2,7 +2,17 @@ import argparse import unittest from h8536.emulator import H8536Emulator, SCI1_RDR, SCI1_SSR, SCI_SSR_ORER, SCI_SSR_RDRF -from h8536.emulator.rx_probe import RunContext, UartTiming, _inject_frame_uart_timed, frame_checksum, frame_checksum_ok, parse_frame +from h8536.emulator.rx_probe import ( + RunContext, + UartTiming, + _inject_frame_uart_timed, + frame_checksum, + frame_checksum_ok, + parse_frame, + parse_panel_action_arg, + parse_panel_press_arg, + parse_panel_release_arg, +) def rom_with_reset(*, reset: int = 0x1000, size: int = 0x1020) -> bytearray: @@ -30,6 +40,25 @@ class EmulatorRxProbeTest(unittest.TestCase): with self.assertRaises(argparse.ArgumentTypeError): parse_frame("04 00 00 40") + def test_parse_panel_action_accepts_alias_state_and_raw_shadow_bit(self): + action = parse_panel_action_arg("cam-power=release") + self.assertEqual(action.panel_input.shadow, 0xF6D4) + self.assertEqual(action.panel_input.bit, 3) + self.assertFalse(action.pressed) + + raw = parse_panel_press_arg("F6D4.6") + self.assertEqual(raw.panel_input.source, 0xF105) + self.assertEqual(raw.panel_input.dirty, 0xF6F2) + self.assertEqual(raw.panel_input.dirty_bit, 4) + self.assertTrue(raw.pressed) + + def test_parse_panel_release_accepts_source_address_lane(self): + action = parse_panel_release_arg("F006.5") + + self.assertEqual(action.panel_input.shadow, 0xF6DB) + self.assertEqual(action.panel_input.previous, 0xF6EB) + self.assertFalse(action.pressed) + def test_uart_timed_injection_does_not_wait_for_rdrf_consumption(self): emulator = H8536Emulator(bytes(rom_with_reset()), clock_hz=10_000_000) context = RunContext() diff --git a/tests/test_serial_scenario_compare.py b/tests/test_serial_scenario_compare.py new file mode 100644 index 0000000..4e9159b --- /dev/null +++ b/tests/test_serial_scenario_compare.py @@ -0,0 +1,37 @@ +import unittest + +from h8536.serial_scenario_compare import format_comparison + + +class SerialScenarioCompareTest(unittest.TestCase): + def test_comparison_reports_extra_selector_and_value(self): + baseline = { + "_path": "baseline.json", + "log": "baseline.txt", + "rx_frames": 10, + "ack_sent": 2, + "ack_targets": { + "01 00 02 00 00 59": 1, + }, + } + candidate = { + "_path": "candidate.json", + "log": "candidate.txt", + "rx_frames": 12, + "ack_sent": 3, + "ack_targets": { + "01 00 02 00 00 59": 1, + "01 01 0F 80 00 D5": 1, + }, + } + + report = format_comparison(baseline, candidate) + + self.assertIn("extra ACK-target frames in candidate", report) + self.assertIn("01 01 0F 80 00 D5", report) + self.assertIn("selector=0x008F", report) + self.assertIn("value=0x8000", report) + + +if __name__ == "__main__": + unittest.main()