INTRODUCTION

Macronics produced a version of Space Invaders for the 1K ZX80 and also an expanded version of Space Invaders for the 3K ZX80. Both were produced in 1981 (or possibly 1980), and could be purchased pre-recorded on cassette or as a printed listing. The game was referred to as both Space Intruders (Source: Your Computer, Vol. 1 No. 5, December 1981) and Space Invaders (Souce: Computer & Video Games, Issue 1, November 1981), and was also ported to the ZX80 with 8K ROM / ZX81. The original listing of the 1K version of the game is not currently available on the Internet and hence not publicly archived, but it is hopefully held in a private collection somewhere and will one day surface. However, a close study of the few Macronics programs that survive for the ZX80 and a comparison with their ZX80 with 8K ROM / ZX81 counterparts provides enough information to make a conjecture of how the 1K ZX80 (4K ROM) Space Invaders program would have been. To support both the ZX81 and the ZX80 fitted with the upgrade ROM, the game includes its own video driver routine. This generates all lines of the TV display in software just as the ZX81 does in FAST mode to provide compatibility with the ZX80 hardware. In addition, by making minor modifications to this video driver routine it is possible to get the same game running on a ZX80 with its original 4K ROM. This page documents an analysis of 8K ROM version of 1K Space Invaders and presents a reconstructed version for the 4K ROM ZX80.

The reconstructed game file (along with the ZX81 original) is available from the downloads section.


DESCRIPTION

Macronics' 1K Space Invaders implements a 16 row by 31 column cut-down version of the arcade classic.


Screenshot of 1K ZX80 Space Invaders

There are 8 invaders to destroy and the player only has a single life to do this with. The player moves left using keys 5 or 6 and right using keys 8 or 3. A missile is fired using keys 0 or 1. Only one missile may be fired at a time, and the invaders can only drop one bomb at a time. It is sometimes possible for a missile and a bomb to annihilate each other. Each time an invader is hit, the score increases by a value of 1. Once a wave has been destroyed, it is replaced by new wave identical to the previous one. The display shows the current score in the bottom left hand corner and the previous game's score in the bottom right hand corner.



LOADER RECONSTRUCTION

The machine code for the game is too large to be encoded within PRINT statements as is done with the 3K version of the game. Instead a BASIC program allows the machine code bytes to be typed in and stored within an array. Macronics sold the game both on cassette and as a listing, and hence this why the BASIC program allows the user to type in the program bytes. A small transfer machine code program is also stored within the array. When the game is run, it is the transfer routine that is actually run and it copies the rest of the program bytes to address $4000 (16384). The BASIC program for the ZX81 version and a suggested alternative for the ZX80 are shown below.


Program Listing of 1K ZX81 Space Invaders Program Listing of 1K ZX80 Space Invaders
ZX81 Version ZX80 Version

The ZX81 version stores the machine code bytes in a string array. A loop is used to allow each byte to be entered. Once all bytes have been entered, the loop can be executed again using GOTO 20 and can now be used to verify each byte entered. Pressing NEWLINE will move to the next array entry without modifying the current entry. Once the entry of the machine code bytes has been verified, the complete program should be saved to cassette. The game is then be run by typing GOTO 100.

The ZX80 does not support string arrays and so instead an integer array must be used. The ZX80 only allows integer arrays of up to 256 entries in size, but this is sufficient to hold the game bytes. The ZX80 also does not support the VAL function and so the preview option present in the ZX81 version is not reproduced. Using an integer array requires typing in signed integer values instead of unsigned bytes. There is no evidence that Macronics stored the machine code bytes in an integer array but 1K is not enough space to store hex bytes in PRINT statements and so another mechanism must have been used. Storing machine code in an array was a well known technique, as can be seen by the fact it was described in Toni Baker's Mastering Machine Code on the ZX81 and ZX80. Once the machine code bytes have been typed in the complete program should be saved to cassette. The game can then be run by typing GO TO 100.

Program Bytes of 1K ZX80 Space Invaders (Part 1) Program Bytes of 1K ZX80 Space Invaders (Part 2) Program Bytes of 1K ZX80 Space Invaders (Part 3) Program Bytes of 1K ZX80 Space Invaders (Part 4)

To modify the game to run on USA models of the ZX80 (60 Hz), change the two values coloured red: change '20494' to '14350' and '-12976' to '-13000'.


GAME RECONSTRUCTION

