1
0
Files
h8-536-decoder/tests/test_dtc.py
2026-05-25 14:22:32 +10:00

104 lines
3.6 KiB
Python

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()