import json import tempfile import unittest from pathlib import Path from h8536.render import format_listing, write_json from h8536.rom import Rom from h8536.vectors import read_dtc_vectors_min def _manual_sci1_rxi_rom() -> Rom: data = bytearray([0xFF] * 0xFB88) data[0x00A2:0x00A4] = bytes([0xFB, 0x80]) data[0xFB80:0xFB88] = bytes( [ 0x20, 0x00, # DTMR: byte transfer, destination increments 0xFE, 0xDD, # DTSR: SCI1_RDR 0xFC, 0x00, # DTDR: receive buffer 0x00, 0x80, # DTCR: 128 transfers ], ) return Rom(bytes(data)) class DtcDecodeTest(unittest.TestCase): def test_decodes_manual_sci1_receive_register_information(self): vectors = read_dtc_vectors_min(_manual_sci1_rxi_rom()) entry = vectors[0x00A2] info = entry["register_info"] self.assertTrue(info["valid"]) self.assertEqual(entry["source"], "sci1_rxi") self.assertEqual(info["dtmr"], 0x2000) self.assertEqual(info["mode"]["size"], "byte") self.assertFalse(info["mode"]["source_increment"]) self.assertTrue(info["mode"]["destination_increment"]) self.assertEqual(info["source"]["address"], 0xFEDD) self.assertEqual(info["source"]["name"], "SCI1_RDR") self.assertEqual(info["destination"]["address"], 0xFC00) self.assertEqual(info["destination"]["region"], "on_chip_ram") self.assertEqual(info["count"]["transfers"], 128) self.assertEqual(info["count"]["bytes"], 128) def test_invalid_register_information_pointer_is_reported_conservatively(self): data = bytearray([0xFF] * 0x0200) data[0x00A2:0x00A4] = bytes([0xFB, 0x80]) vectors = read_dtc_vectors_min(Rom(bytes(data))) info = vectors[0x00A2]["register_info"] self.assertFalse(info["valid"]) self.assertIn("outside ROM image", info["error"]) def test_zero_count_represents_65536_transfers(self): data = bytearray([0xFF] * 0x0200) data[0x00C0:0x00C2] = bytes([0x01, 0x00]) data[0x0100:0x0108] = bytes([0xC0, 0x00, 0x01, 0x20, 0xFE, 0x80, 0x00, 0x00]) info = read_dtc_vectors_min(Rom(bytes(data)))[0x00C0]["register_info"] self.assertEqual(info["mode"]["size"], "word") self.assertEqual(info["mode"]["source_increment_step"], 2) self.assertEqual(info["count"]["transfers"], 65536) self.assertEqual(info["count"]["bytes"], 131072) self.assertTrue(info["count"]["zero_means_65536"]) def test_listing_and_json_include_decoded_register_information(self): rom = _manual_sci1_rxi_rom() dtc_vectors = read_dtc_vectors_min(rom) listing = format_listing( Path("rom.bin"), rom, {}, {}, {}, "min", traced=True, dtc_vectors=dtc_vectors, ) self.assertIn("; DTC Register Information", listing) self.assertIn("sci1_rxi", listing) self.assertIn("byte x128", listing) self.assertIn("SCI1_RDR (H'FEDD) -> H'FC00", listing) with tempfile.TemporaryDirectory() as tmpdir: path = Path(tmpdir) / "out.json" write_json(path, {}, {}, {}, dtc_vectors=dtc_vectors) payload = json.loads(path.read_text(encoding="utf-8")) json_info = payload["dtc_vectors"][0]["register_info"] self.assertEqual(json_info["mode"]["size"], "byte") self.assertEqual(json_info["source"]["name"], "SCI1_RDR") self.assertEqual(json_info["count"]["transfers"], 128) if __name__ == "__main__": unittest.main()