Files
vt1200/tools/vt1200_map.py

61 lines
2.2 KiB
Python

#!/usr/bin/env python3
"""Inspect an *address-ordered* VT1200 ROM image.
Expects the image produced by ``reconstruct.py`` in the default (linear) mode,
where file offset == physical byte - 0x07E40000. Reports the reset vector, the
interrupt vector page and each bank header checksum.
Usage:
python3 vt1200_map.py vt1200_v22.bin
"""
import struct
import sys
ROM_BASE = 0x07E40000
BANK = 0x40000 # 256 KiB per EPROM pair
N_BANKS = 7
VECTOR_PAGE = 0x80 # 32 x 32-bit entries at the top of the image
def main(path):
d = open(path, "rb").read()
n = len(d)
print(f"image : {path} ({n} bytes = 0x{n:X})")
print(f"load base : byte 0x{ROM_BASE:08X} bit 0x{ROM_BASE << 3:08X}")
print(f"top byte : 0x{ROM_BASE + n - 1:08X} bit 0x{(ROM_BASE + n - 1) << 3:08X}")
# --- reset vector: last entry of the vector page ---
rv = struct.unpack_from("<I", d, n - 4)[0]
tgt = rv >> 3
off = tgt - ROM_BASE
where = f"file 0x{off:06X}" if 0 <= off < n else "OUT OF RANGE"
print(f"\nreset vector: 0x{rv:08X} -> byte 0x{tgt:08X} ({where})")
print(f" [8:16] = {d[8:16].hex(' ')}")
# --- interrupt vector page (last 128 bytes) ---
print(f"\nvector page @ file 0x{n - VECTOR_PAGE:06X} "
f"(logical bit 0xFFFFFC00..0xFFFFFFFF):")
base = n - VECTOR_PAGE
for k in range(VECTOR_PAGE // 4):
v = struct.unpack_from("<I", d, base + 4 * k)[0]
o = (v >> 3) - ROM_BASE
tag = f"-> file 0x{o:06X}" if 0 <= o < n else f"(0x{v:08X})"
print(f" vec{k:2d} = 0x{v:08X} {tag}")
# --- per-bank header: [checksum16][?][0xAAAA][0x5555] ---
print("\nbank headers (h0 = 16-bit word sum from the magic word to bank end):")
for b in range(N_BANKS):
off = b * BANK
h0, h1 = struct.unpack_from("<HH", d, off)
words = struct.unpack_from(f"<{(BANK - 4) // 2}H", d, off + 4)
s = sum(words) & 0xFFFF
print(f" bank {b} byte 0x{ROM_BASE + off:08X}"
f" hdr=0x{h0:04X} 0x{h1:04X} aaaa 5555"
f" sum=0x{s:04X} checksum_ok={s == h0}")
if __name__ == "__main__":
if len(sys.argv) != 2:
raise SystemExit(__doc__)
main(sys.argv[1])