from __future__ import annotations from .formatting import h16 class DecodeError(Exception): pass class Rom: def __init__(self, data: bytes, base: int = 0) -> None: self.data = data self.base = base @property def end(self) -> int: return self.base + len(self.data) def offset(self, address: int) -> int: return address - self.base def contains(self, address: int, size: int = 1) -> bool: off = self.offset(address) return 0 <= off and off + size <= len(self.data) def u8(self, address: int) -> int: if not self.contains(address): raise DecodeError(f"address out of ROM: {h16(address)}") return self.data[self.offset(address)] def u16(self, address: int) -> int: if not self.contains(address, 2): raise DecodeError(f"word out of ROM: {h16(address)}") off = self.offset(address) return (self.data[off] << 8) | self.data[off + 1] def slice(self, address: int, size: int) -> bytes: if not self.contains(address, size): raise DecodeError(f"range out of ROM: {h16(address)}+{size}") off = self.offset(address) return self.data[off : off + size]