108 lines
3.0 KiB
Python
108 lines
3.0 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import TypedDict
|
|
|
|
from .dtc import DtcRegisterInfo, decode_dtc_register_info
|
|
from .rom import Rom
|
|
from .tables import VECTOR_NAMES_MIN
|
|
|
|
|
|
class DtcVectorEntry(TypedDict):
|
|
vector_address: int
|
|
source: str
|
|
register_info_address: int
|
|
target: int
|
|
register_info: DtcRegisterInfo
|
|
|
|
|
|
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(rom: Rom, vector_address: int, source: str, target: int) -> DtcVectorEntry:
|
|
return {
|
|
"vector_address": vector_address,
|
|
"source": source,
|
|
"register_info_address": target,
|
|
"target": target,
|
|
"register_info": decode_dtc_register_info(rom, 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(rom, 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(rom, addr, source, target)
|
|
return vectors
|