82 lines
2.8 KiB
Python
82 lines
2.8 KiB
Python
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()
|