Inside the machine

Programming the PDP-1

To read Spacewar! as code you have to know what kind of code it is. There was no operating system, no high-level language, no library to call. A program for the PDP-1 was a list of 18-bit words in the machine's own instruction set, written in octal or in the MACRO assembler's mnemonics, punched to paper tape and loaded into core. The game's physics, its controls and its glowing ships are all built from a few dozen instruction types operating on a single accumulator. This page is a short tour of that instruction set, and of the one instruction, dpy, that made the whole genre possible.1

the 18-bit word
One word, one instruction

Eighteen bits, octal, and one's complement

The PDP-1's word is 18 bits wide, conventionally written as six octal digits (each digit is three bits, so the largest word is 777777 octal). A memory-reference instruction divides that word into three fields: a five-bit operation code, a single indirect-address bit, and a twelve-bit address. Twelve bits is why the basic machine reaches exactly 4,096 words of core (00000 to 07777 octal); larger memories were addressed by switching in an extend mode.

opcode i address
bits 0–4 · 5 bits bit 5 bits 6–17 · 12 bits → 4,096 words

Arithmetic is one's complement: a negative number is the bitwise complement of its positive, which means the machine has two representations of zero (all-zeros and all-ones) and that overflow and sign behave a little differently from the two's-complement machines that came later. The programmer works mostly through one accumulator (AC), with an in-out register (IO) alongside it (the two can be joined for 36-bit shifts), a program counter (PC), an overflow flag, six program flags and a bank of sense switches on the console. A core cycle takes about 5.35 microseconds; most instructions take two cycles, roughly 10.7 microseconds, so the machine runs on the order of ninety thousand instructions a second. Every moving thing in Spacewar! has to be computed and drawn.

the instruction set
A few dozen verbs

What the machine can be told to do

The instruction set is small enough to hold in your head: memory-reference instructions name a word to act on, while the operate, skip, shift and in-out groups are micro-coded bit-fields that combine in a single word. Type a mnemonic to look one up, the table filters as you go.

MnemonicOctalInstruction

Mnemonic, the short name written in assembly (for example lac), standing in for the machine's numeric operation. Octal, that operation as a base-8 number, the way PDP-1 programmers wrote it (three bits per digit): two digits for memory-reference instructions, six for the micro-coded operate, skip, shift and in-out groups. Instruction, what it does, where AC is the accumulator, IO the in-out register, Y a memory location, and means "is given the value of".

The table loads sorted alphabetically by mnemonic. Click a column heading to sort by it (again to reverse, a third time to restore the original order). Instruction data after Norbert Landsteiner's PDP-1 instruction list and DEC's PDP-1 Handbook.

the instruction that draws the game
dpy: display one point

The whole game is points, plotted in a loop

One instruction matters more than all the others for this project. dpy, "display one point," takes the value in the accumulator as the point's X coordinate and the value in the IO register as its Y coordinate, and lights a single dot at that position on the Type 30 screen (a few bits select brightness). There is no line-drawing, no shape primitive, no frame buffer. A ship, a torpedo, a star, the heavy sun, every one of them is a set of points pushed through dpy, and they stay visible only because the program plots them again on the next pass and the phosphor holds the glow for a moment. Spacewar! at bottom is a loop: compute positions, load X into AC and Y into IO, dpy, repeat, fast enough that the eye reads motion.

Here is that idea in the game's own source. This is the dispt ("display point") macro from the 3.1 listing of September 1962, a definition in DEC's MACRO assembler:

define dispt A,Y,B repeat 6, B=B+B / shift brightness B up into the display field lio Y / load the Y coordinate into the IO register dpy-A+B / display one point (X already in the accumulator) term

Quoted from Spacewar! 3.1 (24 September 1962), held in our source archive. repeat 6, B=B+B doubles the brightness value six times, that is, shifts it left six bits, to seat it in the instruction's brightness field; lio loads the IO register; dpy then plots the point whose X coordinate the caller has already left in the accumulator.

It is worth pausing on the fact that this is a macro. DEC's MACRO assembler let the MIT programmers define their own higher-level operations, dispt, scale, diff, and build the game out of them, which is part of how a program this ambitious fitted in a few thousand words and stayed readable enough to be modified by a dozen hands. The assembler is itself part of the PDP-1 software the hackers wrote for themselves.

why this belongs here
The reading

The instruction set is part of the meaning

Reading Spacewar! closely means reading at this level. The 18-bit word fixes the precision of the orbital arithmetic; one's-complement sign handling shows up in the physics; the single accumulator dictates a style of code that constantly loads, operates and stores; and dpy is the reason the game is a redraw loop rather than a picture.

← The PDP-1   The versions and source →

notes

1 The complete reference is Norbert Landsteiner's PDP-1 instruction list (masswerk.at).

sources
On this page

References