Loading listing…
1985 · Domark
Every routine, table and variable the game uses, with the names and descriptions given to them. Click an operand to follow it; the counter beside a label lists what refers to it. The reference below the fold is rendered from the game's facts file.
This game is in 5 parts, and the same addresses hold something else in each. Each part has a listing of its own.
File 1 of the copy studied. Every fact names the routine or table it comes from, in this part's listing.
| Range | What |
|---|---|
$0800-$17FF | sprite shapes: $20 the rolling dot, $22-$39 Bond walking (eight frames of three stacked sprites), $3A-$3F Bond turning, $40-$45 the six pieces of the Domark logo, $46-$48 the sparkles; $21 and $49-$5F are never pointed at |
$1800-$1BFF | the credits' character set, 128 glyphs, copied to $4800 |
$2000-$3F3F | the gun barrel, a multicolour bitmap, copied to $6000 |
$8000-$801A | copy_tune_start: copies the tune to $E000 and starts the intro |
$8500-$8EFF | the tune, the James Bond theme (heard by the contributor): three note lists |
$9000-$9B9F | the credits: printer, 85 entries (credit_lines), their strings, the title rows |
$A000-$AA82 | speech_play and its samples |
$B000-$B9FF | a hires fragment with "A VIEW TO A KILL" lettering that nothing shows |
$C000-$CEFF | the intro's code, its interrupt handler at $CC00 and the music driver ($C640-$C7B5, state at $C600) |
$8020 blacks the border and background, calls GETIN once, ignores the result and jumps to $8000, which copies the tune from $8500-$8EFF to the RAM under the KERNAL at $E000-$E9FF and jumps to intro_init ($C5A0).irq_handler ($CC00, installed at $C5B5) takes the raster interrupt only ($D01A = 1) and dispatches on $0313: 0 music only, 1 the gun barrel (irq_mode1, $CC30), 2 the credits (irq_mode2, $CCD0). Every mode ends in irq_music ($CCF7), and every interrupt goes on to the KERNAL's $EA31.opcodes.py --refs $DC00, $DC01). At the end ($C4A7-$C4B5) it puts $0314 back to $EA31, silences the SID and loops in sparkle_loop ($C476) for good.In frames of a whole-part run in kit/c64/cpu6502.js (no bad lines, so the real machine runs a little longer):
| Frame | What |
|---|---|
| 14 | two white dots roll across the screen (rolling_dots, $C000) |
| 226 | the barrel is wiped in from the right (white_wipe, $C100) |
| 269 | it scrolls left while Bond walks in (barrel_step, $C809; bond_step, $C200) |
| 551 | the gunshot (gunshot, $CABC) |
| 559 | blood runs down (blood_step, $C840) |
| 782 | the screen shakes (shake, $C900) |
| 1053 | the speech (speech_play, $A000) |
| 1163 | the picture dissolves (speech_and_fade, $CA80; bitmap_mask, $CA50) |
| 1215 | the Domark logo flies together from six sprites (logo_assemble, $C430) |
| 1485 | "D O M A R K / presents you / as / JAMES BOND 007" (title_print, $90A0) |
| 1850 | the credits begin to scroll (credits_scroll, $C54E) |
| 5171 | the end, about 103 s in |
scroll_copy ($CD00) and swap_bank ($C170) move the picture two cells per swap, and barrel_colour ($CE00) whitens the columns as they come in.$BAAA, played with interrupts off. The blood is an EOR of one bitmap line with $55 every second frame, turning white pixel pairs red, 192 lines in all.CMP #$54 at $C4A3), a new line every 40 frames.$C640-$C7B5). A note is three bytes, frequency high, frequency low and length (voice_step, $C723).tune_tick, $C6AB). Vibrato adds 0, 4, 8 or 12 to the low frequency byte each frame ($C798). Voice 1 alone goes through the low-pass filter ($C66D-$C67E).$01 = 0, all RAM ($C773), and restarts the tune when voice 1 reaches $E1EC ($C786). One pass is 5,106 ticks, about 102 s.music_save ($C1B0) and music_restore ($C1C0) park the driver's state at $9F00 during the gunshot and the speech.$C621-$C7FE are the same, at the same addresses, in City Hall, and City Hall's $E000-$E977 is this tune.speech_play ($A000) plays one bit at a time by switching the SID's volume, $D418, between 0 and 15. Its data is a length word at $A090 and samples at $A092-$AA81; in the simulator it ran 2,149,012 cycles (about 2.2 s, some 9,400 bits a second) with 20,355 writes to $D418. $A453-$A715 is zeros, a silence of about 0.6 s. It runs with BASIC banked out ($01 = $36, $CA90).
$8020-$802D is a patch of 14 bytes over the start of another group's title and menu routine. The rest of it is still in the file and never runs: its code ($802E, $80A5), its title screen at $8100-$84FF ("THE DYNAMIC-DUO PRESENTS … BROKEN BY THE DARK-ANGLE & THE EXECUTOR") and its menu at $8F00-$8FFF ("1) SEE OPENING 2) PARIS-CHASE 3) CITY ESCAPE 4) SILICON MINE 5) FINALE"), whose loader asks for files named P*, C*, S* and F*.$9A00 (it sets the BRK and NMI vectors to $9A2A, ten bytes past its own return), $9D00, $C4BB, $C500, $C5C3.credits_setup ($CB50) writes $97 to $D011, whose top bit is bit 8 of the raster line the interrupt is asked for: line $1F0, which a PAL screen never reaches. The only thing that clears it is the read, AND and write of $D011 at $C540, and a read of that bit gives the line the beam is on. If $C540 runs while the beam is below line 255, the bit is written back set, no raster interrupt comes again, and the credits, the music and everything else driven from irq_handler stop.
Live, 30 September 2026, four boots with the start moved by a tenth of a second each time: three read A = $17 at $C545 and scrolled the credits (100 calls of credits_scroll in 15 s); one read $97, at raster line 38 after the store, and credits_scroll never ran.
Current truth for this game. The workflow lives in kit/skills/; how this understanding developed lives in agent-history.md. Every fact names the routine or table it comes from. Unless marked live, a fact comes from reading the code in the snapshots named in orientation.md.
The game is five programs, and each has its own facts, listing and symbols under parts/<id>/: parts/intro/facts.md, parts/paris/facts.md, parts/city-hall/facts.md, parts/mine/facts.md, parts/finale/facts.md. An address is always an address in the part named with it. This file holds what spans the parts.
Five programs, loaded one at a time from a menu, each unpacked over the whole of memory and started at its own entry (orientation.md):
| Part | Entry | Interrupt in play | Screen | Sound |
|---|---|---|---|---|
| intro | $8020 | $CC00 | bitmap, banks 1 and 2 | the Bond theme, speech |
| Paris | $43B0, then $5A00 | $5026 | $0400 | the theme, effects, speech |
| City Hall | $1000 | $4022 | $0400 | the intro's tune, effects |
| mine | $5660 | $1022 | $4000 | Paris's tune, effects |
| finale | $8000 | the KERNAL's | bitmap $2000, $6000 | none |
Nothing is loaded once a part runs, and no part loads the next: the player goes back to the menu for each.
The three later parts start at a KERNAL "PLEASE ENTER CODE" prompt with the same routine (read_code: City Hall $1088, mine $5707, finale $804C): five characters through CHRIN, compared with a fixed string. A match stores 1 in $1BA0; RETURN before five characters stores 0 and plays on without the code (the finale goes back to its prompt instead); a wrong code is read again, with no limit on tries.
| Given by | Where it is shown | Code | Checked by |
|---|---|---|---|
| Paris, on a catch | the telex, Paris $8140 | CCPHJ | City Hall $10D8 |
| City Hall, on escape | mission_complete, City Hall $1334 | DB4CT | mine $5757 |
| the mine, on defusing | mission_complete, mine $0AFE | ILVCT | finale $809C |
$1BA0 is the same address in all three parts, and a part reads it once, at its end:$7096): with the code, reaching room 76 with Stacey shows DB4CT; without it the game starts again ($8600).$25F2): with the code, the right bomb digits show ILVCT; without it the bomb goes off, whatever the digits (game_over, $25D0).parts/city-hall/facts.md, parts/mine/facts.md). The finale compared only five characters: ILVCTX was accepted.Bytes identical at the same addresses, compared in the unpacked images:
| What | Where |
|---|---|
| the three-voice music driver | intro and City Hall $C621-$C7FE |
| the Bond theme's notes | intro $E000, City Hall $E000 (and intro $8500, the copy it moves there) |
| the second tune's notes | Paris and mine $E000-$FFFF |
read_joystick | City Hall $4700, mine $17A0 |
tick_clock | Paris $4170, City Hall $6E40 |
| the "OK" sound | City Hall $6B50, mine $3B7D |
read_code | City Hall $1088, mine $5707, finale $804C, apart from the addresses they name |
mission_complete and its text with ILVCT | mine $0A00-$0B04, and the same bytes in City Hall, where nothing calls them |
All four playable parts read the joystick in port 2 only ($DC00) and stop CIA 1's timer A, so the KERNAL never scans the keyboard during play; the keyboard is used only at the code prompts.
Each part carries leftovers of earlier work on the game, none of which runs:
$8020 onwards, overwritten by a 14-byte patch (parts/intro/facts.md).$0800.$967B), an older end screen ("WEBL DONE 007 YOUR CODE IS 111122", $7E5A), and the mine's end screen at $0A00.$0B04-$0FFF).Whether the code prompts and end screens are the original game's or the crackers' is open. For the crackers: the older prompt and end screen left in City Hall, and the mine's prompt placed in character-set glyphs the mine's tiles do not use. Against: the memos, which are plainly the game's, also print through the KERNAL. The published game is documented with the three codes (C64-Wiki, features.md).
| Test | Part | Result |
|---|---|---|
| each code at its prompt; a wrong code; RETURN | City Hall, mine, finale | as above |
| four intro boots, start moved a tenth of a second each time | intro | the credits stalled in one (parts/intro/facts.md) |
| Bond's room set burning, with and without CCPHJ | City Hall | the DB4CT screen; a new game |
end_check run with set digits, with and without DB4CT | mine | ILVCT; game_over |
| RESTORE after the ending | finale | the prompt again, blind |
| holding fire for 1.2 s on Paris's instruction page | Paris | the chase started normally; a stuck start seen once earlier was not reproduced |
Pokes that change the game within its own parameters. Each one names the variable it changes and whether it has been tested live. Untested pokes are labelled as candidates. Addresses are in the part named.
| Effect | Poke | Status |
|---|---|---|
| Play City Hall or the mine without the previous code | press RETURN at "PLEASE ENTER CODE" | live |
| Codes: City Hall CCPHJ, the mine DB4CT, the finale ILVCT | type at the prompt | live |
| City Hall: end the part at once (with CCPHJ typed) | set byte 12 of Bond's room record: POKE the address in $3F/$40 plus 12 with 1 | live |
| Mine: the bomb's combination | numbered items 6, 7, 1, 3, 4 ($26F0) | live, by storing the digits |
| Mine: stop the clock | $1B80 = 1 (the PAUSE flag) | candidate |
| Paris: repair the car | $03A1 = 0 (damage, 40 loses) | candidate |
| City Hall: refill Bond's energy figure | $1B5B = 42 (the gauge never kills) | candidate |
Loading listing…