from __future__ import annotations from typing import TypedDict from .rom import Rom from .tables import VECTOR_NAMES_MIN class DtcVectorEntry(TypedDict): vector_address: int source: str register_info_address: int target: int DTC_VECTOR_NAMES_MIN: dict[int, str] = { 0x00C0: "irq0", 0x00C2: "interval_timer", 0x00C8: "irq1", 0x00D0: "irq2", 0x00D2: "irq3", 0x00D8: "irq4", 0x00DA: "irq5", 0x00E0: "frt1_ici", 0x00E2: "frt1_ocia", 0x00E4: "frt1_ocib", 0x00E8: "frt2_ici", 0x00EA: "frt2_ocia", 0x00EC: "frt2_ocib", 0x00F0: "frt3_ici", 0x00F2: "frt3_ocia", 0x00F4: "frt3_ocib", 0x00F8: "tmr_cmia", 0x00FA: "tmr_cmib", 0x00A2: "sci1_rxi", 0x00A4: "sci1_txi", 0x00AA: "sci2_rxi", 0x00AC: "sci2_txi", 0x00B0: "ad_adi", } DTC_VECTOR_NAMES_MAX: dict[int, str] = { min_addr * 2: name for min_addr, name in DTC_VECTOR_NAMES_MIN.items() } def read_vectors_min(rom: Rom) -> dict[int, tuple[str, int]]: vectors: dict[int, tuple[str, int]] = {} for addr in range(0x0000, 0x009A, 2): if not rom.contains(addr, 2): break target = rom.u16(addr) if target in (0x0000, 0xFFFF): continue name = VECTOR_NAMES_MIN.get(addr, f"vector_{addr:04X}") vectors[addr] = (name, target) return vectors def read_vectors_max(rom: Rom) -> dict[int, tuple[str, int]]: vectors: dict[int, tuple[str, int]] = {} for addr in range(0x0000, 0x0134, 4): if not rom.contains(addr, 4): break page = rom.u8(addr + 1) pc = rom.u16(addr + 2) if pc in (0x0000, 0xFFFF) or page != 0: continue name = VECTOR_NAMES_MIN.get(addr // 2, f"vector_{addr:04X}") vectors[addr] = (name, pc) return vectors def _dtc_entry(vector_address: int, source: str, target: int) -> DtcVectorEntry: return { "vector_address": vector_address, "source": source, "register_info_address": target, "target": target, } def read_dtc_vectors_min(rom: Rom) -> dict[int, DtcVectorEntry]: vectors: dict[int, DtcVectorEntry] = {} for addr, source in sorted(DTC_VECTOR_NAMES_MIN.items()): if not rom.contains(addr, 2): continue target = rom.u16(addr) if target in (0x0000, 0xFFFF): continue vectors[addr] = _dtc_entry(addr, source, target) return vectors def read_dtc_vectors_max(rom: Rom) -> dict[int, DtcVectorEntry]: vectors: dict[int, DtcVectorEntry] = {} for addr, source in sorted(DTC_VECTOR_NAMES_MAX.items()): if not rom.contains(addr, 4): continue target = rom.u16(addr + 2) if target in (0x0000, 0xFFFF): continue vectors[addr] = _dtc_entry(addr, source, target) return vectors