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, parse_panel_action_arg, parse_panel_press_arg, parse_panel_release_arg, ) def rom_with_reset(*, reset: int = 0x1000, size: int = 0x1020) -> bytearray: rom = bytearray([0xFF] * size) rom[0:2] = reset.to_bytes(2, "big") rom[reset : reset + 2] = b"\x20\xFE" # BRA self return rom class EmulatorRxProbeTest(unittest.TestCase): def test_parse_frame_accepts_five_bytes_and_appends_checksum(self): frame = parse_frame("04 00 00 40 00") self.assertEqual(frame, bytes.fromhex("04000040001E")) self.assertTrue(frame_checksum_ok(frame)) def test_parse_frame_accepts_compact_checked_frame(self): frame = parse_frame("0780684030C5") self.assertEqual(frame, bytes.fromhex("0780684030C5")) self.assertEqual(frame_checksum(frame), 0xC5) self.assertTrue(frame_checksum_ok(frame)) def test_parse_frame_rejects_wrong_length(self): 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() steps, reason = _inject_frame_uart_timed( emulator, b"\x11\x22", timing=UartTiming(baud=38_400), max_steps_per_gap=1000, context=context, ) self.assertEqual(reason, "frame_injected_uart_timing") self.assertGreater(steps, 0) self.assertEqual(emulator.memory.read8(SCI1_RDR), 0x11) self.assertEqual(emulator.memory.read8(SCI1_SSR) & (SCI_SSR_RDRF | SCI_SSR_ORER), SCI_SSR_RDRF | SCI_SSR_ORER) if __name__ == "__main__": unittest.main()