#!/usr/bin/env python3
# buildOverlays.py - assemble each runtime-loaded overlay (from the decrypted sectors) into a binary
# at its load address, and build two full "runtime" images (mode A / mode B) for analysis.
import os, json
SPT = [21]*17 + [19]*7 + [18]*6 + [17]*5
def sec(t, s): return open(f"decrypted/t{t:02d}s{s:02d}.bin", "rb").read()
def run(t, s0, n): return b"".join(sec(t, s0+i) for i in range(n))

os.makedirs("overlays", exist_ok=True)
OVERLAYS = {
  # name: (loadAddr, [(track, firstSector, count), ...], description)
  "ovl_C000_T30":      (0xC000, [(30,0,16)],  "runtime $C000-$CFFF: replaces boot loader (T30 S0-15)"),
  "ovl_6F00_A_T31T32": (0x6F00, [(31,0,17),(32,0,8)], "variant A $6F00-$87FF (T31 S0-16 + T32 S0-7)"),
  "ovl_6F00_B_T33T32": (0x6F00, [(33,0,17),(32,8,8)], "variant B $6F00-$87FF (T33 S0-16 + T32 S8-15) [boot default]"),
  "ovl_8800_T29":      (0x8800, [(29,9,2)],   "$8800-$89FF (T29 S9-10)"),
  "ovl_E000_1_T35":    (0xE000, [(35,0,12)],  "variant 1 $E000-$EBFF (T35 S0-11) [when $0BA5 bit7 set]"),
  "ovl_E000_2_T18T34": (0xE000, [(18,7,1),(34,1,11)], "variant 2 $E000-$EBFF (T18 S7 + T34 S1-11)"),
  "ovl_EC00_1_T34":    (0xEC00, [(34,12,4)],  "variant 1 $EC00-$EFFF (T34 S12-15) [paired with $0BA5 bit7 set]"),
  "ovl_EC00_2_T35":    (0xEC00, [(35,12,4)],  "variant 2 $EC00-$EFFF (T35 S12-15)"),
  "ovl_F000_T18":      (0xF000, [(18,8,7)],   "$F000-$F6FF (T18 S8-14)"),
  "ovl_0200_T18":      (0x0200, [(18,15,2)],  "$0200-$03FF (T18 S15-16)"),
}
meta = {}
for name, (addr, runs, desc) in OVERLAYS.items():
    data = b"".join(run(*r) for r in runs)
    open(f"overlays/{name}.bin", "wb").write(data)
    meta[name] = {"load": f"${addr:04X}", "end": f"${addr+len(data)-1:04X}", "sectors": runs, "desc": desc}
json.dump(meta, open("overlays/overlays.json", "w"), indent=1)

boot = bytearray(open("bootImage.bin", "rb").read())
def apply(img, name):
    addr = int(meta[name]["load"][1:], 16)
    d = open(f"overlays/{name}.bin", "rb").read()
    img[addr:addr+len(d)] = d
for variant, names in {"A": ["ovl_C000_T30","ovl_6F00_A_T31T32","ovl_8800_T29","ovl_E000_2_T18T34","ovl_EC00_2_T35","ovl_F000_T18","ovl_0200_T18"],
                       "B": ["ovl_C000_T30","ovl_6F00_B_T33T32","ovl_8800_T29","ovl_E000_1_T35","ovl_EC00_1_T34","ovl_F000_T18","ovl_0200_T18"]}.items():
    img = bytearray(boot)
    for n in names: apply(img, n)
    open(f"runtimeImage_{variant}.bin", "wb").write(img)
for n, m in meta.items(): print(f"{n:22s} {m['load']}-{m['end']}  {m['desc']}")
