1988 · Systems Editoriale (Commodore 64 Club)
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 | 42,982 | 65.6 % |
| Code | 30,550 | 46.6 % |
| Graphics | 5,163 | 7.9 % |
| Level data | 1 | 0.0 % |
| Sound | 4,050 | 6.2 % |
| Text | 1,083 | 1.7 % |
| Tables | 1,936 | 3.0 % |
| Variables | 199 | 0.3 % |
| Screen, bitmap, colour, stack, I/O | 13,312 | 20.3 % |
| ROM the game runs under | 8,192 | 12.5 % |
| Unused | 1,050 | 1.6 % |
| Tier | silver |
|---|---|
| Coverage | 100 % of the bytes the game uses have a description |
| Build analysed | Commodore 64 Club issue 14, disk side B (a freezer backup of the title screen) |
| Copy | agent-draft |
| Tools | host: Linux 6.8 x86_64, Ubuntu 24.04 desktop with sixteen cores; the emulator ran under xvfb-run (no display in the agent's shell), emulator: VICE, release v3.13.1, v3.13.1-linux-x86_64-gui.zip, MCP on port 6511 (KIT_VICE_PORT); 6512 for the comparison of versions on 4 October 2026, disassembler: regenerator2000 0.9.20, python: 3.12.3, node: 20.19.5, subagents: nine annotation agents on disjoint address ranges and one page verifier, all claude-opus-5-5; one research agent for the web sources only, on the Agent tool's `sonnet` alias, exact model id not stated, widget tests: node 20.19.5: the title tune's port checked against the game's player in kit/c64/cpu6502.js, write by write (work/music-test.js); the point adders run in the simulator (work/scoretest.js), browser check: Chromium headless shell 1243 (Playwright's cache), a full-page screenshot of the built page |
| Model | claude-opus-5-5 |
| Kit version | 0.0.46 |
Read this before annotating code. What the game is documented to do, with verification status against the binary. Statuses: open (documented, not found yet), traced (in the code, could not be exercised; say what was tried), confirmed (in the code, consistent with the emulator), live (observed directly), differs (the code does something else). "Absent" is not a status.
Sources, all read on 30 September 2026 (work/research.md has the notes, source by source). No C64-Wiki page exists for the game (English and German both 404), and no manual beyond the magazine's blurb was found.
work/web-reference/, not published: they are other people's), two comments.| Feature | Status | Where |
|---|---|---|
| Joystick in port 2 | live | the title waits for $DC00 = $6F at $1770; every room loop reads $DC00 |
| Fire on the title starts the game | live | $1770-$1788 |
| Title screen "SYSTEMS PRESENTS A NEW GAME WITH": Mr Hat, Octopus, Snaily, Dynky (so spelt), Kniffy, "and all others" | live | $B683 draws it from the screen codes at $C000-$C058; reference/title.png |
| Title music | confirmed | the player $C080-$C373 from the title's interrupt $C0AF; register activity seen, no sound in the session |
| Walk left and right | live | $5340/$5370 and each room's copies, about 2.4 pixels a frame |
| Fire jumps, the way Mr Hat faces | live | from standing in room 1, fire held: sprite Y 204 to 183, 13 frames, back, again while held; $DC00 = $6F at $438D and in every room loop but room 10's (a ladder loop); three phases of 21 steps |
| Stick up | live | does nothing on a floor (20 frames held in room 1); climbs ladders and rides lifts ($4B20, $4000, $8265) |
| Stick down: crouch, climb down, take a treasure | traced | $7D compared in the room loops and in $8E10, $B100-$B4BB; not tried live |
| Touching a guardian kills ("everything you touch kills you", Lemon64) | live | in room 1, Mr Hat sank into the floor and restarted at the room's entry (reference/death.png, reference/room01-respawn.png); $D01E read as exact values at $55B0, death $A877 |
| Deadly spots in the rooms | traced | $BB10, by position and exact standing height; room 6's dark-only hazard |
| Lives, four marks at the bottom right | live | $07B9, $07BA, $07E1, $07E2: one recoloured to $CC per death (by the code, two for a death in room 3; not tried); after five deaths in room 1 the title came back |
| Game over | live | after the last life $4475 returns to the title, which waits for fire for a new game; there is no game-over screen of its own |
| After a game over, the title's I is broken | live | the title set-up $CDC0 copies the font again from $CE00, whose $CE48-$CE55 are damaged in the image; the I in "WITH", "SNAILY" and "KNIFFY", and in the end message, shows noise in its top half (reference/title-after-game-over.png, reference/end-screen.png); botowrap's fixed version puts the bytes back (facts.md, "Versions") |
| Status line: SCORE, ROOM, STAGE | live | bitmap rows 23-24, glyphs at $1600; reference/stage1-room1.png |
| Score in thousands | live | $41DA/$8AD0 step the thousands digit; the 1,000, 10,000, 25,000 and 75,000 adders run in the simulator gave exactly those scores (work/scoretest.js); the 20,000 and 50,000 adders by the code |
| Eleven rooms in four stages (web screenshots reach ROOM 10, STAGE 4) | live | rooms 1-11 drawn by starting each set-up (reference/room02-setup.png to room11-setup.png); stage 1 room 1, stage 2 rooms 2-5, stage 3 rooms 6-9, stage 4 rooms 10-11 (rooms 4 and 7 keep the STAGE digit of the room before, so started from room 1 they show STAGE 1) |
| Room 1: three floors and a LIFT | traced | the lift ride $4000 moves Mr Hat and sprite 5 56 pixels a floor; not ridden live |
| Ladders | traced | $4B20; rooms 2, 3, 5, 6, 9, 10, 11, and room 8's shaft |
| Guardians: Octopus, Snaily, Dinky, Kniffy and others | live | they move in room 1 (sprites 0, 1, 7); each room's IRQ moves its own (facts.md, "Guardians") |
| Treasures worth points | traced | $8E10, $B100-$B4BB: 10,000 to 75,000 each, taken with the stick down |
| Keys and doors (Lupenio's text: "each key opens one door and one only") | traced | room 9's two doors, which test for the objects carried from rooms 6 and 8, can never open: their fills were patched out (facts.md, "Leftovers") |
| Colour-coded switches opening barriers in other rooms | traced | $B2E0-$B4BB, five switch and barrier pairs (facts.md, "Barriers and switches") |
| The candle lights the dark rooms | live | rooms 6 and 9 dark with $22 = 0, lit with $22 = $40 (reference/room06-lit-setup.png, room09-lit-setup.png); $5519 sets it when room 2's candle is taken (traced) |
| Immunity | traced | the objects of rooms 3 and 7 call $1250, which writes RTS over the death $A877 and the life loss $4C52 until $100F reaches $FE |
| The Golden Hat, the goal, and the end | live | drawn in room 11 ($7C00, $7C50); $7CC0, with Mr Hat level with it on the bottom floor, anywhere left of X $80, shows "WONDERFUL / YOU HAVE FINISHED YOUR MISSION" ($BFA8, $B7D8) and starts a new game. Seen live (reference/end-screen.png, work/room11win.py), with Mr Hat placed on that floor carrying nothing. By design the way needs room 5's object to open a block; in this copy that object cannot be taken (tried live), and the block is open from the start because its fill was patched out (facts.md, "The end") |
| RUN/STOP | traced | the game never calls the KERNAL's STOP; the vector at $0328 holds the KERNAL default $F6ED in every game snapshot. The tape's loader writes $E1 to $0328 ($A220), but the freezer's restore puts the saved value back |
Found in the code, not in the manual.
$7C70, $1019), live. It does not pause the game.$8C00), besides the title tune, and a second tune at $89D0 that nothing plays; both ported and checked against the game's code, write for write.$97ED-$9FFF, never called: the source of the image's calls to CHRIN. The game itself calls CHROUT at seven places ($926B, $B68A, $B68F, $B700, $BFAA, $BFAF, $CDE6).$7D70, $8000).$1020: it reads $400B (a code operand, always $FC) where it wrote $40BB, so the X high-bit check in $A97C never runs; 19 spots whose callers have chosen the left half work only because of it.$18B3 (STA $2BF8 where its twin at $916A has STA $35D8,Y): only part of that drawing is done.$D022, invisible in hires bitmap mode, several where a colour store or a call was switched off.$D022, and who damaged the title font? Both are in the image Commodore 64 Club issue 14 shipped, a freezer backup. Issue 6's copy, the first printing, compared byte for byte would tell whether they were already there.How to get from the contributor's own copy to the analysed state. Someone else must be able to follow this exactly.
mr hat (original).D64 (174,848 bytes, a 35-track disk without error bytes; SHA-256 49d5f88c98dff47d0a18055f3072a62c773499d51a2f0ec7b1d8c9e41d314d61, MD5 7059c4b03ecfe42cf2db70eb72c79c96), the contributor's own copy, in work/original.d64. The disk is named COMMODORE CLUB, ID 64, and its directory holds seven programs: three loaders of 5 blocks, MR HAT, HAWK MISSION and DALTO, the 7-block SPRITE SCANNER, and the three games they load, HM (189 blocks), MH (114) and DA (109). That is the side B of Commodore 64 Club issue 14 that the German C64-Wiki lists (read 4 October 2026: "Seite B: Mr Hat, Hawk Mission, Dalto, Sprite Scanner"), the magazine's second printing of the game; issue 6, the first (September 1988), was a disk with a COVER menu and other programs, and no copy of it was examined.
MR HAT loads at $0801 (1,253 bytes, SYS 3223). It blacks out the screen, installs a fast loader (drive code kept under the I/O area at $D000, the KERNAL's LOAD vector $0330 pointed at $0144), prints "MH",8: at the top of the screen behind four spaces, and puts HOME and shifted RUN/STOP ($13, $83) in the keyboard buffer: back at BASIC, the cursor goes home, shifted RUN/STOP types LOAD over the spaces with a RETURN and then RUN. The three loaders are the same file but for the two letters of the name ($0CCA-$0CCB).
MH loads at $0801-$78F9 (28,921 bytes); its BASIC line is 1001 SYS2066. It is a freezer backup (kit/skills/c64/c64-reference, "Freezer-cartridge backups"): a packed image of the running game, saved while it sat on its title screen and repacked with a depacker of its own. So the magazine shipped the game as a frozen image. The original program is still inside it: at $0801 the unpacked image holds the game's own BASIC line, 10 SYS 2157 followed by the text SYSTEM EDITOR<<<E **, and SYS 2157 is $086D, the game's entry (below). Who froze it is unknown; no intro, trainer or credit appears on screen. DA starts with the same depacker (its first 43 bytes are MH's), HM with another.
The analysis was first made from mrhat.t64 (29,017 bytes, SHA-256 1825d07c0490dd00191599178e403336a0048749c751a45bbe1599ab0c5f875b), a T64 tape archive that the contributor took from the GameBase collection, whose name field reads ASS PRESENTS:. Its one program, MR. HAT, is MH byte for byte, and the two give the same memory: started from the disk and stopped at $1773, the machine's RAM equals handover.vsf's in all 65,536 bytes, so the listing, built from that snapshot, is the disk's. Everything below holds for both.
vice_machine_reset, mode: hard), resume it, and wait for READY..vice_autostart work/original.d64 (the first program, MR HAT; the directory's first entry is an empty separator). The loader runs, LOAD "MH",8 and RUN follow by themselves, and the depacker starts. Autostart turns warp mode on; turn it off (vice_machine_config_set, WarpMode 0). work/mrhat.t64 gives the same machine: VICE loads the tape file through its traps and types RUN.$1770 for $DC00 to read exactly $6F (fire alone). Room 1 of stage 1 appears at once, in bitmap mode, with SCORE, ROOM and STAGE on the bottom line and a LIFE panel on the right. The stick moves Mr Hat (hardware sprite 4) along the bottom floor.work/versions/bootcmp.py does steps 1 and 2 for any of the three copies and stops at the game's first instruction ($1773 for the disk and the tape, $086D for botowrap's fixed version, which starts cold); work/boot.py is the tape's. Snapshots in work/, each saved without ROMs:
| File | State |
|---|---|
handover.vsf | a stopping checkpoint on $1770-$1776 after the freezer's resume, from a power-cycled machine: the game's first instruction, $1773, with the stack it was frozen with. The disassembler and the listing are built from this one. |
restart-title.vsf | despite its name, not a restart: a stop at $1773 that never passed the title set-up $CDC0 (a real restart copies the damaged font to $2848; here $2848 is clean), differing from handover.vsf only in $00A2 and $C438, two counters |
versions/d64-restart.vsf | the real restart: the disk's machine, PC set to $086D and SP to $F6, stopped again at $1773 after the title set-up ran; differs from handover.vsf in $2848-$2855 (the damaged font, copied) and $C436 (a music counter) only, outside zero page, the stack and the RAM under I/O |
versions/d64-entry.vsf | the same stop, reached from the disk: identical to handover.vsf in all 65,536 bytes of RAM |
title.vsf | the title screen, running |
play-room1.vsf | room 1 of stage 1, a second of play |
entry.vsf, entry2.vsf, resume.vsf | the depacker at $0690, the freezer restore at $0948, and the first IRQ after the resume; for the loader only |
The emulator was vice-mcp v3.13.1 (release zip, Linux x86_64, under xvfb-run), PAL, 6581 SID. check-emulator on 30 September 2026: 56 of 57 passed; warp failed (78 passes a second in warp against 51 at normal speed, where the check wants over 100). Nothing below depends on warp.
The game keeps the KERNAL and I/O banked in: $01 reads $36 in the title and in play (RAM at $A000-$BFFF, I/O at $D000, KERNAL at $E000), and it hooks the KERNAL's IRQ vector. On the title $0314 holds $C0AF (the music), in play $1C00, which jumps to $AAB2. The RAM copies of the hardware vectors at $FFFA-$FFFF are zero, which is harmless with the KERNAL banked in. The video chip uses bank 0 ($DD00 = $C7): on the title, text mode with the screen at $0400 and characters at $2800 ($D018 = $1B); in play, bitmap mode ($D011 = $3B) with the bitmap at $2000 and colours at $0400.
Compared byte for byte with handover.vsf, play-room1.vsf differs in the screen ($0400-$07FF), the bitmap and the title's character set ($2000-$3F4A, redrawn by the room), zero page, the stack, and a few scattered variables ($100C, $1371-$1383, $1C12, $1E06, $41DD-$4261, $4ACD, $64F0-$64F9, $8C58-$8C64, $C434-$C438). The program is not reloaded: the game is one file, and no JSR or JMP to the KERNAL's LOAD ($FFD5), SETLFS or SETNAM is in the image. Because play overwrites the title's character set, the hand-over is the image to read, not a play snapshot.
No page of handover.vsf holds VICE's $00/$FF power-up pattern. The all-zero ranges are $2000-$27FF and $2A00-$3EFF (the bitmap, filled by play), $A000-$A0FF, and $D100-$FFFF, which lies under I/O and the KERNAL. A restart from $086D (versions/d64-restart.vsf) rebuilt the same memory but for the font's copy and a music counter, so the freezer lost nothing the start-up needs; whether it lost anything the game reads later is checked with store and execute checkpoints on those ranges during play (features.md).
SYS 2066 runs $0812, which copies a depacker to $00FA-$01A0 and $0334-$03D9 and runs it, unpacking the image upwards from $0801 to $A231. A stub at $A220 sets the STOP vector's low byte ($0328 = $E1, so RUN/STOP is ignored), prints CHR$(142) and CHR$(8) (upper case, case switch locked) and jumps to $081B, a second depacker that banks everything to RAM ($01 = $34) and runs a byte-stream decoder in zero page ($0008-$00B4, bytes XORed with $12). The stream calls out to $0690 (in what becomes screen memory), which checks two marker bytes on the stack and goes on to $0948: the freezer's restore. It copies $0200-$05FF into colour RAM, $0607-$0635 into the VIC registers, $0637-$0653 into the SID and $0660-$067F into the two CIAs, restarts the decoder for the rest of memory, and ends in a routine on the stack page ($01C4-$01EA) that copies zero page back from the RAM under the I/O area, sets $00 = $2F and $01 = $36, and returns with RTI to $1773 with A = $7F, X = $50. The game resumes in its title's fire loop, called from $16EE in the title routine $16A3, which $0876 calls from the entry $086D, which BASIC's SYS called.
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.