1984 · Progressive Peripherals & Software
Every byte of the C64's 64 KB, one pixel each, 512 to a row. Lit pixels are what this game is: its code, graphics, level data, sound, text, tables and variables, exactly where they sit in memory. Dim areas are screen and working memory; dark is unused.
| What | Bytes | Of 64 KB |
|---|---|---|
| Program | 45,560 | 69.5 % |
| Code | 28,075 | 42.8 % |
| Graphics | 10,919 | 16.7 % |
| Level data | 3,424 | 5.2 % |
| Sound | 90 | 0.1 % |
| Text | 353 | 0.5 % |
| Tables | 2,393 | 3.7 % |
| Variables | 306 | 0.5 % |
| Screen, bitmap, colour, stack, I/O | 11,640 | 17.8 % |
| ROM the game runs under | 8,192 | 12.5 % |
| Unused | 144 | 0.2 % |
| Tier | silver (claimed) |
|---|---|
| Coverage | 100 % of the bytes the game uses have a description |
| Build analysed | PP&S disk edition; supplied G64, 49 directory entries; WIZ boot |
| Copy | agent-draft |
| Tools | emulator: release v3.13.2, v3.13.2-linux-x86_64-gui.zip, disassembler: regenerator2000 0.9.20 (local copy of crates.io installation; stdio MCP), host: Linux x86_64, Ubuntu 24.04, no display |
| Model | gpt-6-astra |
| Kit version | 0.0.54 |
Sources read 2 October 2026:
| ID | Feature to check | Status | Evidence / question |
|---|---|---|---|
| F01 | Demonstration, play and construction choices | live | reference/program-menu.png; each choice appears in the supplied image |
| F02 | Four ten-level difficulty bands | traced | GAME $36AE / $3D85: bases 0,10,20,30; ten-level progression advances bands. |
| F03 | Customized levels and randomized Mystery mode | traced | GAME $36AE/$3831: Customized base40, Mystery bit7; editor accepts files 0–99. Player routes through custom files remain open. |
| F04 | Six players taking turns | differs; live | Five joystick changes select six players; reference/six-players.png. GAME $34EC wraps seven to one. Manual agrees; wiki says four. |
| F05 | Speeds 1–9 chosen while a level draws | differs; traced | Engine $90ED accepts digits0–9, broader than the documented 1–9. Default 5 at $80DA; GAME $2B19 computes the delay. |
| F06 | Walking and ducking | live; traced | Matched 12-frame control holds position; right moves X172→182. Down selects the duck path at $73B7 when descent is blocked; pose behavior traced. |
| F07 | Fire plus direction jumps | live | From the same snapshot, up+fire changes Y165→155; right+fire changes X172→182 and Y165→155. Engine $75EE/$7616/$763E. |
| F08 | Ropes and ladders have different lateral movement | traced; live; tested | Narrow rope glyphs $63/$64 differ from three-piece ladders $65/$66/$67. Original-code replays show catches, centering and one-pixel climbing; prepared emulator cases agree. |
| F09 | Falls can kill; jumps can catch ladders | traced; live; tested | Bounded falling at $7142–$7171; thirteen-pixel clear jump arc and rope/ladder interception at $770B. A prepared one-cell gap kills walking but permits a running jump. |
| F10 | Key opens exit and grants spells | live; traced | Forced key tile changes $C030 from 0 to 1 and restores charge digit 3. Exit checks the key flag at $7AD2. A checkpointed Burning Bridges route takes the key, enters the exit and reaches the next file load. |
| F11 | Treasures award points | live | Forced first-class treasure produces 50 points; original-code comparison covers all 16 class/difficulty combinations. $8464/$84D8. |
| F12 | Completion converts remaining bonus to score | traced; live; tested | GAME $3D96 adds50 per remaining bonus unit; setup gives 24 units, timer period is level-specific. 150 prepared original-code payouts and four live cases pass. Resuming the Burning Bridges exit checkpoint settles 2550+17×50=3400 and loads L18T. |
| F13 | Extra lives from score and ten-level completion | live; traced | Forced 9950+50 gives 10000 and lives6→7. GAME $3BA5 adds ten-level survival lives; $850A detects score-digit crossing. Prepared live milestones at bases0/30 confirm life additions, byte wrap and Expert→Mystery progression. |
| F14 | RUN/STOP pause; Q returns to menu | live; traced | RUN/STOP pause and resume captured in reference/paused.png and resumed.png. Q matrix code branches to $6400 at $96E1. |
| F15 | SPACE or down+fire casts; facing selects direction | traced | Engine $7185 accepts SPACE column pattern$EF and port 2 down+fire$0D; $765B debounces and spends a charge. Facing sets projectile direction. |
| F16 | Fireball, Magic Missile, Disintegrate and Enchantment kill on hit | traced; live; tested | All four use the same removal branch at $8C0F–$8C19, consistent with the manual. Original collision/hit matrix covers every actor type and slot; each spell also removes a forced queued target live. Tests isolate hit processing, not projectile reachability. |
| F17 | Freeze immobilizes enemies | live; tested | Queued spell 4 turns the target cyan. Original-code timelines verify 109/93/77/61 actor-update passes by difficulty and a shared countdown reset by later hits. $8C1C applies Freeze; $862E restores each original color. |
| F18 | Invisibility supplies protection against fatal events | traced; live; tested | GAME $2B6E/$3091/$30B3 gives 32 protected fatal reports, not 32 movement passes. Safe updates preserve it; red hazard death bypasses it. 84 interpreter cases plus live cast, safe controls, all 32 units and subsequent death. |
| F19 | Teleport, Feather Fall and Levitate change movement | traced; live; tested | GAME $30EE–$3127 and engine $7956/$794E/$7952. Teleport exchanges coordinates and nudges X two pixels; down/up travel moves two Y pixels per update until terrain ends it. Prepared original-code and emulator traces agree. |
| F20 | Haste and slow alter movement rates | traced | GAME $3128 halves delay plus1; $3132 slows actor horizontal velocity and lengthens delay below64. |
| F21 | Portals transport the player | traced | Engine $795A dispatches portal/question-mark/directional glyph effects; $79B3 exchanges saved/start coordinates. |
| F22 | Moving lifts, gates, pits and trapdoors | traced | Types7–12 have separate motion/stationary handlers; signed elevator velocity and leg duration read at $892A. |
| F23 | Ground enemies, flying enemies and aimed hazards | traced; tested | Editor DATA establishes type IDs; engine $860E dispatches ground, flying pursuit, random-axis, arrow and falling-rock controllers. Four movement replays compare 960 original-code states including terrain and sprite animation. |
| F24 | Thief collects treasure; cat eats rats on contact | traced; tested | Thief $7F7A invokes treasure callbacks. Cat follows the wizard via the shared ground controller $86BA; collision $7D45 removes a contacted rat. All thirty ordered slot pairs tested with five spell IDs, including Freeze. Cat is exempt from killing the wizard. |
| F25 | Cyan monsters are inactive | traced | Engine $862E recognizes color 3 and shared freeze phase; collision compares per-level exempt color at $7CFA. All40 supplied headers default that color to 3. |
| F26 | Treasure-triggered changes and hidden exits | traced; live; tested | $9477 applies 3×2 patches and then player/thief calls level code at $C376. Twenty levels have active callbacks. Simon Says rule checked in 4,096 original-code cases and four live callbacks; its automatic starting pearl and color patch replayed with neutral input. The atlas compares 700 pickup states; neutral-input traces establish hidden-thief operation in Friend or Foe? and Ladder Land. Burning Bridges has a completed checkpointed input route with Intermediate behavior and active hazards; other full room routes remain open. |
| F27 | Death animation, retries and player turns | traced; live; tested | Death motion $9526 plus GAME $2C7B/$388E; complete animation captured. Live $2DA3 cases confirm a surviving player retries; final-life loss advances to the next survivor. Completion also settles the account through $373D/$3831. Six accounts, dead-player skipping and wrap are tested. |
| F28 | Ten persistent scores, champion name and other initials | traced; live; tested | SCOR128-byte layout, GAME $419A insertion and $4745 save; initials entry $8FA6 and champion-name entry $8FB5, both timeout-enabled; the separate $8FC4 entry edits construction titles. A prepared 1000-point account passes original ranking, typed name/initials and SAVE with status0 on a disposable D64; all128 reloaded bytes match, including a separate disk extraction. The supplied disk is unchanged. Additional live six-player and top/bottom-tie records confirm name attribution can reclaim an existing equal score; all three saved records match disk extraction. Status0 alone is insufficient: the empty-drive test also returns zero. Full and write-protected disposable disks have real failure controls; a full disk with existing SCOR succeeds after scratching that record. Held FIRE exhausts three failed SAVE calls; a missing level exhausts four LOAD calls. |
| F29 | Commodore key clears scores during startup | live; tested | LODR $1117 compares port B with exactly $DF and clears $C100–$C14F. Naturally reached held/released keyboard cases verify eighty cleared bytes and preserved tail; all 256 port values tested. |
| F30 | Level drawing, movement and actions produce sound | traced; tested | SID writes across title, construction and gameplay. Five effect ports match the original routines write-for-write across60 test cases. |
| F31 | Construction edits terrain, player start and colors | live; traced | Construction loads level0 live. BLDR $35EC positions wizard, $43F6 edits colors, $49A6 edits terrain; separate reference/editor-source.txt. Seven prepared live portal placements verify that its upper-left and upper-middle cells can overwrite existing terrain; the other occupied footprint cells reject placement. |
| F32 | Construction chooses six monsters and separate appearance | traced | BLDR $36B8 selects six slots; $3906 behavior 0–20, $3A66 shape0–127, $3AB0 animation0–4. Behavior and appearance are separate fields. |
| F33 | Construction configures spells and saves/loads level files | traced; live | BLDR $3BE0 spell/charges, $33CF load and $4135 save. Live CTRL-S save and reload of L99T on a private blank disk verifies the $45EF elevator reset. A private game-disk copy is rejected when PPSS loads successfully; the supplied original is unchanged. |
| F34 | Level capacity, treasure and fire limits | traced | BLDR validates screen0–99 and maintains separate limits of16 treasures and 16 fires at $5088; map has 21 playable rows of40 cells with borders. |
work/external-reference/wiki-title.png: https://www.c64-wiki.com/images/c/c2/Wizard_Titelbild.png, external title reference, retrieved 2 October 2026.work/external-reference/wiki-level20.png: https://www.c64-wiki.com/images/1/11/WizardHighscoreMindless.png, external level-20 gameplay screenshot, retrieved 2 October 2026.Open rows describe what was searched and what remains unverified. Traced facts have source evidence; live facts also have an emulator observation. Forced-state tests establish a code response, not a player route.
Madhouse rotates 839 cells and skips the arrow at $C700; For Your Ice Only erodes its glyph on early indices too. work/audit_room_rules.js checks all forty callback entries and both treasure callers. The checks listed in facts.md also cover pickup deltas, actor motion, prepared movement and native register/boundary details; isolated fixtures do not establish full room routes.
The contributor supplied a G64 with the eight-byte GCR-1541 header, version 0 and 84 half-track entries (42 tracks). It is a disk image, not a frozen running game. SHA-256: 040b0615ab6dc3d741ee7bb85b59352a7c4c1a6fca0276672b9ab71ffa398c81.
The directory has 49 entries: WIZ, SCOR, LODR, CHRW, SPRW, M.L., GAME, BLDR, L00T through L39T, and PPSS. The PP&S introduction and credits appear; no trainer menu was observed. Work used a copy in work/wizard.g64, leaving the supplied original alone. The companion NBZ was retained privately but was not used to boot.
Measured on 2 October 2026: vice-mcp release v3.13.2, v3.13.2-linux-x86_64-gui.zip; regenerator2000 0.9.20. Linux x86_64 with a virtual display. This clone uses MCP ports 6511 and 3001, set in the ignored tools/mcp-ports.json, because other sessions use the defaults. The disassembler is served through the kit's stdio bridge. A fixture verified binary inspection, tracing, labels, comments and clean shutdown.
verify-footprint passed. The emulator check passed 54 of 57 cases, including exact stopping and stepping, persistent input, snapshot equality and equality after restart. The failed checks were watch-store, watch-load and warp: their fixed host-speed thresholds failed (39 watchpoint hits; warp 71 passes/s, normal 46/s). Nonzero counters and the precise frame tests worked. Game timing must therefore be measured in emulated frames or cycles, not host seconds. The startup liveness check was corrected to accept positive progress on a busy host.
python3 kit/scripts/tools.py vice. Hard-reset, resume execution, and call vice_autostart on the local G64 with program: "WIZ" and run: true. Leave the drive's processor enabled. This run used the bundled 1541-II drive ROM and PAL video.$19A3 reads 128 bytes from track 3, sector 3, XORing them into $7000–$707F, and the loop at $195C waits for the first byte to become $4C. True-drive reads in this run supplied only one of the two protected sector patterns. The direct vice_disk_read_sector call supplied the other.$195C. Check $FB before intervening: when it is 1, resume to the next hit without changing RAM. The loader rejects a first-attempt success at $1973–$1977; the fresh-boot check on 3 October 2026 succeeded on attempt 2. With $FB no longer 1, read $7000–$707F from RAM and the first 128 bytes returned by vice_disk_read_sector for unit 8, track 3, sector 3. XOR the two byte arrays. In this image their first bytes are $44 and $08; the result starts $4C,$9F,$8E and has $4C every third byte through offset 117, a valid jump table. Only when those checks pass, write the result to $7000. Remove the checkpoint and resume. Do not alter $FB, the program counter or the loader code. The loader then writes marker $FA to $99F0 at $1986 and to $58FF at $1989, observed with store watchpoints, and proceeds to the title. This applies the loader's own computation to bytes from the supplied disk; no engine instruction or disk file is patched.$0819, its SYS entry. When it stops, before executing the jump to $2245, save without ROMs. work/entry.vsf is the canonical disassembly and listing snapshot. It is an actual stopped machine after the disk loader, including the protection table already produced in RAM.Remove the entry checkpoint and resume. Choose Beginner, then one player, then press fire once more on the instruction to begin. Leave the number keys untouched for the default speed 5. The first level is Playground. Wait for the level to finish drawing and for the player to appear; turn WarpMode off. Stop between instructions with the kit's pause() and save work/play-round1.vsf. reference/playground.png shows that state. Port-2 right for 12 PAL frames moved sprite 7 from X=172 to X=182 while other objects advanced; reference/playground-moved.png records the response.
At entry $00/$01 = $2F/$37; the RAM IRQ vector is $7D6A and NMI vector $7D6F. In play the same banking remains, IRQ is $7CBF, and NMI remains $7D6F. The live PC was $8E62, inside the disk's machine-code image. These are observations, not a claim about an interrupt's rate.
In play $DD00=$C4 selects VIC bank $C000; $D018=$13 selects screen $C400 and charset $C800. The font matches CHRW byte-for-byte. SPRW loads from disk at $4000 and is relocated to $E000–$FFFF; 8190 of its 8192 bytes match the snapshot, with the two bytes at $FFFA/$FFFB changed to $FE43. This sprite RAM lies beneath the KERNAL ROM and must be included in analysis.
GAME occupies $0801–$4A88. M.L. occupies $5800–$9F6F. Comparing the canonical entry with Playground finds 307 changed bytes in GAME and four at $8AB7–$8ABA in M.L.; font and sprite RAM are identical. The entry image preserves the initialization values. The meaning of the changed ranges is established in facts and symbols, rather than presumed from the comparison.
Levels are separate L00T–L39T files. A gameplay snapshot contains one loaded level; the level format and the complete disk set must be checked separately. BLDR is a separate construction program, not simultaneously resident with GAME.
WIZ loads LODR, whose illustrated sequence loads the shared machine routines and graphics, relocates sprites under ROM, and combines the two protected sector patterns into the engine's jump table. Its title menu then loads GAME or BLDR into the low program area. The program begins through SYS 2073 and a jump at $0819. The protection assist above is the only intervention before that hand-over; the loader is not the subject of the annotation pass.
A hard reset and WIZ autostart from a disposable copy of the supplied G64, using the guarded assist above, reached GAME through the program menu. All 45,560 listed resident bytes at the fresh $0819 stop matched the canonical listing. Joystick selection of Beginner and one player reached Playground through its normal load/setup, with wizard (172,165), six lives in all six account slots, and the documented banking and interrupt vectors. This establishes the assisted boot recipe; it is not a claim that the protected image booted without assistance.
The symbol map for this game is symbols.json; the listing behind the Source tab is listing.json. Write-ups, facts and symbol maps are CC BY-SA 4.0. The game itself is not hosted here.