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 5 of the copy studied. Every fact names the routine or table it comes from, in this part's listing.
| Range | What |
|---|---|
$0800-$0BBF | fifteen sprite shapes, pointers $20-$2E: the black overlays of the animation |
$1000-$119F | show_ending, the whole ending, straight-line code that never returns |
$2000-$3F3F | the first picture, a hires bitmap: the shower seen through binoculars |
$5000-$5010 | delay, a busy-wait of about 0.35 s |
$6000-$7F3F | the second picture, the same lenses cracked |
$8000-$80A0 | finale_start, str_enter_code, read_code, the typed characters and secret_code |
The part's packer writes $0800-$80FF and nothing else (it was run in kit/c64/cpu6502.js over memory filled with $00 and then $AA). What lies between the pieces above is memory nothing in the part reads. Some of it came with the file: $11A0-$1FFF and $5011-$5FFF match Paris's code at the same addresses in 55 to 66 % of their bytes, with many bytes differing in single bits ($D059 where Paris has $D019). Whether that is another build of Paris or damaged memory the crackers saved with the file is not known.
The part has no interrupt handler of its own (the KERNAL's runs), no sound, no joystick read and no character set.
finale_start ($8000) points the NMI vector $0318 at $8000, blacks the screen and prints "PLEASE ENTER CODE" through the KERNAL's CHROUT.read_code ($804C) reads characters through CHRIN into $8092 and compares the first five with secret_code, ILVCT at $809C ($8061-$806E). A match stores 1 in $1BA0 and jumps to show_ending. RETURN before five characters stores 0 and goes back to the prompt. A wrong code prints RETURN, cursor-up and a space and reads again.ABCDE and RETURN left the prompt waiting; ILVCTX and RETURN started the ending, since only five characters are compared.$1BA0 is written ($8072, $808C) and never read in this part (opcodes.py --refs $1BA0).read_code is City Hall's $1088 and the mine's $5707, byte for byte apart from the addresses it names. Only the early-RETURN target differs: here it is the prompt again, there it is the section's start.$FE43 is SEI and JMP ($0318) (KERNAL 901227-03). Live, after the ending: RESTORE left the cracked picture on screen, because finale_start restores none of the video registers, and typing ILVCT and RETURN blind played the ending again.show_ending ($1000):
$03E8-$07E7, $43E8-$47E7) with $0E, black ink on light blue, and turns hires bitmap mode on with a light grey border and background;$2000 and plays eight sprite steps over it, each followed by delay: a man's head seen from behind, turning left in two frames ($103E, $106E, $10BC), a bar growing out of the small machine at the lower left ($110A), and a round object flying from the machine towards the head and growing to double size ($1142; the last step is sprite expansion, $117B-$1180, since shapes $2D and $2E have the same image);$1186-$1195) to show the cracked picture at $6000, turns the sprites off and ends in JMP $119D.The whole ending takes about 2.8 s. Nothing prints a code, a score or a message.
delay ($5000) counts 79 × 255 passes of a 17-cycle loop, about 343,000 cycles.
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…