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, 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 run on the ZX80 with the 8K ROM upgrade and hence the ZX81. For the 8K ROM version 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.
This page presents both the 4K ROM and 8K ROM versions of the game.
Macronics' 1K Space Invaders implements a 16 row by 31 column cut-down version of the arcade classic. The game appears as follows, although note that the display is heavily shifted to the left on the 4K ROM version such that there is no visible left-hand border. This might have been tolerated and displayed correctly on TVs at the time.
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.
Adverts for the game appears below (source: Computer & Video Games, Issue 1, November 1981, and Your Computer magazine, Vol. 1 No. 5, December 1981):
|Computer & Video Games magazine
Issue 1, November 1981
|Your Computer magazine
Vol. 1 No. 5, December 1981
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 machine code program (also stored within the array in the 8K ROM version, and poked directly into RAM in the 4K ROM version) is then used to transfer the game bytes to address $4000 (16384). The BASIC programs for the 4K ROM and 8K ROM versions are shown below.
|4K ROM Version||8K ROM Version|
The 8K ROM 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. This executes a short machine code transfer routine that copies the game bytes from the array to location $4000.
The 4K ROM does not support string arrays and so instead an integer array must be used. The 4K ROM only allows integer arrays of up to 256 entries in size, but this is sufficient to hold the game bytes. The 4K ROM also does not support the VAL function and so a different mechanism is used to allow review and modification of the bytes. The user is asked to input C to change the byte at the current location, or NEWLINE to skip to the next address, or E to exit the entry loop. 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. This pokes a shorty machine code transfer routine into RAM and then runs it to copy to contents of the game bytes held in the array to location $4000.
To modify the 4K ROM version to run on 60Hz models of the ZX80, enter the following before running the game: LET A(18)=14539.
To modify the 8K ROM version to run on 60Hz models of the ZX80, enter the following before running the game: LET A$(136)=56 and LET A$(145)=56.
The code for the 4K and 8K versions are essentially the same. The game 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 a row of invaders left or right.
- Move the invader bomb (if there is one active), and move a fired missile (if there is one active).
- Read the keyboard and move the missile base.
- Test whether to drop a new invader bomb.
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.
The comparison of the assembly listings for the 4K ROM and 8K ROM versions of 1K Space Invaders shows that they differ with respect to the video generation routine, the instructyions used to increment the sequence counter, a few timing constants as a result of the sequence counter changes and a few character codes. The rest of the program is identical and runs from exactly the same memory locations.
The listings below show the difference in how the sequence counter is incremented in the 4K ROM and 8K ROM versions:
POP HL ; Fetch the sequence counter. INC L ; Increment it. PUSH HL ; Save the updated sequence counter. IN A,($FE) ; Turn on the vertical sync generator. LD A,L ; Fetch the sequence counter. AND $03 ; Keep only the lower 2 bits. JR Z,L4096 ; Sequence 0 -> Move a row of invaders. CP $01 ; Sequence 1? JR Z,L40EF ; Move invader bomb and laser base missile. CP $02 ; Sequence 2? JP Z,L4166 ; Read keyboard and move laser base. CP $03 ; Sequence 3? JP Z,L41AD ; Check whether to drop new invader bomb.
IN A,($FE) ; Turn on the vertical sync generator. POP AF ; Fetch the sequence counter. INC A ; Increment it. PUSH AF ; Save the updated sequence counter. AND $03 ; Keep only the lower 2 bits. JR Z,L4096 ; Sequence 0 -> Move a row of invaders. DEC A ; Sequence 1? JR Z,L40EF ; Move invader bomb and laser base missile. DEC A ; Sequence 2? JP Z,L4166 ; Read keyboard and move laser base. DEC A ; Sequence 3? JP Z,L41AD ; Check whether to drop new invader bomb.
|4K ROM Sequence Counter||8K ROM Sequence Counter|
The listings below show the difference in video drivers for the 4K ROM and 8K ROM versions:
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,$11 ; 16 rows and 1 for the top border. LD HL,$C1FF ; Display file address (bit 15 set). CALL $01AD ; Produce the top border and main area. ; Generate the bottom border. LD A,$EB ; First scan line timing counter. INC B ; Set the row count to $01. DEC HL ; Point back to the last HALT. CALL $01AD ; Produce the bottom border.
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 scan 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 scan lines in the bottom border. CALL $02B5 ; Produce the bottom border.
|4K ROM Video Routine||8K ROM Video Routine|
Different character codes are used for the graphics representing the invaders and the invader's bombs. The 4K ROM version uses character codes of $07, $01 and $06 for the invaders where as in the 8K ROM version the codes are $87, $0B and $04. Also, the 4K ROM version uses character code $94 for an invader bomb where as in the 8K ROM version the code is $97.
|Click here to download 1K ZX80 (4K ROM) Space Invaders in .O program format. Run the game using GO TO 100.|
|Click here to download 1K ZX80 (8K ROM) 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 1K ZX80 Space Invaders, covering both the 4K and 8K ROM versions.|