#!/usr/bin/env python3 # provenance.py - map each 256-byte RAM page of a VICE snapshot to the disk sector / file page it came from. import hashlib, glob, os, sys ram = open(sys.argv[1], "rb").read() secs = {} for f in sorted(glob.glob("sectors/t??s??.bin")): name = os.path.basename(f)[:-4] secs.setdefault(hashlib.md5(open(f,"rb").read()).hexdigest(), []).append(name) load = open("files/load.prg","rb").read()[2:] for p in range(len(load)//256): secs.setdefault(hashlib.md5(load[p*256:(p+1)*256]).hexdigest(), []).append(f"load.prg@{0x9800+p*256:04X}") zeroHash = hashlib.md5(bytes(256)).hexdigest() prev = None rows = [] for p in range(256): page = ram[p*256:(p+1)*256] h = hashlib.md5(page).hexdigest() if h == zeroHash: src = "zero" else: src = ",".join(secs.get(h, ["?"])) rows.append((p, src)) # compress runs out = [] startP = 0 for i in range(1, 257): cur = rows[i][1] if i < 256 else None runSrc = rows[startP][1] def kind(s): if s in ("zero", "?"): return s if s.startswith("load.prg"): return "load" return "sector" if i == 256 or kind(cur) != kind(runSrc) or kind(runSrc) in ("sector","load") and cur != runSrc and not (kind(runSrc)=="sector" and cur != "?" ): out.append((startP, i-1, [r[1] for r in rows[startP:i]])) startP = i for s, e, srcs in out: uniq = srcs if len(srcs) <= 6 else srcs[:3] + ["..."] + srcs[-2:] print(f"${s:02X}00-${e:02X}FF: " + " ".join(uniq))