1987 · Incentive Software

Driller: play

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/spectrum/driller with me to Gold.

The whole game, playable in the browser: the security question, the control options, the moon's eighteen sectors in solid 3D, the probe and the jet, the rigs, the sensors, the clock and the information screen, with saving and loading to a tape file. Every routine is ported from the game's own Z80 code and was run beside it until the two agreed.

Loading the game's data…
  • The security question: type the word from the Federation Briefing (it is shown under the screen), then Enter
  • The control options: 1 keyboard, 2 Sinclair, 3 Kempston, 4 cursor; Enter begins
  • O K forward and back, Q W turn left and right, or the arrow keys
  • 0 or Ctrl fires the laser; Space swaps moving for aiming the crosshair; B shows or hides the crosshair
  • P L look up and down, N M tilt, U turns round
  • R F rise and fall, A Z the angle of a turn, S X the size of a step
  • D drills: a rig is put down in front of the probe; C collects it
  • I the information screen: S saves, L loads (a .tap file), 1 abandons the game, any other key goes back

The game's own screen, drawn from the port's memory each frame as the Spectrum would show it, at the Spectrum's own pace: the game draws each view into a buffer of its own and then copies it to the screen. The sound is the port's writes to the beeper, each edge at the T-state the game's loops make it, played by the site's model of it as each frame is shown.

01 · The port

Every routine of the game, checked against the original

The game is a Z80 program of about 20,000 bytes of code. The port is the same program written again in JavaScript, one function for each of the game's 89 routines, reading and writing the game's variables at the game's own addresses. The page runs only the port: the game's code is in the tests, as the original the port is held to.

CheckWhat it showed
Each routine aloneEight test files take each routine at the moments the game itself calls it, in 208 moments of play saved from the emulator; others run on inputs made at random: the arithmetic on random operands, keys and the joystick held at random, and scripts of random instructions. The port's routine and the game's own, on the kit's Z80, run from the same machine, and every byte of memory, the border and the beeper's writes must come out the same.
The whole program in lockstepThe port's program runs beside the game's, pass by pass: from the loader's hand-over through the security question and the control options into play, and from each moment of play for 150 passes, with the keys played at random. Five more runs force the ways out of play the sessions seldom reach: the clock running out, the energy, the shield, the information screen, and abandoning the game from it, each through the game over and back to the menu. Every byte of memory and the border were the same at every stop, but for the stack.
The ROMCollecting a rig in Amethyst before any rig of the game has been put down reads the gas from a table whose pointer is still 0: the ROM's first byte, $F3. The page carries that one byte of the 48K ROM and nothing else of it.
The page's memoryThe page carries the game's memory as the loader leaves it, with 20,091 bytes of instructions set to zero; it keeps 288 bytes of code that the game also keeps state in, operands it rewrites and the two bytes the security question mends. The page's machine on that memory and on the whole memory ran the same, frame for frame, from the hand-over and from the moments of play with random keys.
The paceThe port executes no instructions, so the page charges each stretch of the main loop, each routine, and each row, byte and character it fills or prints the T-states they cost the game. The heaviest routines are priced from their own T-states, measured on the game: the span filler by the rows, bits and bytes it fills, a polygon's edges by their rows and steps, the vertex rotation by its multiplications, the painter's sort by its comparisons and swaps, and nine routines whose cost a call holds within 10 % at that cost. The rest is fitted around them on 16,389 passes timed on the kit's model of the 48K; the interrupt is fitted the same way, with each sensor it checks and each beam it draws. On 2,399 passes it was not fitted on, the median pass is 0.1 % short of the game's time, and seven in eight are within 5 %. Over 60 passes from each of 153 moments of play, once with random keys and once with a fixed round of walks, turns, looks up and down and moves of the crosshair, 296 of the 306 runs take within 5 % of the game's time; the slowest, in Mitral, takes 9 % longer. From moments of play, with that round of commands on both for 30 seconds, the page takes within 5 % of the game's time for the same passes.
The listingThe port was written before the listing's comments on the code, and they were written from it, so porting found none of them wrong.

02 · Differences

What differs from a Spectrum

The game plays as it does on a 48K Spectrum, at the 48K's pace. These are the places where the page cannot be the machine, and what it does instead.

On a SpectrumOn this page
The interrupt can fall between any two instructions of the main program.The interrupt runs between two of the port's routines, at the clock's time for it. The bytes the interrupt changes and the main program reads in the middle of a routine (the wait counter, the clock's frame count, the minutes, the energy and the shield, and the sensors' beams) are read after the interrupts due by then have run.
Each instruction takes its T-states, and a pass takes as long as its drawing does.The port executes no instructions. Each stretch of the main loop, each routine and each row and byte it fills costs what it cost the game, measured or fitted on the game's own timings (01, The pace), so a pass takes about as long as on the Spectrum: within 5 % but for a few scenes, the slowest of them in Mitral, 9 % slower.
A sound effect plays with the interrupts off, and the frames it lasts are lost to the game's clock.The page's effects take the game's time with the interrupts off too, and lose the same interrupts, as does a sensor's hit, whose sound plays inside the interrupt.
The beeper is toggled from the effects' timing loops.The site's model of the beeper plays the port's writes to it, each at the T-state the game's loops make it, as the frame is shown.
The ULA draws the screen a line at a time as the beam crosses it.The page takes the screen whole at the moment the beam would reach its first line, so a change made while the beam is drawing shows a frame later, all at once.
The information screen's S and L save and load a position on tape.S gives a .tap file to download, with the game's two blocks; L asks for a .tap file and gives the game its blocks in turn. Cancel is BREAK.
The joystick is a Kempston interface, a Sinclair stick or the cursor keys, as the control options choose.The arrow keys, and the pad under the screen, are whichever joystick the control options chose, with Left Ctrl for fire; every other key is the Spectrum's own.