Go to the Index

Inside Spacewar!
Part 4: The Outline Compiler

Prev. Next

(Introduction · The Code · Compiling the Outlines · Movement Semantics · Outline Pragmatics · Constraints · The Object Code)

In this part of our software archeological journey through the internals of Spacewar!, the earliest known digital video game, we're going to peek inside one of the most opaque parts of Spacewar!, Dan Edwards' famous outline compiler for drawing the spaceships.

Spaceship outlines in Spacewar!

Outline encoding of the spaceships in Spacewar!

BTW: You can play here the original code of Spacewar! running in an emulation.

There is some history behind this piece of code: Once there would have been an outline interpreter by Steve Russell which would be stepping over the defining outline data held in a separate table per spaceship. But with the introduction of the code for calculating gravity — also by Dan Edwards and all-important to the gameplay — the game was driven beyond flicker-free display performance. Enter the outline compiler, maintaining both the required speed and the configureable outlines:

The ship outlines were represented as a series of direction codes starting from the nose of the ship; when the ship was vertical and tail-down, each code pointed to one of the five possible adjacent dots could be displayed next. To display the ship at an angle, Russell calculated the appropriate sine and cosine and added them to the original direction code constants, in effect rotating the entire grid. With this method, the ship's angle had to be calculated only once in each display frame. The outline codes were kept in a table so that different shapes could be tried out at will, but this meant the table had to be searched every frame to generate the outline. As the game developed, this arrangement proved to be a sticking point which we shall see, was neatly solved by Dan Edwards.
(…)
The addition of gravity pushed Spacewar! over the edge of flicker-free display. To get back under the limit, Dan Edwards devised an elegant fiddle to speed up the outline display routine.
In Russell's original program, the outline tables were examined and interpreted in every display frame, an essentially redundant operation. Edwards replaced this procedure with an outline "compiler," which examined the tables at the start of a game and compiled a short program to generate the outline for each ship. This dramatically reduced calculation time, restoring the steady display and making room for the last of the original bells and whistles. (J. M. Graetz, "The Origin of Spacewar", Creative Computing, August 1981)

So, instead of iterating over the data twice per frame (once for each ship) and having to do all this parsing of the data and branching to various parts of the code based on the encoded commands, the outline data would be parsed once for all at the start of the game. The outline compiler would step over the various data points and would assemble the required code in a single stream of commands, to be injected into the PDP-1's memory just after the end of the data of the collidible objects table. Thus, there are now two sides to the code, which is effectively separating into two distinctive tasks, what would have been done at once by the interpreter before: On the one hand, there's the branching required to follow an outline as encoded in the outline table, which is done at compile time. On the other hand, there is the actual drawing in a 2D context, done by calling the resulting object code. For this, the main program would have to supply the current x and y coordinates telling the compiled code were to draw the outline. And it will have to tell the compiled routine, at wich angle to draw a ship. (There will be probably some trigonometry involved in order to map a given rotation angle to a Cartesian coordinate system.)

We've already seen in Part 3, how the outline compiler would have been initially called at the start of the program. Let's see, what's actually happening, when "jda oc" is executed …

The Code

Credits: Spacewar! was conceived in 1961 by Martin Graetz, Stephen Russell, and Wayne Wiitanen. It was first realized on the PDP-1 in 1962 by Stephen Russell, Peter Samson, Dan Edwards, and Martin Graetz, together with Alan Kotok, Steve Piner, and Robert A Saunders. Spacewar! is in the public domain, but this credit paragraph must accompany all distributed versions of the program.
	/outline compiler
	/ac=where to compile to, call   jda oc
	/ot=address of outline table

define
	plinst A
	lac A
	dac i oc
	idx oc
	terminate

define
	comtab A, B
	plinst A
	jsp ocs
	lac B
	jmp oce
	terminate

ocs,	dap ocz		/puts in swap
	dio i oc
	idx oc
	dio i oc
	idx oc
ocz,	jmp .

