1986 · Micro Power

Doctor Who and the Mines of Terror: the source

This minisite was contributed by air, unorig. It’s currently claimed by unorig who is editing it to reach a Gold tier standard.

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.

Technical reference: memory map, timing, tables, cheats

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 work/entry.vsf, the hand-over snapshot named in orientation.md.

Build

A single packed program file (orientation.md). The depacker leaves the game at $484D with the KERNAL banked in; the game banks it out itself ($01 = $35) and banks it back only to save ($958A). A loader stub at $7F00-$7F52 that prints "PLEASE WAIT -- STILL LOADING" and jumps to $484D, and a prologue at $4800-$484C that never runs, are left over from the release the file was made from.

Memory layout

ThingWhere
Zero pageevery variable named in symbols.json: countdown $1B-$1D, lives $1E, battery $1F, camera $20-$2D, programmer $2F-$3B and $FF, pockets $3C-$41, markers $42-$45, throws $46-$4D, score $57-$59, oxygen $F1
Glyph-merge operand pointers$03-$16, pixel masks $17-$1A, copied from $4A4E
Status screen and its font$0400, glyphs for codes $94-$FF at $04A0-$07FF
Splinx Programmerfont $0800, sprites $0B00, screen $0C00, colours parked at $1000
Map row pointers$0A80/$0AC0
Block pointers, terrain classes$1400/$1500, $1600
Item names, lives field, digit glyphs$1770, $1720, $1730
Object tables, 80 objects$1850-$1EFF
Music$1F00-$2D3F, player $74C0-$7649
Character colours$2F00
Block definitions, 256 x 4x4 characters$3000-$3FFF
Play-area character set$4000-$47FF
Status screen source$4B00-$4EFF
Sprite images$5000-$73FF, pointers $40-$CF
Play screens$7800 and $7C00; $7800-$7D7F is also the save block
Code$484D-$4A85 (start-up), $7440-$7649, $8000-$CFF5, $FC8C-$FF6E
Cavern map$E000-$FBFF, under the KERNAL

Timing

Controls

$8F24 reads the stick in control port 2 ($DC00) and six keyboard rows, each into its own zero-page byte, and sets movement flags (traced: $8F3C-$9058):

InputFlagEffect
stick left, Z$CB = $81walk left (live)
stick right, X$CB = $01walk right (live)
stick up, ;$CC = $01climb up
stick down, /$CC = $81climb down
fire, RETURN$CD = $FFjump
F1$D0move the pocket selector $3C through 0-4 (live: 0, 1, 2, 3, 4, 0) ($A530)
F3$CFput the held item in the first free pocket, a marker in its slot, or with empty hands take the selected one out ($A575)
F5$D2standing still, pick up the object in front ($A6B4, $A929); use the held item ($BB28)
F7$D1with a direction, throw the held item ($A68A)
S$D3the Splinx Programmer (live)
R$E8 = $12forced regeneration (live: message, lives 5 to 4)
D, CTRL+D, L$E8 = $80, $C0, $FFthe save menu, but only where the Doctor stands on tile $23: everywhere else doctor_update clears $E8 ($C902-$C909; live: D beside the TARDIS does nothing)

Graphics

Three raster bands ($8010-$80D7), checked against the emulator's picture by a frame capture (live: frame.py compare, 104,448 of 104,448 pixels):

  1. Raster 256 to 78: VIC bank 0, $D018 = $11, screen $0400, characters from $0000. The status bar uses codes $94-$FF, so the video chip reads its font from $04A0-$07FF, the rows of the same screen below the status bar. Start-up copies $4B00-$4EFF there and builds the letters and digits from the character ROM ($48F5-$493E): code $DC is A, $F6 is 0. Digit 9's glyph would sit under the sprite pointers at $07F8, so 9 is drawn with code $F5 ($1730).
  2. From raster 78: bank 1, $D018 = $E3/$F3 (screen $7800 or $7C00, characters $4800), fine scroll from $5E and $5F.
  3. From raster 86: $D018 = $E1/$F1, characters $4000. $7440 clears $4800-$4FFF, so the one character row of band 2 is blank.

