39 lines
1.5 KiB
Python
39 lines
1.5 KiB
Python
#!/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))
|