#!/usr/bin/env python3 # buildImage.py - replay the boot loader ($C145) on the decrypted sectors to produce the exact # 64K memory image that exists when control reaches the game entry at $0800. import 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() mem = bytearray(65536) origin = [None]*256 # per page provenance loadPrg = open("files/load.prg", "rb").read() lo, hi = loadPrg[0], loadPrg[1] body = loadPrg[2:] mem[0x9800:0x9800+len(body)] = body for p in range(0x98, 0xC4): origin[p] = f"load.prg@{p:02X}00" def loadRun(dest, track, firstSector, count, note): for i in range(count): s = firstSector + i mem[dest:dest+0x100] = sec(track, s) origin[dest >> 8] = f"T{track:02d}S{s:02d}" dest += 0x100 # $C23F: colour RAM <- $9800-$9BFF ; $8C00-$8FFF <- $9C00-$9FFF colorRam = bytes(mem[0x9800:0x9C00]) mem[0x8C00:0x9000] = mem[0x9C00:0xA000] for p in range(0x8C, 0x90): origin[p] = f"copy of load.prg@{p+0x10:02X}00" # main sequence ($C190..) for t in range(22, 28): loadRun(0x0800 + (t-22)*18*0x100, t, 0, 18, "main") mem[0x0400:0x0800] = mem[0x6F00:0x7300] # $C1B3 copy loop for p in range(4, 8): origin[p] = f"copy of {origin[p+0x6B]} (via $6F00)" loadRun(0x6F00, 33, 0, 17, "") loadRun(0x8000, 32, 8, 8, "") loadRun(0x9300, 28, 0, 13, "") loadRun(0xFA00, 29, 11, 5, "") # $C1FE: move 16 pages from $xx1A -> $xx1A+$1B8, top page first ($FD1A..$FE19 -> $FED2..$FFD1) for i in range(16): srcHi = 0xFD - i dstHi = 0xFE - i for y in range(256): mem[(dstHi << 8) + ((0xD2 + y) & 0xFF) + (0x100 if 0xD2 + y > 0xFF else 0)] = mem[(srcHi << 8) + ((0x1A + y) & 0xFF) + (0x100 if 0x1A + y > 0xFF else 0)] for p in range(0xFB, 0x100): origin[p] = "T29S11-15 moved up $1B8 (garbage below $FBB8)" open("bootImage.bin", "wb").write(mem) open("bootImage_colorRam.bin", "wb").write(colorRam) json.dump({f"{p:02X}00": o for p, o in enumerate(origin) if o}, open("bootImage_origin.json", "w"), indent=1) # verify against VICE ram = open("vice/ram_at_0800.bin", "rb").read() diffs = [(a, mem[a], ram[a]) for a in range(0x0400, 0xA000) if mem[a] != ram[a]] print("diffs $0400-$9FFF vs VICE:", [(f"${a:04X}", f"{m:02X}", f"{r:02X}") for a, m, r in diffs]) diffs = [(a, mem[a], ram[a]) for a in range(0xA000, 0xC400) if mem[a] != ram[a]] print("diffs $A000-$C3FF:", [(f"${a:04X}", f"{m:02X}", f"{r:02X}") for a, m, r in diffs]) diffs = [(a, mem[a], ram[a]) for a in range(0xFBB8, 0xFFD2) if mem[a] != ram[a]] print("diffs $FBB8-$FFD1:", [(f"${a:04X}", f"{m:02X}", f"{r:02X}") for a, m, r in diffs][:10])