The comparison of the assembly listings for the the ZX80 and ZX81 versions of 3K Space Invaders shows that they differ only in the video generation routine and a few character codes. The rest of the program is identical and runs from exactly the same memory locations. The same is also true between the ZX80 and ZX81 versions of Breakout. This approach allowed Macronics to develop a single program which would only require minimal changes to get it running on the two platforms. To achieve this, the ZX81 version of the game generates the TV display entirely in software, just as is done when the machine operates in FAST mode. In effect, Macronics chose to by-pass the SLOW mode functionality provided by the ZX81 hardware, and this also allowed the game to be run on a ZX80 fitted with the new ROM upgrade.

The listings below show side by side comparisons of the ZX81 and ZX80 video routines for both 3K Space Invaders:

OUT  ($FD),A   ; Vertical sync generator off.

; Generate the top border and main display area.

LD   A,$EA     ; First scan line timing counter.
LD   B,$19     ; 24 rows and 1 for the top border.
LD   C,$30     ; 48 lines in the top border.
LD   HL,$C4FF  ; Display file address (bit 15 set).
CALL $02B5     ; Produce the top border and main area.

; Generate the bottom border.

LD   A,$E7     ; First scan line timing counter.
INC  B         ; Set the row count to $01.
DEC  HL        ; Point back to the last HALT.
LD   C,$2F     ; 47 lines in the bottom border.
CALL $02B5     ; Produce the bottom border.
OUT  ($FE),A   ; Vertical sync generator off.

; Generate the top border and main display area.

LD   A,$ED     ; First scan line timing counter.
LD   B,$19     ; 24 rows and 1 for the top border.

LD   HL,$C4FF  ; Display file address (bit 15 set).
CALL $01AD     ; Produce the top border and main area.

; Generate the bottom border.

LD   A,$F0     ; First scan line timing counter.
INC  B         ; Set the row count to $01.
DEC  HL        ; Point back to the last HALT.
DEC  (IY+$23)  ; 47 lines in the bottom border.
CALL $01AD     ; Produce the bottom border.
3K Space Invaders Video Routine - ZX81 Version 3K Space Invaders Video Routine - ZX80 Version

A similar video routine is used in 1K Breakout. The listings below show side by side comparisons of the ZX81 and ZX80 video routines for both 1K Breakout:

OUT  ($FD),A   ; Vertical sync generator off.

; Generate the top border and main display area.

LD   C,$38     ; 56 lines in the top border.
LD   A,$EC     ; First scan line timing counter.
LD   B,$19     ; 24 rows and 1 for the top border.
LD   HL,$C0FF  ; Display file address (bit 15 set).
CALL $02B5     ; Produce the top border and main area.

; Generate the bottom border.

LD   A,$E8     ; First scan line timing counter.
INC  B         ; Set the row count to $01.
DEC  HL        ; Point back to the last HALT.
NOP
LD   C,$37     ; 55 lines in the bottom border.
CALL $02B5     ; Produce the bottom border.
OUT  ($FE),A   ; Vertical sync generator off.

; Generate the top border and main display area.


LD   A,$EC     ; First scan line timing counter.
LD   B,$19     ; 24 rows and 1 for the top border.
LD   HL,$C0FF  ; Display file address (bit 15 set).
CALL $01AD     ; Produce the top border and main area.

; Generate the bottom border.

LD   A,$F0     ; First scan line timing counter.
INC  B         ; Set the row count to $01.
DEC  HL        ; Point back to the last HALT.
DEC  (IY+$23)  ; 55 lines in the bottom border.

CALL $01AD     ; Produce the bottom border.
1K Breakout Video Routine - ZX81 Version 1K Breakout Video Routine - ZX80 Version

The similarities between the ZX80 and ZX81 versions of the video routines is very clear. So given the ZX81 video routine for 1K Space Invaders it becomes possible to speculate how the equivalent ZX80 version would have been. The listings below show the ZX81 video routine for 1K Breakout and the corresponding version speculated for the ZX80:

OUT  ($FD),A   ; Vertical sync generator off.

; Generate the top border and main display area.

LD   A,$EF     ; First scan line timing counter.
LD   B,$11     ; 16 rows and 1 for the top border.
LD   HL,$C1FF  ; Display file address (bit 15 set).
LD   C,$50     ; 80 lines in the top border.
CALL $02B5     ; Produce the top border and main area.

; Generate the bottom border.

LD   A,$E8     ; First scan line timing counter.
INC  B         ; Set the row count to $01.
DEC  HL        ; Point back to the last HALT.
LD   C,$50     ; 80 lines in the bottom border.
CALL $02B5     ; Produce the bottom border.
OUT  ($FE),A   ; Vertical sync generator off.