oc,	0		/outline compiler proper
	dap ocx
	lac i ocx
	dap ocg
	plinst (stf 5
	dap ocm
	idx ocx
ock,	plinst (lac \sx1
	plinst (lio \sy1
	clf 6
ocj,	setup \occ,6
ocg,	lio .		/outline table
och,	cla
	rcl 3s
	dio \oci
	lio (rcl 9s
	dispatch
	opr
	jmp oc1
oco,	jmp oc2
ocq,	jmp oc3
ocp,	jmp oc4
ocr,	jmp oc5
	jmp oc6

	plinst (szf 5	/7 code
	add (4
	dap ocn
	plinst ocn
	plinst (dac \sx1
	plinst (dio \sy1
	plinst (jmp sq6
	plinst (clf 5
	plinst (lac \scm
	plinst (cma
	plinst (dac \scm
	plinst (lac \ssm
	plinst (cma
	plinst (dac \ssm
	plinst (lac \csm
	plinst (lio \ssd
	plinst (dac \ssd
	plinst (dio \csm
	plinst (lac \ssc
	plinst (lio \csn
	plinst (dac \csn
	plinst (dio \ssc
	plinst ocm
ocx,	jmp .

ocm,	jmp .
ocn,	jmp .

oc1,	plinst (add \ssn
	jsp ocs
	lac (sub \scn
oce,	dac i oc
	idx oc
	jsp ocs
	plinst (ioh
	lac (dpy-4000
ocd,	dac i oc
	idx oc
	lio \oci
	count \occ, och
	idx ocg
	jmp ocj

oc2,	comtab (add \scm, (add \ssm
oc3,	comtab (add \ssc, (sub \csm
oc4,	comtab (sub \scm, (sub \ssm
oc5,	comtab (add \csn, (sub \ssd
oc6,	szf 6
	jmp oc9
	stf 6
	plinst (dac \ssa
	lac (dio \ssi
	jmp ocd
oc9,	clf 6
	plinst (lac \ssa
	lac (lio \ssi
	jmp ocd

And this is the data defining the outlines of the spaceships:

/ outlines of spaceships

ot1,	111131
	111111
	111111
	111163
	311111
	146111
	111114
	700000
. 5/

ot2,	013113
	113111
	116313
	131111
	161151
	111633
	365114
	700000
. 5/

(For the basics of PDP-1 instructions and Macro assembler code, please refer to Part 1. We'll repeat the semantics of the instructions as we're encountering them.)

Where to start with this piece of code? Following best practice, we'll start at the beginning, right where the compiler is called by the main code:

Compiling the Outlines

As we might remember from Part 3, the outline compiler is called by the following instructions, here for spaceship 1:

	law nnn		/ start of outline program
	dac not
/	...
	jda oc		/ compile outline
	ot1

This is loading the address of the location right after the data of the objects table into the accumulator, stores this for later use as the start address of the compiled code in the location labeled not, and calls the outline compiler by the instruction "jda oc", followed by the address of the outline data for the first spaceship in the next location.

As we already know (from previous parts), instruction jda deposits the contents of the accumulator in the location provided in the address part, puts the value of the program counter plus 1 into the accumulator (to be used as the return address) and jumps to the next location after the provided address. By this, we've successfully passed the start address for the code (in oc) as well as the address of the data (in the accumulator), and make a jump to oc+1.

Note: It might be fair to note here that this technique of passing multiple parameters is already to be found in the multiply and divide routines by BBN (Bolt, Beranek and Newman) and might have been adopted from there.

oc,	0		/outline compiler proper
	dap ocx		// store address of pointer to the data in ocx
	lac i ocx	// load first data word
	dap ocg		// store it in address part of ocg
	plinst (stf 5	// compile "stf 5" (set flag 5)
	dap ocm		// put the current object code address in ocm
	idx ocx		// index ocx, now the actual return address

(As usual, comments starting with double slashes are mine and not in the original code.)

With location oc serving as the pointer for the generated object code, we enter at the next instruction, where we store the location of the data table in the address part of ocx. (This is using the naming convention generally indicating a return address. We'll see soon, why this would be so.) Then, we load the contents of the address to which the value in ocx is pointing to, the very first location of the data table, into the accumulator. This first data word is then stored in ocg, serving as the store for the current data word.

The macro plinst (push last instruction ?) injects the provided constant expression in the current (or currently last) location of the object code as designated by oc and increments oc to point to the next location. As a side effect, the current value of oc is also left in the accumulator. This is now stored in the address part of location ocm (which is already containing a jmp in the instruction part) for later use. We may note that this is the location of the next instruction after the very first "stf 5" (set flag 5) at the start of the compiled code.

Finally, the contents of ocx is incremented by 1, now pointing to the actual return address after the pointer to the outline data.

Let's have a closer look at macro plinst, which is performing most of the actual assembly:

define
	plinst A
	lac A
	dac i oc
	idx oc
	terminate

This macro is taking a single argument (A), a constant expression which is loaded into the accumulator by the first lac. This value is then deposited in the location to which oc is currently pointing to. Finally, the instruction "idx oc" increments the contents of oc, leaving the incremented value in the accumulator as a side effect.

The following instructions are finializing the setup steps:

ock,	plinst (lac \sx1	// compile "lac \sx1" (load x into AC)
	plinst (lio \sy1	// compile "lio \sy1" (load y into IO)
	clf 6			// clear flag 6
ocj,	setup \occ,6		// initialize \occ with -6

The first two pseudo instruction insert the macor plinst to compile the instructions "lac \sx1" and "lio \sy1", effecting in the object code to load the x-position and the y-position of the current object (the spaceship) into the accumulator and the IO register respectively. Then "clf 6" clears program flag 6 and the macro setup (which we've already seen in Part 3) sets the variable \occ to the value -6 to be used as a count-up.

By now, the compiled code is:

	stf 5
	lac \sx1
	lio \sy1

As we may remember from Part 3, the variables \sx1 and \sy1 are containing the x and y coordinates of the current spaceship in the format used by the dpy instruction (with the most significant 10 bits indicating the position and the lower 8 bits ignored). Thus, in the compiled code, AC and IO are now pointing to the very first display location as stored in \sx1 and \sy1.

ocg,	lio .		/outline table  // load current data word into IO
och,	cla		// clear AC
	rcl 3s		// rotate first three bits (first nibble) of IO into AC
	dio \oci	// store rest in \oci
	lio (rcl 9s	// load constant "rcl 9s" into IO
	dispatch	// like FORTRAN computed GO TO on contents of AC
	opr		// case 0: nop, fall through
	jmp oc1		// case 1
oco,	jmp oc2		// case 2
ocq,	jmp oc3		// case 3
ocp,	jmp oc4		// case 4
ocr,	jmp oc5		// case 5
	jmp oc6		// case 6
	...		// case 7

With this initial setup done, we're heading straight to the actual parsing. At ocg the lio instruction loads the contents of the current data word (this being the very first location, inserted previously by a dap instruction) into the IO register. The next instruction "rcl 3s" (rotate combined registers left) rotates the highest three bits (or nibble, or the first octal digit) into the accumulator, with the remainder stored in the variable \oci for later use. As we can already see, the commands creating the outlines are encoded in three bits or a single octal digit. Since there are 6 of them in an 18-bit word, we also can now understand, why the counter occ would have been initialized for a countup from -6. The next pseudo instruction inserts the production of the macro dispatch, which is quite the equivalent of a FORTRAN computed GO TO statement (or, as we would call this in assembler, is setting up a jump by a dispatch table):

	define
dispatch
	add (. 3	// add current address + 3 (first after macro) to AC
	dap . 1		// deposit in next address
	jmp .		// and jump there
	term

The macro effects in an indexed jump to any of the 7 locations following immediately after its insertion.
(In case you would wonder, this macro is defined at the top of the source of part 1, in the section containing the macros specific to Spacewar!. This placement and the fact that it is used only here once, suggests that this might have been a piece of code used more commonly by the original outline interpreter.)

The first instruction of the dispatch table, executed in case that the accumulator would contain 0, is a simple opr, synonymous to nop (no operation). This will simply fall through to the next case.

The next jmp instructions cover the cases for the acumulator containing any value in the range 1..6, and with 7, we would continue with the code following to these jump vectors.

Let's see, what's happening, in case we would take the jump to oc1 for a nibble of value 1 in our data word:

oc1,	plinst (add \ssn	// compile "add \ssn"
	jsp ocs			// copy IO to the next 2 addresses at oc (swap)
	lac (sub \scn		// load "sub \scn" into AC
oce,	dac i oc		// display action: deposit AC at current code location
	idx oc			// increment oc
	jsp ocs			// copy IO to the next 2 addresses at oc (swap)
	plinst (ioh		// compile "ioh" (wait for completion pulse)
	lac (dpy-4000		// load "dpy-400" into AC
ocd,	dac i oc		// deposit at current code location
	idx oc			// increment oc
	lio \oci		// advance to next nibble or word: load \oci in IO
	count \occ, och		// increment \occ (up from -6), while negative,
				// jump to och (get next nibble and execute switch)
	idx ocg			// increment ocg (next data word)
	jmp ocj			// start over with the new data word

After compiling "add \ssn" by inserting macro plinst (we'll explore the semantics of these variables soon), the jump to the subroutine ocs effects in the compiliation of twice the contents of IO:

ocs,	dap ocz		/puts in swap // deposit return address in ocz
	dio i oc	// deposit IO in address in oc
	idx oc		// increment oc
	dio i oc	// deposit IO in address in oc
	idx oc		// increment oc
ocz,	jmp .		// return

Since the IO register was set up to contain the value of the constant expression "rcl 9s", this will insert the equivalent of the macro swap, we've seen already in Part 2: Two consecutive instructions to rotate AC and IO as a combined register by 9 bits, resulting in an exchange of the contents of the two registers. As we may remember, this was used to set up AC for the x-coordinate of a dpy instruction, then swap the registers, compose the y-coordinate in the accumulator, and swap the registers back, now with the y-coordinate in IO and the x-coordinate in AC.

This is exactly what is compiled here: AC was set up in the compiled code to contain the current x-coordinate as in \sx1. This is now swapped and the accumulator is now containing the current y-position. The expression "sub \scn" is now compiled and this is followed by another call of ocs, inserting another swap.

The pseudo instruction "plinst (ioh" compiles a ioh instruction, resulting in the CPU to wait for the completion pulse sent by the CRT display. (For details, please refer to Part 2.) Then the constant expression for the actual display command "dpy-4000" is loaded into AC. At ocd this is put at the current end of the object code stack and the pointer oc is incremented once again.

By now, this inserted the following code production in the object code at oc, updating both the x and y coordinates, waiting for the display to be ready, and finally issuing a new display command:

	add \ssn
	rcl 9s
	rcl 9s
	sub \scn
	rcl 9s
	rcl 9s
	ioh
	dpy-4000

With the actual compilation done, we're left with advancing to the next nibble of the outline data (last few lines repeated from above):

	lio \oci		// advance to next nibble or word: load \oci in IO
	count \occ, och		// increment \occ (up from -6), while negative,
				// jump to och (get next nibble and execute switch)
	idx ocg			// increment ocg (next data word)
	jmp ocj			// start over with the new data word

This loads the rest of the rotated data word as stored previously in \oci into IO, just as befor at label ocg. The pseudo instruction "count \occ, och" performs the count-up on the 6 nibbles of the data word. (We've seen the macro count already in Part 3.) If \occ would be still negative after the increment, we would jump to label och, rotating the next nibble into AC. If the result would be positive, indicating we would have parsed all 6 nibbles already, we fall through to the next instruction, incrementing the address stored in ocg to advance to the next data word. This is then parsed by the jump to ocj, resetting the counter \occ, and starting over with the new data word.

Having investigated a full loop for parsing and compiling an outline code of 1, let's see whats happening with some other codes:

oc2,	comtab (add \scm, (add \ssm
oc3,	comtab (add \ssc, (sub \csm
oc4,	comtab (sub \scm, (sub \ssm
oc5,	comtab (add \csn, (sub \ssd

The jump vectors for the codes 2..5 will take us to the labels with the respective numbers at their end. Each of them inserts the macro comtab with two constant expressions as the arguments, each representing an instruction to be compiled. This is, what comtab (command tablutor ?) looks like:

define
	comtab A, B
	plinst A		// compile A in oc
	jsp ocs			// compile swap
	lac B			// put B into AC
	jmp oce			// display and advance
	terminate

This is compiling the first parameter into the current location of the object code, adds a swap to it (there's still "rcl 9s" in IO) and puts the value of the second parameter into the accumulator. Then it jumps to the label oce, we've seen before: This will compile the contents of AC, add another swap to the compiled code, as well as the ioh and dpy-4000 instructions, and execute the next iteration over the parse/compile loop.

Thus, macro comtab produces a compiled object code quite like the one we've seen before, with the notable difference of the instructions for updating the x and y coordinates by the expressions in A and B respectively:

	A		// first parameter (update x)
	rcl 9s
	rcl 9s
	B		// second parameter (update y)
	rcl 9s
	rcl 9s
	ioh
	dpy-4000

Note: An attentive reader might have noticed that this is the same production as the one of the code entered at oc1, even using the same instructions at label oce and beyond, but with parameters. Why isn't the code at oc1 just "comtab (add \ssn, (sub \scn"? We don't know, but it's quite as if the code at oc1 would be exemplifying the workings of the macro comtab which would be hidden in some indirectness else.

Movement Semantics

In order to understand the semantics of these code productions inserted by the outline codes 0...5, we'll have to peek ahead into some code of the main program, we haven't explored yet. By now, we only know that the outline commands will cause the following movements:

outline advance by x, y:

0: fall through to 1
1: +\ssn -\scn
2: +\scm +\ssm
3: +\ssc -\csm
4: -\scm -\ssm
5: +\csn -\ssd

Inside the code managing the spaceships, we'll find the following setup of these variables just before the call of the compiled outline code (at sp5), with \sn being the sine of the rotation angle in mth and \cs containing the cosine:

	scale \sn, 9s, \ssn	// store scaled sine in \ssn
	scale \cs, 9s, \scn	// store scaled cosine in \scn
	lac \ssn
	dac \ssm		// \ssm = \ssn
	add \scn
	dac \ssc		// \ssc = \ssn + \scn
	dac \ssd		// \ssd = \ssn + \scn
	lac \ssn
	sub \scn
	dac \csn		// \csn = \ssn - \scn
	cma			// complement AC
	dac \csm		// \csm = -\csn
	lac \scn
	dac \scm		// \scm = \scn
	cla cli-opr		// clear AC and IO
	dpy-4000		// display a dot in center, request completion pulse
sp5,	jmp .			// jump to compiled outline code
sq6,	ioh			// wait for last completion pulse

The two insertions of the macro scale are scaling the current sine and cosine to a value that would produce an advance by a single display location for a value of 1. (By altering the scaling factor as in 9s, we could enlarge the outline by multiplying the steps by powers of 2. This is also the trick applied by Barry Silverman, Brian Silverman, and Vadim Gerasimov in their version of the code of Spacewar! 3.1, modified to display the ships at double size for the benefit of modern displays, by changing this value to 8s.) Since the format of the positional values for the dpy instruction automatically allows for a fractional part of 8 binary digits, any values between 0 and 1 will be handled gracefully, with just the discrete integer parts used as the actual display location.

As we can see, rather than just supplying the turning angle (theta) of the ship, the required trigonometry is done in the main program. This is part of Steve Russell's "basic trick" of calculating the sine and cosine only once per frame and reusing them (resulting in something alike turning the entire universe), here by setting up a matrix of derivative values for the use of the compiled outline routines, which will have to deal with these positional offsets only. This is, what this matrix looks like, when the code produced by the outline compiler is called at label sq5:

\ssn = sin (scaled)
\scn = cos (scaled)
\ssm = \ssn
\ssc = \ssn + \scn
\ssd = \ssn + \scn
\csn = \ssn - \scn
\csm = -(\ssn - \scn)
\scm = \scn

Before we investigating these values, we may note the actual calling sequence of the compiled outline code: Since the compiled code is starting with a ioh, we would need to call a dpy-4000 instruction before (in order to provide the completion pulse by the display) or the code would be waiting for ever. This is provided by the combined cla (clear AC) and cli (clear IO) as in "cla cli-opr" and the following dpy-4000 display command. As this is resetting AC and IO to point to the origin at the center of the screen, there will be always a spot at the very center of the scope, even, if the "heavy star" would be disabled by activating sense switch 6. Likewise, the code produced by the compiler loop is ending in a dpy-4000 instruction, so there's a ioh to wait for and clear this final completion pulse at label sq6.

Back to the semantics of the outline code, we'll see that just some values are actually used to move the outline in the resulting code. This would translate to the following values and respective movements:

Movements by x, y:

code / theta (deg)          90        45          30        0
0: => 1
1: +sin       -cos         1 -0    0.7 -0.7    0.5 -0.8    0 -1
2: +cos       +sin         0  1    0.7  0.7    0.8  0.5    1  0
3: +(sin+cos) +(sin-cos)   1  1    1.4  0      1.3 -0.3    1 -1
4: -cos       -sin        -0 -1   -0.7 -0.7   -0.8 -0.5   -1  0
5: +(sin-cos) -(sin+cos)   1 -1    0   -1.4   -0.3 -1.3   -1 -1

Thus, for a rotation angle theta of 0, the following semantics apply to the outline codes 0..5:

0:           fall through to 1
1:   0 -1    down
2:   1  0    right
3:   1 -1    right down
4:  -1  0    left
5:  -1 -1    left down

So, what's happening at codes 6 and 7, and why are there 8 variables defined to encode just 5 distinctive values? Let's see:

Outline Pragmatics

The codes 6 and 7 may be referred to as the pragmatic part of the outline vocabulary. This is, what's happening at oc6, executed for code 6:

oc6,	szf 6			// flag 6: store or restore?
	jmp oc9			// set: restore position at oc9
	stf 6			// set flag 6 for visted, store position
	plinst (dac \ssa	// compile "dac \ssa" (deposit AC in \ssa)
	lac (dio \ssi		// load "dio \ssi"    (deposit IO in \ssi)
	jmp ocd			// compile and next nibble

oc9,	clf 6			// clear flag 6
	plinst (lac \ssa	// compile "lac \ssa" (load \ssa)
	lac (lio \ssi		// load "lio \ssi"    (load \ssi)
	jmp ocd			// compile and next nibble

So, based on flag 6 set or unset, this either compiles a code that will store the current x and y coordinates as in AC and IO in the variables \ssa and \ssi respectively, or will restore the current location from these. (Label ocd is the final part of the parser/compiler loop, depositing the contents of the accumulator in the current object-code address and advancing to the next nibble or word.)

Since flag 6 is initially cleared just before the start of the loop at label ocj, code 6 is alternatingly storing and restore the current display location for the outline.

The part covering code 7 is following immediately to the jump table with the vectors for code 1..6:

	plinst (szf 5	/7 code  // compile "szf 5"
	add (4			// add 4 (to oc)
	dap ocn			// deposit in address part of ocn
	plinst ocn		// compile "jmp ocn" (oc+4)
	plinst (dac \sx1	// compile "dac \sx1" (deposit AC in \sx1)
	plinst (dio \sy1	// compile  "dio \sx1" (deposit IO in \sy1)
	plinst (jmp sq6		// compile "jmp sq6" (return)

	plinst (clf 5		// compile "clf 5" (clear flag 5)
	plinst (lac \scm	// compile "lac \scm" (load \scm into AC)
	plinst (cma		// compile "cma" (complement AC)
	plinst (dac \scm	// compile "dac \scm" (\scm = -\scm)
	plinst (lac \ssm	// compile "lac \ssm"
	plinst (cma		// compile "cma"
	plinst (dac \ssm	// compile "dac \ssm" (\ssm = -\ssm)
	plinst (lac \csm	// compile "lac \csm"
	plinst (lio \ssd	// compile "lio \ssd"
	plinst (dac \ssd	// compile "dac \ssd" (swap \csm and \ssd)
	plinst (dio \csm	// compile "dio \csm" (--"--)
	plinst (lac \ssc	// compile "lac \ssc"
	plinst (lio \csn	// compile "lio \csn"
	plinst (dac \csn	// compile "dac \csn" (swap \csn and \ssc)
	plinst (dio \ssc	// compile "dio \ssc" (--"--)
	plinst ocm		// compile "jmp <start+1>" (start over)
ocx,	jmp .			// return

ocm,	jmp .
ocn,	jmp .

As we can see by the jump instruction at label ocx, a code of 7 is ending the compilition. Also, as we've seen all of the code of the outline compiler by now, a code 7 must be the last command of any outline data, else the compiler will not return. (Since the current value of oc is also left by plinst in the accumulator, when executing the jump at ocx, the location of the next instruction follwing immediately after the object code will be returned thus in the accumulator to the main program.)

On the pragmatic side, this is producing the following object code as the final coda of the assembled stream:

szf 5		// flag 5 zero?
jmp . + 4	// no, not visited yet, skip next three instructions
dac \sx1	// yes, update \sx1 and \sx2 to current outline position
dio \sy1
jmp sq6		// return (sq6 is a label in the main program)

clf 5		// clear flag 5
lac \scm
cma
dac \scm	// \scm = -\scm
lac \ssm
cma
dac \ssm	// \ssm = -\ssm
lac \csm
lio \ssd
dac \ssd	// swap \ssd and \csm
dio \csm
lac \ssc
lio \csn
dac \csn	// swap \csn and \ssc
dio \ssc
jmp <ocm>	// start+1

As we may remember, a "stf 5" (set flag 5) was the very first instruction compiled at the head of the resulting outline code. Now this flag is checked. If still set, we haven't seen this code production by command 7 yet and jump to the "clf 5" instruction 4 locations ahead, clearing this flag. The next instructions are either complementing or swapping all values related to left and right movements, then the code jumps to the very beginning, just after the initial set flag 5 to start over with the same code, but now drawing the left side.

If we would return from this second run, as indicated by a cleared flag 5, the code stores the current position of the outline in \sx1 and \sy1, the x and y coordinates of the spaceship currently handled. Thanks to this, any exhaust trail to be displayed for a thrusting ship will be drawn at the exact tail position, what ever shape would be described by the outline data.

Now, we may provide the complete instruction set of the outline compiler, properly replacing any references to left and right by in and out, referring to either an inward or outward direction relative to the central y-axis:

0:  synonymous to 1
1:  down
2:  out
3:  out & down
4:  in
5:  in & down
6:  store /restore current position
7:  draw other side / return

Note: Actually, we might exchange the terms "out" and "in". Applying them as described here, we would start in a clockwise motion — as used in Spacewar!. By interchanging them, we would still achieve a visually similar result, but now by drawing the first half of the outline in a counterclockwise motion. This is much like describing (a cross section of) a lathe object by describing the curve defining its surface: It doesn't matter, which side of the object we would actually describe, as long as we're using directions consistently.

Constraints

An attentive reader may have already noticed the following constraints applied to any outline data, to be properly contemplated by any ardent hacker of spaceship outlines (remember the extra space of 4 instruction words appended to each of the data tables?):

It's also this very last constraint, which might shed some light on the else superfluous outline code 0 that is still the very first code of the outline data for the second spaceship, the "wedge", as defined in ot2: This might have originally served as some kind of elaborated NOP, spending the runtime consumed by any of the other outline commands (each of them being of the same length and cycle count), while effecting essentially in a void instruction, just to compensate for any timing differences. (Please mind that this just a guess and not confirmed by any historical sources or references.)

 

Sticking to our usual procedures, this would be just the place to investigate a (prominent) variations of the main theme of the article as to be found in some versions of Spacewar!. — But not this time!

The outline compiler was that a success, it didn't see any variations or modifications at all, just like the data defining the outline of two spaceships.

With nothing else to show, we're closing here with the disassembly of the productions of the outline compiler for both of the spaceships:

The Object Code

Disassembly of the spaceship outline code produced by the outline compiler, locations as in Spacewar! 3.1 (labels c1m and c2m inserted by me, N.L.):

spaceship 1

ot1,	111131
	111111
	111111
	111163
	311111
	146111
	111114
	700000

loc.    instr.     opcode       symbols

3772    760015     stf 5        stf 5
3773    203225     lac 3225     c1m,	lac \sx1
3774    223226     lio 3226     lio \sy1
3775    403223     add 3223     add \ssn
3776    663777     rcl 9s       rcl 9s
3777    663777     rcl 9s       rcl 9s
4000    423224     sub 3224     sub \scn
4001    663777     rcl 9s       rcl 9s
4002    663777     rcl 9s       rcl 9s
4003    730000     ioh          ioh
4004    724007     dpy-4000     dpy-4000
4005    403223     add 3223     add \ssn
4006    663777     rcl 9s       rcl 9s
4007    663777     rcl 9s       rcl 9s
4010    423224     sub 3224     sub \scn
4011    663777     rcl 9s       rcl 9s
4012    663777     rcl 9s       rcl 9s
4013    730000     ioh          ioh
4014    724007     dpy-4000     dpy-4000
4015    403223     add 3223     add \ssn
4016    663777     rcl 9s       rcl 9s
4017    663777     rcl 9s       rcl 9s
4020    423224     sub 3224     sub \scn
4021    663777     rcl 9s       rcl 9s
4022    663777     rcl 9s       rcl 9s
4023    730000     ioh          ioh
4024    724007     dpy-4000     dpy-4000
4025    403223     add 3223     add \ssn
4026    663777     rcl 9s       rcl 9s
4027    663777     rcl 9s       rcl 9s
4030    423224     sub 3224     sub \scn
4031    663777     rcl 9s       rcl 9s
4032    663777     rcl 9s       rcl 9s
4033    730000     ioh          ioh
4034    724007     dpy-4000     dpy-4000
4035    403235     add 3235     add \ssc
4036    663777     rcl 9s       rcl 9s
4037    663777     rcl 9s       rcl 9s
4040    423233     sub 3233     sub \csm
4041    663777     rcl 9s       rcl 9s
4042    663777     rcl 9s       rcl 9s
4043    730000     ioh          ioh
4044    724007     dpy-4000     dpy-4000
4045    403223     add 3223     add \ssn
4046    663777     rcl 9s       rcl 9s
4047    663777     rcl 9s       rcl 9s
4050    423224     sub 3224     sub \scn
4051    663777     rcl 9s       rcl 9s
4052    663777     rcl 9s       rcl 9s
4053    730000     ioh          ioh
4054    724007     dpy-4000     dpy-4000
4055    403223     add 3223     add \ssn
4056    663777     rcl 9s       rcl 9s
4057    663777     rcl 9s       rcl 9s
4060    423224     sub 3224     sub \scn
4061    663777     rcl 9s       rcl 9s
4062    663777     rcl 9s       rcl 9s
4063    730000     ioh          ioh
4064    724007     dpy-4000     dpy-4000
4065    403223     add 3223     add \ssn
4066    663777     rcl 9s       rcl 9s
4067    663777     rcl 9s       rcl 9s
4070    423224     sub 3224     sub \scn
4071    663777     rcl 9s       rcl 9s
4072    663777     rcl 9s       rcl 9s
4073    730000     ioh          ioh
4074    724007     dpy-4000     dpy-4000
4075    403223     add 3223     add \ssn
4076    663777     rcl 9s       rcl 9s
4077    663777     rcl 9s       rcl 9s
4100    423224     sub 3224     sub \scn
4101    663777     rcl 9s       rcl 9s
4102    663777     rcl 9s       rcl 9s
4103    730000     ioh          ioh
4104    724007     dpy-4000     dpy-4000
4105    403223     add 3223     add \ssn
4106    663777     rcl 9s       rcl 9s
4107    663777     rcl 9s       rcl 9s
4110    423224     sub 3224     sub \scn
4111    663777     rcl 9s       rcl 9s
4112    663777     rcl 9s       rcl 9s
4113    730000     ioh          ioh
4114    724007     dpy-4000     dpy-4000
4115    403223     add 3223     add \ssn
4116    663777     rcl 9s       rcl 9s
4117    663777     rcl 9s       rcl 9s
4120    423224     sub 3224     sub \scn
4121    663777     rcl 9s       rcl 9s
4122    663777     rcl 9s       rcl 9s
4123    730000     ioh          ioh
4124    724007     dpy-4000     dpy-4000
4125    403223     add 3223     add \ssn
4126    663777     rcl 9s       rcl 9s
4127    663777     rcl 9s       rcl 9s
4130    423224     sub 3224     sub \scn
4131    663777     rcl 9s       rcl 9s
4132    663777     rcl 9s       rcl 9s
4133    730000     ioh          ioh
4134    724007     dpy-4000     dpy-4000
4135    403223     add 3223     add \ssn
4136    663777     rcl 9s       rcl 9s
4137    663777     rcl 9s       rcl 9s
4140    423224     sub 3224     sub \scn
4141    663777     rcl 9s       rcl 9s
4142    663777     rcl 9s       rcl 9s
4143    730000     ioh          ioh
4144    724007     dpy-4000     dpy-4000
4145    403223     add 3223     add \ssn
4146    663777     rcl 9s       rcl 9s
4147    663777     rcl 9s       rcl 9s
4150    423224     sub 3224     sub \scn
4151    663777     rcl 9s       rcl 9s
4152    663777     rcl 9s       rcl 9s
4153    730000     ioh          ioh
4154    724007     dpy-4000     dpy-4000
4155    403223     add 3223     add \ssn
4156    663777     rcl 9s       rcl 9s
4157    663777     rcl 9s       rcl 9s
4160    423224     sub 3224     sub \scn
4161    663777     rcl 9s       rcl 9s
4162    663777     rcl 9s       rcl 9s
4163    730000     ioh          ioh
4164    724007     dpy-4000     dpy-4000
4165    403223     add 3223     add \ssn
4166    663777     rcl 9s       rcl 9s
4167    663777     rcl 9s       rcl 9s
4170    423224     sub 3224     sub \scn
4171    663777     rcl 9s       rcl 9s
4172    663777     rcl 9s       rcl 9s
4173    730000     ioh          ioh
4174    724007     dpy-4000     dpy-4000
4175    403223     add 3223     add \ssn
4176    663777     rcl 9s       rcl 9s
4177    663777     rcl 9s       rcl 9s
4200    423224     sub 3224     sub \scn
4201    663777     rcl 9s       rcl 9s
4202    663777     rcl 9s       rcl 9s
4203    730000     ioh          ioh
4204    724007     dpy-4000     dpy-4000
4205    403223     add 3223     add \ssn
4206    663777     rcl 9s       rcl 9s
4207    663777     rcl 9s       rcl 9s
4210    423224     sub 3224     sub \scn
4211    663777     rcl 9s       rcl 9s
4212    663777     rcl 9s       rcl 9s
4213    730000     ioh          ioh
4214    724007     dpy-4000     dpy-4000
4215    403223     add 3223     add \ssn
4216    663777     rcl 9s       rcl 9s
4217    663777     rcl 9s       rcl 9s
4220    423224     sub 3224     sub \scn
4221    663777     rcl 9s       rcl 9s
4222    663777     rcl 9s       rcl 9s
4223    730000     ioh          ioh
4224    724007     dpy-4000     dpy-4000
4225    403223     add 3223     add \ssn
4226    663777     rcl 9s       rcl 9s
4227    663777     rcl 9s       rcl 9s
4230    423224     sub 3224     sub \scn
4231    663777     rcl 9s       rcl 9s
4232    663777     rcl 9s       rcl 9s
4233    730000     ioh          ioh
4234    724007     dpy-4000     dpy-4000
4235    403223     add 3223     add \ssn
4236    663777     rcl 9s       rcl 9s
4237    663777     rcl 9s       rcl 9s
4240    423224     sub 3224     sub \scn
4241    663777     rcl 9s       rcl 9s
4242    663777     rcl 9s       rcl 9s
4243    730000     ioh          ioh
4244    724007     dpy-4000     dpy-4000
4245    403223     add 3223     add \ssn
4246    663777     rcl 9s       rcl 9s
4247    663777     rcl 9s       rcl 9s
4250    423224     sub 3224     sub \scn
4251    663777     rcl 9s       rcl 9s
4252    663777     rcl 9s       rcl 9s
4253    730000     ioh          ioh
4254    724007     dpy-4000     dpy-4000
4255    243237     dac 3237     dac \ssa
4256    323240     dio 3240     dio \ssi
4257    403235     add 3235     add \ssc
4260    663777     rcl 9s       rcl 9s
4261    663777     rcl 9s       rcl 9s
4262    423233     sub 3233     sub \csm
4263    663777     rcl 9s       rcl 9s
4264    663777     rcl 9s       rcl 9s
4265    730000     ioh          ioh
4266    724007     dpy-4000     dpy-4000
4267    403235     add 3235     add \ssc
4270    663777     rcl 9s       rcl 9s
4271    663777     rcl 9s       rcl 9s
4272    423233     sub 3233     sub \csm
4273    663777     rcl 9s       rcl 9s
4274    663777     rcl 9s       rcl 9s
4275    730000     ioh          ioh
4276    724007     dpy-4000     dpy-4000
4277    403223     add 3223     add \ssn
4300    663777     rcl 9s       rcl 9s
4301    663777     rcl 9s       rcl 9s
4302    423224     sub 3224     sub \scn
4303    663777     rcl 9s       rcl 9s
4304    663777     rcl 9s       rcl 9s
4305    730000     ioh          ioh
4306    724007     dpy-4000     dpy-4000
4307    403223     add 3223     add \ssn
4310    663777     rcl 9s       rcl 9s
4311    663777     rcl 9s       rcl 9s
4312    423224     sub 3224     sub \scn
4313    663777     rcl 9s       rcl 9s
4314    663777     rcl 9s       rcl 9s
4315    730000     ioh          ioh
4316    724007     dpy-4000     dpy-4000
4317    403223     add 3223     add \ssn
4320    663777     rcl 9s       rcl 9s
4321    663777     rcl 9s       rcl 9s
4322    423224     sub 3224     sub \scn
4323    663777     rcl 9s       rcl 9s
4324    663777     rcl 9s       rcl 9s
4325    730000     ioh          ioh
4326    724007     dpy-4000     dpy-4000
4327    403223     add 3223     add \ssn
4330    663777     rcl 9s       rcl 9s
4331    663777     rcl 9s       rcl 9s
4332    423224     sub 3224     sub \scn
4333    663777     rcl 9s       rcl 9s
4334    663777     rcl 9s       rcl 9s
4335    730000     ioh          ioh
4336    724007     dpy-4000     dpy-4000
4337    403223     add 3223     add \ssn
4340    663777     rcl 9s       rcl 9s
4341    663777     rcl 9s       rcl 9s
4342    423224     sub 3224     sub \scn
4343    663777     rcl 9s       rcl 9s
4344    663777     rcl 9s       rcl 9s
4345    730000     ioh          ioh
4346    724007     dpy-4000     dpy-4000
4347    403223     add 3223     add \ssn
4350    663777     rcl 9s       rcl 9s
4351    663777     rcl 9s       rcl 9s
4352    423224     sub 3224     sub \scn
4353    663777     rcl 9s       rcl 9s
4354    663777     rcl 9s       rcl 9s
4355    730000     ioh          ioh
4356    724007     dpy-4000     dpy-4000
4357    423231     sub 3231     sub \scm
4360    663777     rcl 9s       rcl 9s
4361    663777     rcl 9s       rcl 9s
4362    423232     sub 3232     sub \ssm
4363    663777     rcl 9s       rcl 9s
4364    663777     rcl 9s       rcl 9s
4365    730000     ioh          ioh
4366    724007     dpy-4000     dpy-4000
4367    203237     lac 3237     lac \ssa
4370    223240     lio 3240     lio \ssi
4371    403223     add 3223     add \ssn
4372    663777     rcl 9s       rcl 9s
4373    663777     rcl 9s       rcl 9s
4374    423224     sub 3224     sub \scn
4375    663777     rcl 9s       rcl 9s
4376    663777     rcl 9s       rcl 9s
4377    730000     ioh          ioh
4400    724007     dpy-4000     dpy-4000
4401    403223     add 3223     add \ssn
4402    663777     rcl 9s       rcl 9s
4403    663777     rcl 9s       rcl 9s
4404    423224     sub 3224     sub \scn
4405    663777     rcl 9s       rcl 9s
4406    663777     rcl 9s       rcl 9s
4407    730000     ioh          ioh
4410    724007     dpy-4000     dpy-4000
4411    403223     add 3223     add \ssn
4412    663777     rcl 9s       rcl 9s
4413    663777     rcl 9s       rcl 9s
4414    423224     sub 3224     sub \scn
4415    663777     rcl 9s       rcl 9s
4416    663777     rcl 9s       rcl 9s
4417    730000     ioh          ioh
4420    724007     dpy-4000     dpy-4000
4421    403223     add 3223     add \ssn
4422    663777     rcl 9s       rcl 9s
4423    663777     rcl 9s       rcl 9s
4424    423224     sub 3224     sub \scn
4425    663777     rcl 9s       rcl 9s
4426    663777     rcl 9s       rcl 9s
4427    730000     ioh          ioh
4430    724007     dpy-4000     dpy-4000
4431    403223     add 3223     add \ssn
4432    663777     rcl 9s       rcl 9s
4433    663777     rcl 9s       rcl 9s
4434    423224     sub 3224     sub \scn
4435    663777     rcl 9s       rcl 9s
4436    663777     rcl 9s       rcl 9s
4437    730000     ioh          ioh
4440    724007     dpy-4000     dpy-4000
4441    403223     add 3223     add \ssn
4442    663777     rcl 9s       rcl 9s
4443    663777     rcl 9s       rcl 9s
4444    423224     sub 3224     sub \scn
4445    663777     rcl 9s       rcl 9s
4446    663777     rcl 9s       rcl 9s
4447    730000     ioh          ioh
4450    724007     dpy-4000     dpy-4000
4451    403223     add 3223     add \ssn
4452    663777     rcl 9s       rcl 9s
4453    663777     rcl 9s       rcl 9s
4454    423224     sub 3224     sub \scn
4455    663777     rcl 9s       rcl 9s
4456    663777     rcl 9s       rcl 9s
4457    730000     ioh          ioh
4460    724007     dpy-4000     dpy-4000
4461    403223     add 3223     add \ssn
4462    663777     rcl 9s       rcl 9s
4463    663777     rcl 9s       rcl 9s
4464    423224     sub 3224     sub \scn
4465    663777     rcl 9s       rcl 9s
4466    663777     rcl 9s       rcl 9s
4467    730000     ioh          ioh
4470    724007     dpy-4000     dpy-4000
4471    423231     sub 3231     sub \scm
4472    663777     rcl 9s       rcl 9s
4473    663777     rcl 9s       rcl 9s
4474    423232     sub 3232     sub \ssm
4475    663777     rcl 9s       rcl 9s
4476    663777     rcl 9s       rcl 9s
4477    730000     ioh          ioh
4500    724007     dpy-4000     dpy-4000
4501    640005     szf 5        szf 5
4502    604506     jmp 4506     jmp . 4
4503    243225     dac 3225     dac \sx1
4504    323226     dio 3226     dio \sy1
4505    602531     jmp 2531     jmp sq6
4506    760005     clf 5        clf 5
4507    203231     lac 3231     lac \scm
4510    761000     cma          cma
4511    243231     dac 3231     dac \scm
4512    203232     lac 3232     lac \ssm
4513    761000     cma          cma
4514    243232     dac 3232     dac \ssm
4515    203233     lac 3233     lac \csm
4516    223234     lio 3234     lio \ssd
4517    243234     dac 3234     dac \ssd
4520    323233     dio 3233     dio \csm
4521    203235     lac 3235     lac \ssc
4522    223236     lio 3236     lio \csn
4523    243236     dac 3236     dac \csn
4524    323235     dio 3235     dio \ssc
4525    603773     jmp 3773     jmp c1m


spaceship 2

ot2,	013113
	113111
	116313
	131111
	161151
	111633
	365114
	700000

loc.    instr.     opcode       symbols

4526    760015     stf 5        stf 5
4527    203225     lac 3225     c2m,  lac \sx1
4530    223226     lio 3226     lio \sy1
4531    403223     add 3223     add \ssn
4532    663777     rcl 9s       rcl 9s
4533    663777     rcl 9s       rcl 9s
4534    423224     sub 3224     sub \scn
4535    663777     rcl 9s       rcl 9s
4536    663777     rcl 9s       rcl 9s
4537    730000     ioh          ioh
4540    724007     dpy-4000     dpy-4000
4541    403223     add 3223     add \ssn
4542    663777     rcl 9s       rcl 9s
4543    663777     rcl 9s       rcl 9s
4544    423224     sub 3224     sub \scn
4545    663777     rcl 9s       rcl 9s
4546    663777     rcl 9s       rcl 9s
4547    730000     ioh          ioh
4550    724007     dpy-4000     dpy-4000
4551    403235     add 3235     add \ssc
4552    663777     rcl 9s       rcl 9s
4553    663777     rcl 9s       rcl 9s
4554    423233     sub 3233     sub \csm
4555    663777     rcl 9s       rcl 9s
4556    663777     rcl 9s       rcl 9s
4557    730000     ioh          ioh
4560    724007     dpy-4000     dpy-4000
4561    403223     add 3223     add \ssn
4562    663777     rcl 9s       rcl 9s
4563    663777     rcl 9s       rcl 9s
4564    423224     sub 3224     sub \scn
4565    663777     rcl 9s       rcl 9s
4566    663777     rcl 9s       rcl 9s
4567    730000     ioh          ioh
4570    724007     dpy-4000     dpy-4000
4571    403223     add 3223     add \ssn
4572    663777     rcl 9s       rcl 9s
4573    663777     rcl 9s       rcl 9s
4574    423224     sub 3224     sub \scn
4575    663777     rcl 9s       rcl 9s
4576    663777     rcl 9s       rcl 9s
4577    730000     ioh          ioh
4600    724007     dpy-4000     dpy-4000
4601    403235     add 3235     add \ssc
4602    663777     rcl 9s       rcl 9s
4603    663777     rcl 9s       rcl 9s
4604    423233     sub 3233     sub \csm
4605    663777     rcl 9s       rcl 9s
4606    663777     rcl 9s       rcl 9s
4607    730000     ioh          ioh
4610    724007     dpy-4000     dpy-4000
4611    403223     add 3223     add \ssn
4612    663777     rcl 9s       rcl 9s
4613    663777     rcl 9s       rcl 9s
4614    423224     sub 3224     sub \scn
4615    663777     rcl 9s       rcl 9s
4616    663777     rcl 9s       rcl 9s
4617    730000     ioh          ioh
4620    724007     dpy-4000     dpy-4000
4621    403223     add 3223     add \ssn
4622    663777     rcl 9s       rcl 9s
4623    663777     rcl 9s       rcl 9s
4624    423224     sub 3224     sub \scn
4625    663777     rcl 9s       rcl 9s
4626    663777     rcl 9s       rcl 9s
4627    730000     ioh          ioh
4630    724007     dpy-4000     dpy-4000
4631    403235     add 3235     add \ssc
4632    663777     rcl 9s       rcl 9s
4633    663777     rcl 9s       rcl 9s
4634    423233     sub 3233     sub \csm
4635    663777     rcl 9s       rcl 9s
4636    663777     rcl 9s       rcl 9s
4637    730000     ioh          ioh
4640    724007     dpy-4000     dpy-4000
4641    403223     add 3223     add \ssn
4642    663777     rcl 9s       rcl 9s
4643    663777     rcl 9s       rcl 9s
4644    423224     sub 3224     sub \scn
4645    663777     rcl 9s       rcl 9s
4646    663777     rcl 9s       rcl 9s
4647    730000     ioh          ioh
4650    724007     dpy-4000     dpy-4000
4651    403223     add 3223     add \ssn
4652    663777     rcl 9s       rcl 9s
4653    663777     rcl 9s       rcl 9s
4654    423224     sub 3224     sub \scn
4655    663777     rcl 9s       rcl 9s
4656    663777     rcl 9s       rcl 9s
4657    730000     ioh          ioh
4660    724007     dpy-4000     dpy-4000
4661    403223     add 3223     add \ssn
4662    663777     rcl 9s       rcl 9s
4663    663777     rcl 9s       rcl 9s
4664    423224     sub 3224     sub \scn
4665    663777     rcl 9s       rcl 9s
4666    663777     rcl 9s       rcl 9s
4667    730000     ioh          ioh
4670    724007     dpy-4000     dpy-4000
4671    403223     add 3223     add \ssn
4672    663777     rcl 9s       rcl 9s
4673    663777     rcl 9s       rcl 9s
4674    423224     sub 3224     sub \scn
4675    663777     rcl 9s       rcl 9s
4676    663777     rcl 9s       rcl 9s
4677    730000     ioh          ioh
4700    724007     dpy-4000     dpy-4000
4701    403223     add 3223     add \ssn
4702    663777     rcl 9s       rcl 9s
4703    663777     rcl 9s       rcl 9s
4704    423224     sub 3224     sub \scn
4705    663777     rcl 9s       rcl 9s
4706    663777     rcl 9s       rcl 9s
4707    730000     ioh          ioh
4710    724007     dpy-4000     dpy-4000
4711    243237     dac 3237     dac \ssa
4712    323240     dio 3240     dio \ssi
4713    403235     add 3235     add \ssc
4714    663777     rcl 9s       rcl 9s
4715    663777     rcl 9s       rcl 9s
4716    423233     sub 3233     sub \csm
4717    663777     rcl 9s       rcl 9s
4720    663777     rcl 9s       rcl 9s
4721    730000     ioh          ioh
4722    724007     dpy-4000     dpy-4000
4723    403223     add 3223     add \ssn
4724    663777     rcl 9s       rcl 9s
4725    663777     rcl 9s       rcl 9s
4726    423224     sub 3224     sub \scn
4727    663777     rcl 9s       rcl 9s
4730    663777     rcl 9s       rcl 9s
4731    730000     ioh          ioh
4732    724007     dpy-4000     dpy-4000
4733    403235     add 3235     add \ssc
4734    663777     rcl 9s       rcl 9s
4735    663777     rcl 9s       rcl 9s
4736    423233     sub 3233     sub \csm
4737    663777     rcl 9s       rcl 9s
4740    663777     rcl 9s       rcl 9s
4741    730000     ioh          ioh
4742    724007     dpy-4000     dpy-4000
4743    403223     add 3223     add \ssn
4744    663777     rcl 9s       rcl 9s
4745    663777     rcl 9s       rcl 9s
4746    423224     sub 3224     sub \scn
4747    663777     rcl 9s       rcl 9s
4750    663777     rcl 9s       rcl 9s
4751    730000     ioh          ioh
4752    724007     dpy-4000     dpy-4000
4753    403235     add 3235     add \ssc
4754    663777     rcl 9s       rcl 9s
4755    663777     rcl 9s       rcl 9s
4756    423233     sub 3233     sub \csm
4757    663777     rcl 9s       rcl 9s
4760    663777     rcl 9s       rcl 9s
4761    730000     ioh          ioh
4762    724007     dpy-4000     dpy-4000
4763    403223     add 3223     add \ssn
4764    663777     rcl 9s       rcl 9s
4765    663777     rcl 9s       rcl 9s
4766    423224     sub 3224     sub \scn
4767    663777     rcl 9s       rcl 9s
4770    663777     rcl 9s       rcl 9s
4771    730000     ioh          ioh
4772    724007     dpy-4000     dpy-4000
4773    403223     add 3223     add \ssn
4774    663777     rcl 9s       rcl 9s
4775    663777     rcl 9s       rcl 9s
4776    423224     sub 3224     sub \scn
4777    663777     rcl 9s       rcl 9s
5000    663777     rcl 9s       rcl 9s
5001    730000     ioh          ioh
5002    724007     dpy-4000     dpy-4000
5003    403223     add 3223     add \ssn
5004    663777     rcl 9s       rcl 9s
5005    663777     rcl 9s       rcl 9s
5006    423224     sub 3224     sub \scn
5007    663777     rcl 9s       rcl 9s
5010    663777     rcl 9s       rcl 9s
5011    730000     ioh          ioh
5012    724007     dpy-4000     dpy-4000
5013    403223     add 3223     add \ssn
5014    663777     rcl 9s       rcl 9s
5015    663777     rcl 9s       rcl 9s
5016    423224     sub 3224     sub \scn
5017    663777     rcl 9s       rcl 9s
5020    663777     rcl 9s       rcl 9s
5021    730000     ioh          ioh
5022    724007     dpy-4000     dpy-4000
5023    403223     add 3223     add \ssn
5024    663777     rcl 9s       rcl 9s
5025    663777     rcl 9s       rcl 9s
5026    423224     sub 3224     sub \scn
5027    663777     rcl 9s       rcl 9s
5030    663777     rcl 9s       rcl 9s
5031    730000     ioh          ioh
5032    724007     dpy-4000     dpy-4000
5033    203237     lac 3237     lac \ssa
5034    223240     lio 3240     lio \ssi
5035    403223     add 3223     add \ssn
5036    663777     rcl 9s       rcl 9s
5037    663777     rcl 9s       rcl 9s
5040    423224     sub 3224     sub \scn
5041    663777     rcl 9s       rcl 9s
5042    663777     rcl 9s       rcl 9s
5043    730000     ioh          ioh
5044    724007     dpy-4000     dpy-4000
5045    403223     add 3223     add \ssn
5046    663777     rcl 9s       rcl 9s
5047    663777     rcl 9s       rcl 9s
5050    423224     sub 3224     sub \scn
5051    663777     rcl 9s       rcl 9s
5052    663777     rcl 9s       rcl 9s
5053    730000     ioh          ioh
5054    724007     dpy-4000     dpy-4000
5055    403236     add 3236     add \csn
5056    663777     rcl 9s       rcl 9s
5057    663777     rcl 9s       rcl 9s
5060    423234     sub 3234     sub \ssd
5061    663777     rcl 9s       rcl 9s
5062    663777     rcl 9s       rcl 9s
5063    730000     ioh          ioh
5064    724007     dpy-4000     dpy-4000
5065    403223     add 3223     add \ssn
5066    663777     rcl 9s       rcl 9s
5067    663777     rcl 9s       rcl 9s
5070    423224     sub 3224     sub \scn
5071    663777     rcl 9s       rcl 9s
5072    663777     rcl 9s       rcl 9s
5073    730000     ioh          ioh
5074    724007     dpy-4000     dpy-4000
5075    403223     add 3223     add \ssn
5076    663777     rcl 9s       rcl 9s
5077    663777     rcl 9s       rcl 9s
5100    423224     sub 3224     sub \scn
5101    663777     rcl 9s       rcl 9s
5102    663777     rcl 9s       rcl 9s
5103    730000     ioh          ioh
5104    724007     dpy-4000     dpy-4000
5105    403223     add 3223     add \ssn
5106    663777     rcl 9s       rcl 9s
5107    663777     rcl 9s       rcl 9s
5110    423224     sub 3224     sub \scn
5111    663777     rcl 9s       rcl 9s
5112    663777     rcl 9s       rcl 9s
5113    730000     ioh          ioh
5114    724007     dpy-4000     dpy-4000
5115    403223     add 3223     add \ssn
5116    663777     rcl 9s       rcl 9s
5117    663777     rcl 9s       rcl 9s
5120    423224     sub 3224     sub \scn
5121    663777     rcl 9s       rcl 9s
5122    663777     rcl 9s       rcl 9s
5123    730000     ioh          ioh
5124    724007     dpy-4000     dpy-4000
5125    243237     dac 3237     dac \ssa
5126    323240     dio 3240     dio \ssi
5127    403235     add 3235     add \ssc
5130    663777     rcl 9s       rcl 9s
5131    663777     rcl 9s       rcl 9s
5132    423233     sub 3233     sub \csm
5133    663777     rcl 9s       rcl 9s
5134    663777     rcl 9s       rcl 9s
5135    730000     ioh          ioh
5136    724007     dpy-4000     dpy-4000
5137    403235     add 3235     add \ssc
5140    663777     rcl 9s       rcl 9s
5141    663777     rcl 9s       rcl 9s
5142    423233     sub 3233     sub \csm
5143    663777     rcl 9s       rcl 9s
5144    663777     rcl 9s       rcl 9s
5145    730000     ioh          ioh
5146    724007     dpy-4000     dpy-4000
5147    403235     add 3235     add \ssc
5150    663777     rcl 9s       rcl 9s
5151    663777     rcl 9s       rcl 9s
5152    423233     sub 3233     sub \csm
5153    663777     rcl 9s       rcl 9s
5154    663777     rcl 9s       rcl 9s
5155    730000     ioh          ioh
5156    724007     dpy-4000     dpy-4000
5157    203237     lac 3237     lac \ssa
5160    223240     lio 3240     lio \ssi
5161    403236     add 3236     add \csn
5162    663777     rcl 9s       rcl 9s
5163    663777     rcl 9s       rcl 9s
5164    423234     sub 3234     sub \ssd
5165    663777     rcl 9s       rcl 9s
5166    663777     rcl 9s       rcl 9s
5167    730000     ioh          ioh
5170    724007     dpy-4000     dpy-4000
5171    403223     add 3223     add \ssn
5172    663777     rcl 9s       rcl 9s
5173    663777     rcl 9s       rcl 9s
5174    423224     sub 3224     sub \scn
5175    663777     rcl 9s       rcl 9s
5176    663777     rcl 9s       rcl 9s
5177    730000     ioh          ioh
5200    724007     dpy-4000     dpy-4000
5201    403223     add 3223     add \ssn
5202    663777     rcl 9s       rcl 9s
5203    663777     rcl 9s       rcl 9s
5204    423224     sub 3224     sub \scn
5205    663777     rcl 9s       rcl 9s
5206    663777     rcl 9s       rcl 9s
5207    730000     ioh          ioh
5210    724007     dpy-4000     dpy-4000
5211    423231     sub 3231     sub \scm
5212    663777     rcl 9s       rcl 9s
5213    663777     rcl 9s       rcl 9s
5214    423232     sub 3232     sub \ssm
5215    663777     rcl 9s       rcl 9s
5216    663777     rcl 9s       rcl 9s
5217    730000     ioh          ioh
5220    724007     dpy-4000     dpy-4000
5221    640005     szf 5        szf 5
5222    605226     jmp 5226     jmp . 4
5223    243225     dac 3225     dac \sx1
5224    323226     dio 3226     dio \sy1
5225    602531     jmp 2531     jmp sq6
5226    760005     clf 5        clf 5
5227    203231     lac 3231     lac \scm
5230    761000     cma          cma
5231    243231     dac 3231     dac \scm
5232    203232     lac 3232     lac \ssm
5233    761000     cma          cma
5234    243232     dac 3232     dac \ssm
5235    203233     lac 3233     lac \csm
5236    223234     lio 3234     lio \ssd
5237    243234     dac 3234     dac \ssd
5240    323233     dio 3233     dio \csm
5241    203235     lac 3235     lac \ssc
5242    223236     lio 3236     lio \csn
5243    243236     dac 3236     dac \csn
5244    323235     dio 3235     dio \ssc
5245    604527     jmp 4527     jmp c2m

 

The actual advance over the outline data for each of the spaceships can also be investigated in the illustration at the top of this page.

In case you would have cleared your internal program flag 5 and would be skipping this full loop, there's no more left, but to resort to a final "Stay tuned …"

 

Norbert Landsteiner
Vienna, July 2014
www.masswerk.at

 

In case you would have found any errors or inconsistencies, or would have additional information,
please contact me.

*****

Previous:   Part 3: Objects!
Next:   Part 5: Maneuvering in Space

Back to the index.