Text

Mechanics

| $E8 | Cause | Set at | |---|---|---| | $06 | THE EXPLOSION | $C1F6 | | $08 | prints GAME OVER as the cause | $C0C2, when the rising level $51 passes the Doctor | | $0A | A SHOCK FROM A CONTROLLER | $CE5A | | $0C | A FALL, a drop of $60 or more | $CD8B | | $0E | FALLING ON A STALAGMITE, tiles $74/$51 | $CA67 (live) | | $10 | SUFFOCATING | $CAC2 | | $12 | FORCED REGENERATION, key R | $9051 (live) | | $14 | SUFFERING A MADRAG BITE | $B96F | | $16 | BEING ATTACKED BY A BABY MADRAG, near an egg | $B902 |

EXPOSURE TO RADIATION is a message nothing in the table points at.

Sound

Hardware register census

From every instruction in the traced code with an operand in $D000- $DFFF (colour RAM aside).

RegisterWhere
$D000-$D007, $D010sprite positions: $B00F-$B059 (programmer), $FE80-$FE90 (TARDIS)
$D011, $D012start-up, raster bands, $80DA; raster reads in $8D0B, $931B, $B02D, $B15D
$D015-$D01Dsprite enables and modes: $8138-$81BE, $AF83-$AFE2, $FE7A-$FE88
$D018, $D016raster bands; programmer $AFC6; $9594
$D019, $D01Astart-up; $9367, $94F2, $AF88, $B140
$D020-$D02Acolours: start-up, $815E, $AFE7-$AFF6, $FEA2, $FF31-$FF41
$D400-$D40Bmusic, voices 1 and 2: $755D-$7631
$D40E-$D414, $D418, $D41Ceffects on voice 3, volume: $C7CF-$C8A5
$DC00-$DC02keyboard and stick: $8F3C-$8FD2
$DC0Estops CIA1 timer A at start-up
$DD00, $DD02VIC bank: raster bands, $AFB2-$AFC1

Not named by any traced instruction: the filter, $D01E/$D01F (collisions are worked out in software), the CIA timers beyond the one stop. STA $D400,Y at $755D reaches the SID through an index.

Open questions

Live tests

TestResult
Frame capture, rebuild compared with the emulator's picture104,448 of 104,448 pixels
Writes to $1B-$1D from the hand-over$499A, $499E; 010800
$1E and the lives field at play start5; five figures
F1 pressed six times, $3C read0 1 2 3 4 0
S, then stick down, $3A readthe programmer opens; cursor moves
$1F at play start24
R pressed$E8 = $12, FORCED REGENERATION scrolls, lives 4
D pressed beside the TARDISnothing; $E8 back to 0
Walk right until a fallFALLING ON A STALAGMITE, a life lost
Twelve frames stepped in play, SID and $E1 readmusic plays; $E1 stays 1
Original disk, stopped at $484D, RAM compared with the listingequal in all bytes the listing holds except zero page and $FF70-$FFFF (3 October 2026)
Restart point moved to the crystal room, a life lostthe room on screen matches the Maps tab, railing gap included
CIRCUITs $44 and $45 put at x $0208 and $0228, y $0390slots read S T O P T; $4F = $FF; $42/$43 put back: $4F = 0
Restart beside the madraghead and body drawn above the legs, as on Gameplay
Title screen, after NSID voice 2 plays the title tune; stops when space is pressed

Cheats

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. The file is packed, so these are made in a machine code monitor or an emulator while the game runs, not before RUN.

EffectPokeStatus
Lives: n figures, n lives before GAME OVER$1E = n (5 at the start; the field shows up to five)live: 2 poked, one death left one figure
Score$57-$59, six BCD digits, high byte firstlive: 12 34 56 shows 123456
Full Splinx battery$1F = 24candidate (24 read live at the start)
Air$F1 = 50candidate ($CA90)
Time bonus$1B-$1D, BCD, low byte firstcandidate ($91BC)
routines tables variables strings branch labels

Loading listing…