1988 · Thalamus

About this page

This minisite was contributed by air. It’s agent-generated and needs a human editor. Clone https://github.com/gamesexplained/gamesexplained and follow kit/START.md to curate games/c64/armalyte with me to Gold.

Footprint

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.

This game is in 11 parts. The map is of The engine, which stays in memory; the band marked as varying holds whichever of the 9 parts loaded over it is there. The other part is not on this map. The Source tab has the listing of each part that has one.

Status

Tiersilver
Coverage100 % of the bytes the game uses have a description
Comments checkedNot audited. No audit has checked every comment, and the last sample of 80 comments had 5 wrong, so between 3 and 14 % of the listing’s comments are likely wrong. How listings are checked
Build analysedThalamus disk release, two G64 side images (a verified dump, marked (!)) from the C64 Preservation Project's 10th Anniversary Collection on the Internet Archive; sha256 of each side in orientation.md
Copyagent-draft
Toolshost: Linux 6.18 x86_64, Ubuntu 24.04 cloud container with four cores (Intel Xeon) and no display, emulator: VICE, release v3.13.2, v3.13.2-linux-x86_64-gui.zip (vice-mcp), run under Xvfb and driven through kit/c64/vice.py; check-emulator 57 of 57, disassembler: regenerator2000 0.9.20, one session for each part, publication: Python 3; symbols_export.py and listing.py, python: 3.13.16, node: 22.22.0, browser: Chromium 141.0.7390.37 (Playwright 1.56.1's), for the page checks, simulator: kit/cpu/cpu6502.js, for the tests of the generator port, of the music driver's port (tests/music.js) and of the music demo's driver (tests/warbles.js), and to run the demo's unpacker against the emulator's result, subagents: two checker agents on the Agent tool's opus alias for 60-verify, one for each sample of 80 comments; all other work by one agent
Modelclaude-opus-5-5[1m]
Kit version0.0.106

How the listing was checked

Every step that measured the Source tab’s comments or made them more accurate, in the order it happened, with the models that did it. Accuracy of the Source explains each step and what the row above makes of them.

StepByWhat it foundOf the listing
Researchclaude-opus-5-5[1m]Looked the game up online (its manual, reviews or wiki pages) before reading its code.
Annotationclaude-opus-5-5[1m]Wrote the listing’s comments. 100 % of the program is described, in 2,725 comments.
Sample 1claude-opus-5-5[1m]13 of 80 comments wrong, so between 10 and 26 % of the listing is likely wrong. Whether they were then corrected was not recorded.
60 hand-written and 20 decoder comments
Audit 1claude-opus-5-5[1m]Checked 656 of 2,584 comments and corrected 656.
partial, for the frame-rate error: every reader of $68 followed; 16 engine and all 640 path comments rewritten
Sample 2claude-opus-5-5[1m]5 of 80 comments wrong, so between 3 and 14 % of the listing is likely wrong. All 5 were then corrected.
60 hand-written and 20 decoder comments, from those the first did not draw

likely wrong the sample’s range corrected right, or likely right not yet measured

Contributors

Other places to love this game

What the game does, and where we found it

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:

Features

Addresses are the engine's (parts/engine) unless a part is named.

FeatureStatusWhere
Disk menu on side 1: 1 Armalyte, 2 Loading picture, 3 Walker's Warbleslivemenu at boot (reference/disk-menu.png); the first loads the engine, the third a music demo (parts/warbles, section 16), and the second was not followed
The third menu entry is a music demo of Martin Walker's, dated 1988, with eight tunes in it and four on keysliveparts/warbles/facts.md; its screen is reference/warbles.png, and the page plays all eight through a port of its driver that tests/warbles.js checks against it
"Turn disk to side B & press fire" after the first loadlivewrong_disk ($B5CC): the engine asks for level 1's file, does not find it on side 1 and shows the prompt (reference/turn-disk-side-b.png)
Title screen cycles credits, high scores, ship enhancements and keyboard controlsliveseven pages, title_pages ($B953) (reference/title-*.png)
Fire starts the game (title)livefire on either joystick, title_start_keys ($B58A)
F1 on the title: one- or two-player modelivetitle_function_keys ($BC55), $B026; left and right on the stick choose too
F3 on the title: switch between three starfieldslive$B02F steps 2, 0, 1; stars_animate ($F72F)
F7 on the title: demo modelive$B01A: both ships out of play, tune 1 plays, and fire or the tune's end goes back to the title (joysticks_read, $ABD9)
The ship follows the joysticklivecell to cell on an 8-pixel grid, gliding between cells (ships_move, $E59C; ships_glide, $E90B)
A short press of fire fires the normal weapon; holding fire "for a few seconds" (wiki: about 1.5 s) fires the super weapondiffersthe super weapon fires once fire has been held for 15 frames, 0.3 seconds (ship1_fire, $EC87; live: the charge fell at the fifteenth frame); pressing fire and letting go each fire the normal weapons
Player 1 changes super weapon with a key: the manual and the wiki say the Commodore key, this build's title screen says @livethe Commodore key (keys_play, $AB53): the title draws it as character $2A of its font, a C with a bar through it, not @; it steps A, B, C and round
? changes player 2's super weaponlivethe / key, which carries ? on the keyboard (keys_play)
Space toggles the remote (drone) tracking on and off, one-player mode onlylive$74, only with the drone (keys_play)
RUN/STOP pauses; fire restartslivethe pause starts at the end of a scroll step; fire on either stick ends it (pause_and_fire, $AF7E)
Q quits (from the pause, per the wiki)liveonly while paused, to the front end (keys_play)
S in the pause goes to the next leveldifferslive: S held in the pause does nothing; keys_play reads only RUN/STOP, Q, the Commodore key, / and SPACE
Eight levels, each with a mid-level boss and an end boss; the scrolling stops for the end bossdifferslevels 5 and 7 have no mid-level boss and level 8 meets its mid-level boss twice, at tile columns 167 and 242 (each level's script, $9754); every boss, mid-level ones too, is fought with the scroll stopped, and blows up by itself when its time runs out (level_script, $A93E; live in level 1)
Scenery destroys the ship on contacttracedcharacters $21-$F5 under the ship's nose (players_hit_scenery, $9E05)
Munitions pods change shape each time they are shot, to show the enhancement they would give; the more shots, the better the weapontraceda pod moves on to the next of seven enhancements after 11, 11, 11, 11, 17, 17 and 32 hits, five fewer in a two-player game (pod_next_type, $A5F4); the order is fixed (forward fire, tail gun, vertical cannon, trident, converge, generator, battery), not from worse to better
Collecting a pod before it has changed makes the ship invulnerable for five seconds (the ship flashes)traced255 frames, 5.1 seconds, flashing through six colours (p1_collect_pod, $9A94; ship1_invulnerable, $EA77); a full enhancement, converge, a generator and a battery give the same
Invulnerable from a pod, the ship can fly through walls that block the waytracedthe scenery test only looks at a ship in normal play, state 2, and an invulnerable ship is state 3 (players_hit_scenery, $9E05)
Extra forward fire: two forward shots at the start of each level, increased to fourtraced$4B + 1 shots in flight: 2 at the start, 4 with two pods, 6 with converge (ship1_normal_fire, $F1C3)
Tail fire: backward-firing bulletstraceda pair, a row above and below the ship, backwards ($4D)
Vertical cannon: fire up and downtraceda pair, up and down ($4F)
Trident: two flanking guns beside the main weapontraceda pair one column behind, a row above and below, firing forwards ($47)
Converge: two more shots to the main guns, diverting the tail gun's ammunition; needs two extra forward-fire enhancements firsttracedneeds the tail gun as well as forward fire at 3; it adds two forward shots in the tail gun's slots (p1_collect_pod, $9A94; $B2)
Battery: one more energy cell, at most four, each storing six chargestracedfour slots, $B010-$B013 (player 2 $B014-$B017) (generators_recharge, $EB00)
Generator: stores six energy charges and rebuilds to full after firing; energy beyond that goes to a battery (Wikipedia: increases the recharge rate)confirmedboth hold: each generator, up to four, shortens the rebuild tick from 61 frames to 51, 41, 31 and 19; eight ticks fill one battery at a time and, once none is left to fill, the generator's own charge of six (generators_recharge, $EB00; live: from empty, the charge reached 6 after 488 frames with no generator and 152 with four)
Super weapon A: long sustained blast through solid matter, two charges, low availabilityliveten shots across the ship's row, starting beyond any wall; two charges (super_weapon_patterns, $F07D; live: a full generator dropped by 2)
Super weapon B: swarm of laser fire around the craft, from two directions, one charge, medium availabilitydifferscosts two charges, not one (costs at $F486; live: a full generator dropped by 2); five shots, two ahead, one back and two from behind
Super weapon C: rapid burst of pulsed energy, one charge, very high availabilitylivetwo shots side by side, one charge (live: a full generator dropped by 1)
One-player mode: the second ship is an automatic drone that follows the ship, fires as it does and shields against most enemy shots; it does not hurt enemies (wiki)differsthe drone's shots kill: hits are read from the shot characters on the screen, whoever fired them (enemies_hit_by_fire, $A54C); it absorbs enemy shots, is never hit by an object and collects nothing (p2_hit_by_shot, $9CD3; drone_fire, $F0C4)
Detached, the drone "glides along its own trajectory" (manual) or "stays stationary" (wiki) until recalleddiffersfrom the manual: live, the detached drone stays where it is on the screen, as the wiki says (drone_follow, $9E78)
The drone sits a short distance from the ship on the side opposite its last movementliveopposite the way the stick is pushed, stepping a cell at a time; with the stick released it stays where it is (drone_follow, offsets at $9EF8/$9F03)
Two players at once: the second ship is red, of a different design, and controllableconfirmedtwo-player games started live (F1); ship 2 reads joystick port 1 (joysticks_read, $ABD9); its colour and design were not checked
Two-player mode has more pods (manual: "additional"; Wikipedia: doubled)traced174 pods in every game and 123 more only in a two-player game, across the eight levels (type 6 entries, waves_spawn, $E3FF; the levels' facts.md): additional, not doubled
Players push each other when they collidelivea ship that moves into the other pushes it a cell (ships_relative, $E531)
A destroyed ship respawns at once and keeps its enhancements; the next level takes them all away except batteries and generatorsdiffersa hit ship comes back where it was, invulnerable, keeping its enhancements (ship1_hit_sequence, $E9BD); each load takes every weapon (zero page, cleared by level_setup_vars, $A1DE) and also two batteries and two generators from each player (next_level_losses, $B723, run twice by after_level_load, $B3CC)
Scoreboard: battery status, score, generator status, generator type, converge status, super weapon indicator, craft in reservetracedthe eight hardware sprites in the lower border, redrawn one item a frame (panel_update, $99FA) from the front-end font's glyphs: batteries, score, the generator's rebuild box and count, weapon-level bars, the super weapon's letter, and each player's lives at either end
Three craft in reserve at the startlivethree lives each (title_start_keys, $B58A; reference/level-1-start.png)
High-score table of six entries with three-letter nameslivehigh_score_check ($BA72), names entered with the stick (high_score_name_entry, $BB3C) (reference/title-high-scores.png)
Music on the title and loading screens only; sound effects in playtracedtunes 0 title, 1 demo, 2 high scores and the ending's pictures, 3 loading screen (tune_headers, $C765); in play only the 32 effects (sfx_voice_step, $FA3C); the How it works page plays the four tunes through a port of the driver that tests/music.js checks against it
Exploding enemies carry on along their pathtracedenemies_follow_paths ($EE8D) moves exploding objects too
More than 30 sprites on screen at once, without flicker, at 50 frames a seconddiffersat most 30 in a frame: 20 objects multiplexed on six sprites, the two ships, and eight scoreboard sprites in the border (multiplexer_start, $A305); live, the main loop made one pass a frame through all of level 1
Cheat: POKE 59891,173 ($E9F3) "cheat mode"differsit turns the DEC of player 1's life into an LDA, and anti_cheat_check ($F77D) notices and hangs the machine (live: frozen within five frames)
Cheat: POKE 53792,96 ($D220, an RTS) "unlimited energy"differswith the I/O chips in, $D220 is a mirror of the border colour register, so 96 ($60) sets the border to black, which it already is (live: a 5 there turned the border green); the RAM under it holds a level's characters ($60-$7F), copied once at the level's start, and no code runs there (level $D200)

Beyond the documentation

Found in the code, not in the manual.

Open questions

Each part of the game has its own symbol map and listing, parts/<id>/symbols.json and parts/<id>/listing.json; the ids are the ones in its Source pages’ addresses. Write-ups, facts and symbol maps are CC BY-SA 4.0. The game itself is not hosted here.