Brickbuster is a Breakout-style bat-and-ball game where the player uses keyboard controls to deflect a ball and clear rows of bricks. The core game logic runs as machine code embedded in REM statements at lines 1 and 2, with BASIC handling setup, scoring, and the high-score table. The machine code routine is called via RAND USR at lines 100 and 180, with POKE statements at lines 150, 160, and 50 used to pass parameters such as speed, row position, and skill level into the machine code. A display variable is established at line 5 by reading the system variable at address 16396/16397 to locate the program’s own data area for score extraction, which is then assembled into a string and converted with VAL at line 230.
Program Analysis
Program Structure
The program is organized into several distinct phases controlled by BASIC, while the actual game physics and rendering run entirely in machine code:
- Initialization (lines 1–5): Two REM statements hold machine code. Line 5 calculates the address
Dof the program’s data area using system variables at 16396/16397. - Title / Speed Selection (lines 15–50): Clears the screen, prompts for a speed value 1–9, validates it, and POKEs it into address 16773.
- Game Loop (lines 100–200): Calls machine code to initialize the board (
RAND USR 16802), then iterates five waves (FOR F=5 TO 25 STEP 5), POKEing row and lives parameters before each serve and calling the game engine viaRAND USR 16514. - End of Game / High Score (lines 210–300): Reads four bytes from the data area to reconstruct the score string, compares against the best score, and optionally records a new champion name.
- High Score Entry (lines 400–450): Subroutine that accepts a player name via INPUT and stores it in
Z$. - Save / Restart (lines 500–510): SAVEs the program then RUNs it.
Machine Code Usage
The two leading REM statements are the most technically significant parts of the program. Line 1 contains the primary machine code payload (the game board initializer and physics engine), while line 2 holds a secondary routine. The BASIC entry points are:
RAND USR 16802(line 100): Calls the board setup routine, which appears to draw the brick field and reset game state.RAND USR 16514(line 180): Calls the main game loop — ball movement, collision detection, bat control, and scoring — returning to BASIC only when a life is lost.
Parameters are passed to the machine code purely through memory POKEs before the USR calls. Address 16773 holds the speed value; 16556 holds a lives/attempt counter (always set to 5); 16518 holds the current row multiplier F (5, 10, 15, 20, 25), which the machine code presumably uses to determine brick layout or scoring weight.
Score Extraction Technique
Because the score is maintained inside the machine code routine, retrieving it requires reading raw memory. Line 5 computes D as the base address of the program’s variable area:
LET D=PEEK 16396+256*PEEK 16397
Lines 220–230 then read four consecutive bytes at offsets +2 through +5 from D, construct a string S$ of their CHR$ equivalents, and recover the numeric score with VAL S$. This implies the machine code stores the score as four ASCII digit characters at a known offset within the BASIC program area — a compact and clever interface between machine code and BASIC.
Key BASIC Idioms
- Speed input validation: Lines 30–40 read
INKEY$, convert it to a code, subtract 28 (the offset from character code to digit value on this system), and loop until the result is in range 1–9. Line 31 guards against a spurious 118 (newline) code that could corrupt the input. - Inverse-video flash on prompt: Line 280 first PRINTs the “PRESS P TO PLAY AGAIN” message using inverse-video character escapes, then immediately overwrites it with a normal-video version at the same position — a trick to produce a brief visual flash without a PAUSE or timing loop.
- FOR loop as wave controller: The five-wave structure (
FOR F=5 TO 25 STEP 5) is elegant:Fdoubles as the loop counter and the parameter POKEd into the machine code, avoiding a separate variable. - Score display prefix: Line 110 PRINTs
AT 0,0;"▖0000", placing a block graphic and four placeholder zeros at the top-left, which the machine code presumably overwrites in-place as the score updates.
Notable Anomalies
- Line 20 contains a typo:
"ENTER SPEED 1 T0 9"uses the digit zero (0) instead of the letter O in “TO”. This is a display-only cosmetic issue. - Line 1000 is a REM comment reading
BAORD RUTEEN STARTS 16802(“BOARD ROUTINE STARTS 16802”), confirming the developer used this as an inline note. The misspellings are original. - The SAVE filename in line 500 uses an inverse-video
Rat the end of “BRICKBUSTE”, stored as an escape sequence in the listing.
Memory Map Summary
| Address | Role |
|---|---|
| 16514 | Entry point: main game engine (USR call) |
| 16556 | Lives counter (POKEd to 5 each wave) |
| 16773 | Speed parameter (1–9, POKEd from user input) |
| 16802 | Entry point: board initializer (USR call) |
| 16396/16397 | System variable: start of BASIC variables area |
| D+2 … D+5 | Score stored as 4 ASCII bytes by machine code |
Content
Source Code
1 REM 111016 1191678FE 220 73E 432AC4018 3FE18C879FE 220 73E C32AD4018 9FE1F20 53E D32AD40 4 CCD55417EFE 82016CD6A413AAC40FE 520 73E 432AC4018 53E 532AC4036B4CDE040CD8241CDE040CD824136 018AA 0 0E5C5424BDBFEFE3B20 879FE1D28 D C18 AFE2F20 679FE 128 1 DCD554136 02336 32336 32336 0 5CD55413AAD40FE C20 F7EFEB420 A3E D32AD403E 532AC40 6 2237EFEB420 C3E 532AC40D9C1 614C5D9 010EC233AAD40FE D20 F7EFEB420 A3E C32AD403E 532AC4059C1E1C9D5C52A C40C5 6 0 9C11121 010 3C1D1C91918F8E52A C40232323237E3CFE2628 37718 5361C2B18F2E1C9C5 1 0 2 B78B120FBC1C91B1B1B1B1B1B1B1B1B1B1B1B1B1B1B
2 REM E£RND7Q..7.'2Q..7( CLS Q. 77.':'Q :7:2Q##7$4 IF Q: 77( LOAD )3 .'$Q :;Q: 77( RUN TAN TAN
4 SLOW
5 LET D=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 T0 9 ""1""=FASTEST."
25 PRINT AT 2,6;"<< 5....8 >> S=SERVE"
30 LET I=CODE INKEY$
31 IF CODE INKEY$=118 THEN GOTO 30
32 LET I=I-28
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
100 RAND USR 16802
110 PRINT AT 0,0;" .0000"
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
169 PRINT AT 15,6;"PRESS ""S"" TO SERVE"
170 IF INKEY$<>"S" THEN GOTO 169
171 PRINT AT 15,6;" "
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,11;"GAME OVER"
220 LET S$=CHR$ (PEEK (D+2))+CHR$ (PEEK (D+3))+CHR$ (PEEK (D+4))+CHR$ (PEEK (D+5))
230 LET SCORE=VAL S$
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 10,1;"BEST SCORE IS ";BEST;" BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N";AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
400 CLS
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-9 LETTERS)"
435 PRINT AT 6,1;"LAST SKILL LEVEL PLAYED ";I
440 INPUT Z$
450 RETURN
500 SAVE "BRICKBUSTE%R"
510 RUN
1000 REM BAORD RUTEEN STARTS 16802
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