; Generate the top border and main display area.

LD   A,$EE     ; First scan line timing counter.
LD   B,$11     ; 16 rows and 1 for the top border.
LD   HL,$C1FF  ; Display file address (bit 15 set).
LD   C,$50     ; Not used by the ZX80 version.
CALL $01AD     ; Produce the top border and main area.

; Generate the bottom border.

LD   A,$EC     ; First scan line timing counter.
INC  B         ; Set the row count to $01.
DEC  HL        ; Point back to the last HALT.
LD   C,$50     ; Not used by the ZX80 version.
CALL $01AD     ; Produce the bottom border.
1K Space Invaders Video Routine - ZX81 Version 1K Space Invaders Video Routine - Speculated ZX80 Version

The only other changes to the game code are different character codes for the graphics used to represent the invaders and the invader's bombs. The ZX81's character codes of $87, $0B and $04 for an invader become $07, $01 and $06 for the ZX80, and the ZX81 character code $97 for an invader bomb becomes $94 for the ZX80.


GAME OPERATION

The game itself is structured to execute in four blocks of program functionality. These blocks are cycled through, with one block executed per TV field. The functionality blocks perform the following actions:

Move row of invaders left or right - At each invocation, the routine moves all invader characters on a particular row by one position left or right. Every character on a row is shifted each time, whether blank or not, and hence this ensures that the routine completes after a fixed duration of time. The area that the invaders can occupy spans rows 0 to 8, although once the invaders move onto row 8 they become immobile and will be overwritten when the blank line above is eventually shifted down. If all invaders move to row 8 then it is no longer possible to complete the wave or to restart the game without reloading it. On the odd rows the invaders are shifted to the right, and on the even rows they are shifted to the left. Hence the invaders appear to zig-zag their way down the screen. Rows are shifted in decending order, beginning with row 7 and ending with row 0. Initially the invaders are located at the left hand side of the screen and so are shifted to the right. The invaders are shifted by eight columns before they reach the edge of the screen and are moved down a row. The invaders cannot occupy columns 0 or 31, and so these are always filled with black spaces. These black spaces are shifted along with the invaders, thereby overwriting the 'trail' character left by the outer invader. Only the black space 'following' the invaders is shifted for a row and so neither columns of black spaces are ever overwritten.

Move invader bomb and fired missile - This routine first checks whether there is an active invader bomb and if so it moves it one row down the screen. If it reaches row 16 then the bomb has missed the base and so is discarded. If it has not reached row 16 then a check is made to see if the bomb has hit a shield. If it has then that character in the shield is removed. If a shield was not hit then a check is made to see if the bomb has hit the missile base. If it has then the game is over. If the bomb has not hit anything then it is drawn at its new position. The routine then checks whether there is an active missile and moves it up one row if there is one. A check is made to see whether the missile has moved off the top of the screen, and hence can be discarded. If the missile is still on screen then a check is made to see whether it has hit an invader bomb. If it has then the missile destroys the bomb. If the missile has not hit an invader bomb then a test is performed to see if it has hit a shield. If it has then that character in the shield is removed. If a shield was not hit then a test is made to see if an invader was hit. If one was then it is erased from the screen and the score incremented. If the missile did not hit anything then it is drawn at its new position.

Read keyboard and move missile base - This routine reads the top row of the keyboard. The row is electrically wired as two sets of 5 keys, and normally only one set would be read at a time. By reading them together means that cursor keys 5 (left) and 8 (right) and 0 (fire) are all read in one go. However, it also means that key 1 cannot be differentiated from key 0, key 8 cannot be differentiated from key 3, and key 5 cannot be differentiated from key 6. The missile base can be moved between columns 2 to 28 on row 15.

Test whether to drop an invader bomb - This routine searches the invader area from row 7 up to row 0 at the column where the missile base is. It searches for an invader that is directly above the missile base and sets a flag when one is found. Since all rows are checked, this flag ensures that the lowest invader found is the one that drops the bomb. The way the routine has been written means that it is possible for the routine to write to the first page of the ROM area when there is no active invader bomb and no active missile.


DOWNLOADS

Click here to download 1K ZX80 (4K ROM) Space Invaders reconstruction in .O program format. Run the game using GO TO 100.
Click here to download 1K ZX80 (8K ROM) / ZX81 Space Invaders in .P and .P81 program formats. The file name is "V1". Run the game using GOTO 100.
Click here to download a disassembly of the 1K ZX80 (8K ROM) / ZX81 Space Invaders game.

Contact Me
  -   Disclaimer