A flicker-free version of Breakout was created by Macronics for the 1K ZX80 in 1980, and could be purchased pre-recorded on cassette or as a printed listing. The instructions for the game states a copyright date of 1980. The game was still being advertised in late 1981 and was also ported to the ZX80 with 8K ROM / ZX81 (Souce: Computer & Video Games, Issue 1, November 1981). Note that this game will only work with a UK (50 Hz) version of the ZX80, but it can be easily modified to run on a USA model (60 Hz) as detailed later.
The game file is available from the downloads section.
Macronics' 1K Breakout implements a full screen (24 row by 31 column) cut-down version of the arcade classic.
There are four rows of bricks (shown as '*') and the player must bounce a ball against the wall to knock out the bricks. There are a total of ten balls per game, and it is the ball character itself that displays how many are remaining ('9' to '0'). A ball is lost if it is not bounced back up by the bat. The player moves left using keys 5 or 6 and right using keys 8 or 3. The game will continue even once all bricks have been knocked out, and will automatically restart when all balls have been lost.
An advert for the game appears below (source: Computer & Video Games, Issue 1, November 1981):
|Computer & Video Games magazine
Issue 1, November 1981
Like Space Invaders, the game is written entirely in machine code and is encoded within a BASIC program using the same method. This method was probably chosen to allow the game to be presented in a manner which could be sold as a printed listing. However, it has another advantage. If the program had been embedded in a REM statement (as typically done for machine code programs on the ZX81) then the ZX80 would likely become corrupt if any attempt to list the REM statement were made. Corruption would occur because the ZX80 interprets a newline character as signifying the end of a BASIC line. When a newline character is encountered within a REM statement then the bytes following it are interpreted as the start of a new BASIC line, and the ROM attempts to display them as such. Since the ROM locates each BASIC line by scanning for the terminating newline character, it becomes unable to locate genuine BASIC lines within the program and so cannot run them.
The program listing for Breakout is shown below:
The BASIC program begins by jumping to line 300. This routine reads the characters stored in string M$, converts pairs of hexadecimal characters into byte values, and pokes these into memory forming a short machine code routine. This machine code routine is then run, and it performs a similar function to the BASIC routine that constructed it. The routine interprets the pairs of hexadecimal characters found in all BASIC lines with line number less than 256 and commencing with a PRINT command, and stores them in memory. The bytes form the Breakout game. The last line to interpret is identified when the high byte of the line number is $00, and hence the last possible line that the routine could process is line 255.
The machine code loader routine stores the interpreted byte values at address $4000 onwards, which is where the system variables and BASIC program normally reside. Therefore as the bytes of the Breakout game are being constructed in RAM, the BASIC program listing it is being constructed from is overwritten. Note that there is no danger of the constructed game inadvertently overwriting BASIC program lines that are still to be interpreted since two hexadecimal characters within a PRINT command corresponds to only a single byte of the game. The fact that the BASIC program gets overwritten means that the loader routine must end by running the game. If it were to attempt to return to BASIC then a crash would result. While the game is being constructed in RAM, the ZX80 will not generate a TV picture and hence the screen will remain black.
To modify the game to run on USA models of the ZX80 (60 Hz), change the two hex digits coloured red in line 30 from values '38' to '20'.
The flicker-free mechanism used within Breakout is similar to 3K Space Invaders but does not reduce the number of generated scan lines by 16. Instead all of the functionality of the game can be implemented within the 425ms span used for the vertical sync pulse.
Like 3K Space Invaders, 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 the ball.
- Read the keyboard and move the bat.
- Do nothing, just perform a delay.
- Read the keyboard and move the bat.
A check for a move of the bat is made twice as often as moving the ball and hence the speed of the bat is double that of the ball. Note that the tolerance on the duration of the program functionality blocks is much wider than on Space Invaders.
Move the ball - This routine moves the ball and handles all boundary and collision detection. Horizontal and vertical direction offsets are keep and each added to the ball position on each cycle. If the left or right edge of the screen is hit (identified by checking for a newline character) then the horizontal direction offset is negated. The horizontal direction offset can either hold the value $0001 (+1) or $FFFF (-1). If the top of the screen is hit, a brick hit, the bat hit or the bottom of the screen hit then the vertical direction offset is negated. The horizontal direction offset can either hold the value $0020 (+32) or $FFE0 (-32). The display file is situated such that its first visible character is at location $4100, and due to the row length of 31 characters means that the last visible character is at location $43FF. This allows the program to easily detect when the ball moves above or below the screen by checking if the high byte of the display file position is $40 (off the top of the screen) or $44 (off the bottom of the screen). The game looks two steps ahead of the ball to determine whether a direction change is required. This means that the ball will always be moved in the current direction before a change of direction can occur. This ensures that the ball will move onto a brick character, thereby by overwriting it, and will be replaced with a black space when the ball is next moved. If there is a subsequent brick character ahead in the current direction then a change of direction will be noted. The ball will move in this new direction at the next cycle.
Read keyboard and move the bat - 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) are both read in one go. However, it also means that key 8 cannot be differentiated from key 3, and key 5 cannot be differentiated from key 6. The bat can be moved between columns 0 to 30 on row 23. The bat is 5 characters wide and hence the centre of the bat can only be moved between columns 2 to 28.
Delay - This block simply executes a delay of similar length to the other blocks. It is present as a result of the control logic supporting four blocks due to the need to allow the bat to move twice as often as the ball. It also helps set the speed of the game.
|Click here to download 1K ZX80 (4K ROM) Breakout in .O program format. Run the game using RUN.|
|Click here to download a scan of the original 1K ZX80 (4K ROM) Breakout listing sheet.|
|Click here to download a disassembly of the 1K ZX80 (4K ROM) Breakout loader routine.|
|Click here to download a disassembly of the 1K ZX80 (4K ROM) Breakout game.|
|Click here to download 1K ZX80 (8K ROM) / ZX81 Breakout in .P and .P81 program formats. The file name is "B". Run the game using GOTO 100.|
If you have a Spectrum 128 or +2 and an Interface 2 then you can use the ZX80 (4K ROM) Breakout game with my ZX80 Emulator ROM cartridge.