Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REMat line 0. The display file base address is computed and stored inDISP. Speed is collected from the user and POKEd into memory. - Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514. - End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BESTand name inZ$. - Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04(DB 04) for keyboard input. - Uses
EXX(D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops. - Compares character codes against
$80to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention). - Writes
$80and$00into display RAM cells to mark bricks as hit. - Stores ball direction state in addresses
$40AC(16556) and$40AD(16557). - Uses
DJNZloops (10 ECsequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773. - Returns to BASIC via
C9(RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5sets the initial ball X-direction state.POKE 16518,Fsets the serve position (column), stepping in increments of 5 across the five cycles.- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
| Name / Address | Purpose |
|---|---|
DISP | Base address of display file (from PEEK 16396/16397) |
BEST | Highest score achieved this session |
Z$ | Name of high-score holder |
I | Speed setting (1–9), POKEd to 16773 |
F | Serve loop counter (5, 10, 15, 20, 25) |
B | Remaining balls (starts at 5) |
| 16514 | Entry point of machine-code game engine in REM |
| 16556 ($40AC) | Ball X-direction state |
| 16557 ($40AD) | Ball Y-direction state |
| 16773 | Speed delay parameter for the MC engine |
Notable Techniques and Observations
- The ball lives counter
Bis displayed atAT 0,30and decremented each serve cycle, giving the player exactly five serves per game. - Block graphic characters (
\.. \:etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set. - The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R)for R=1..4. - The
RAND USRidiom is the standard Spectrum BASIC method for calling machine code, using the fact thatRANDOMIZE USR addrsets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57151 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.7 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.5"
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\FE
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E\AC\FE\C8\FE
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\AD\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57151 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.7 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.5"FE
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\AD
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\CDE\FE\CDAA\AC\FEE\ACE\AC\CD\E0\CD\CD\E0\CD
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\AA
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\E5\C5B\DB\FEB\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57151 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.7 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.5"D
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\FE
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57151 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.7 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.5" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57151 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.7 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.5"
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\CD
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CDA\AD\FE
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
FE\FE
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
AE
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\ADE\AC
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E\FE
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
CE\AC\D9\C1\C5\D9
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\ECA\AD\FE
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
FE\FE
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
AE
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\ADE\AC\C1\E1\C9\D5\C5
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\C5
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\C1
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\C1\D1\C9\F8\E5
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
CEC\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57151 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.7 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.5"C
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\F2\E1\C9\C5 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57151 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.7 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.5"
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Brick Buster
This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Brick Buster is a breakout-style arcade game in which the player serves a ball to knock out rows of bricks displayed across the top of the screen. The game loop uses RAND USR 16514 to execute a machine-code routine embedded in the REM statement at line 0, which handles all real-time ball physics, collision detection, and display updates. Speed is configurable from 1 (fastest) to 9 and is POKEd into address 16773, while the serve angle is controlled by timing an INKEY$ poll waiting for “S”. The score is read back from display memory by inspecting character codes at offsets from the display file base address (calculated at startup via PEEK 16396/16397), and a high-score table with player name entry is maintained across successive plays.
Program Analysis
Program Structure
The program is organised into several functional phases:
- Initialisation (lines 0–50): The machine-code payload is stored in the
REM at line 0. The display file base address is computed and stored in DISP. Speed is collected from the user and POKEd into memory.
- Screen setup (lines 60–130): The playfield is drawn — a title bar, left/right border characters, and seven rows of brick characters filling columns 1–30.
- Game loop (lines 135–200): Five serve cycles step through positions 5, 10, 15, 20, and 25. Each cycle waits for the player to press “S”, then calls the machine-code engine via
RAND USR 16514.
- End sequence (lines 210–300): Score is decoded from display RAM, compared to the best score, and a flashing “PRESS P TO PLAY AGAIN” prompt is shown using an alternating inverse/normal text loop.
- High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in
BEST and name in Z$.
- Save/auto-run (lines 500–510): Saves the program and re-runs it.
Machine Code Engine
The core game logic — ball movement, collision detection with bricks and borders, and score updating — is entirely implemented in the Z80 machine code embedded in the REM statement at line 0. The routine is entered via RAND USR 16514; address 16514 is the first byte of the REM payload (the REM token itself sits at 16512, the length bytes at 16513–16514 on a 16 KB machine, but the payload bytes begin immediately after the length field, placing executable code at the correct offset).
Key observable behaviours from the raw hex include:
- Reads from I/O port
$04 (DB 04) for keyboard input.
- Uses
EXX (D9) to switch between register banks, a classic Z80 trick for preserving state across inner loops.
- Compares character codes against
$80 to detect whether a display cell contains a brick (set characters have bit 7 clear, while cleared cells or special graphics have bit 7 set — or vice versa depending on convention).
- Writes
$80 and $00 into display RAM cells to mark bricks as hit.
- Stores ball direction state in addresses
$40AC (16556) and $40AD (16557).
- Uses
DJNZ loops (10 EC sequence) for timing delays, with the delay count controlled by the speed value POKEd into 16773.
- Returns to BASIC via
C9 (RET) when the ball is lost.
Display File Score Reading
Rather than maintaining a numeric score variable in BASIC, the score is read back from the display file itself at line 240:
LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
The machine code writes digit characters directly into the top rows of the display (one digit per brick row destroyed). BASIC then reconstructs the numeric score by subtracting 28 (the character code offset for digits in the Spectrum/TS2068 character set, where '0' = 28 in display file encoding) and multiplying by the appropriate power of ten. This is an elegant technique that avoids any score variable passing between BASIC and machine code.
Serve Angle Mechanism
Lines 150–170 implement serve control:
POKE 16556,5 sets the initial ball X-direction state.
POKE 16518,F sets the serve position (column), stepping in increments of 5 across the five cycles.
- The spin loop at line 170 (
IF INKEY$<>"S" THEN GOTO 170) waits for the player to press S, so the moment of keypress determines the serve timing.
Flashing Prompt Technique
Lines 280–300 implement a flashing “PRESS P TO PLAY AGAIN” message without using the Spectrum’s FLASH attribute. Instead, lines 282–287 alternate between printing the message in inverse video (%P%R%E%S%S%...) and in normal video, each separated by a short FOR...NEXT delay loop of 30 iterations. The GOTO 280 at line 300 creates an infinite loop until P is pressed.
Key Variables and Addresses
Name / Address Purpose DISPBase address of display file (from PEEK 16396/16397) BESTHighest score achieved this session Z$Name of high-score holder ISpeed setting (1–9), POKEd to 16773 FServe loop counter (5, 10, 15, 20, 25) BRemaining balls (starts at 5) 16514 Entry point of machine-code game engine in REM 16556 ($40AC) Ball X-direction state 16557 ($40AD) Ball Y-direction state 16773 Speed delay parameter for the MC engine
Notable Techniques and Observations
- The ball lives counter
B is displayed at AT 0,30 and decremented each serve cycle, giving the player exactly five serves per game.
- Block graphic characters (
\.. \: etc.) are used for the border and title bar decorations, making use of the full Spectrum block graphic set.
- The score reconstruction loop (lines 230–250) correctly handles a four-digit score with weights 1000, 100, 10, 1 via
10**(4-R) for R=1..4.
- The
RAND USR idiom is the standard Spectrum BASIC method for calling machine code, using the fact that RANDOMIZE USR addr sets up HL and calls the address as a Z80 subroutine.
Content
Source Code
0 REM \11\10\16\01\0A\16\78\FE\02\20\07\3E\04\32\AC\40\18\03\FE\18\C8\79\FE\02\20\07\3E\0C\32\AD\40\18\09\FE\1F\20\05\3E\0D\32\AD\40\05\0D\CD\55\41\7E\FE\08\20\16\CD\6A\41\3A\AC\40\FE\05\20\07\3E\04\32\AC\40\18\05\3E\05\32\AC\40\36\80\CD\E0\40\CD\82\41\CD\E0\40\CD\82\41\36\00\18\AA\00\00\E5\C5\42\4B\DB\04\FE\3B\20\08\79\FE\1D\28\0D\0C\18\0A\FE\2F\20\06\79\FE\01\28\01\0D\CD\55\41\36\00\23\36\03\23\36\03\23\36\00\05\CD\55\41\3A\AD\40\FE\0C\20\0F\7E\FE\80\20\0A\3E\0D\32\AD\40\3E\05\32\AC\40\06\02\23\7E\FE\80\20\0C\3E\05\32\AC\40\D9\C1\06\14\C5\D9\00\10\EC\23\3A\AD\40\FE\0D\20\0F\7E\FE\80\20\0A\3E\0C\32\AD\40\3E\05\32\AC\40\59\C1\E1\C9\D5\C5\2A\0C\40\C5\06\00\09\C1\11\21\00\10\03\C1\D1\C9\19\18\F8\E5\2A\0C\40\23\23\23\23\7E\3C\FE\26\28\03\77\18\05\36\1C\2B\18\F2\E1\C9\C5\01\00\09\0B\78\B1\20\FB\C1\C9\24\25\1C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\B1\FB\C1\C9 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57151 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.7 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.5"C
5 LET DISP=PEEK 16396+256*PEEK 16397
10 LET BEST=0
15 CLS
20 PRINT "ENTER SPEED 1 TO 9 (1=FASTEST)"
25 PRINT AT 3,6;"<=5....8=> S=SERVE"
30 INPUT I
40 IF I<1 OR I>9 THEN GOTO 30
50 POKE 16773,I
60 CLS
70 PRINT "\ .0000\..\..\..\..\..BRICK BUSTER\..\..\..\..\..\..\..\..\..\. "
80 FOR F=1 TO 20
90 PRINT AT F,0;"\ :";TAB 31;"\: "
100 NEXT F
110 FOR F=1 TO 7
120 PRINT AT F,1;"\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##\##"
130 NEXT F
135 LET B=5
136 PRINT AT 0,30;B
140 FOR F=5 TO 25 STEP 5
150 POKE 16556,5
160 POKE 16518,F
170 IF INKEY$<>"S" THEN GOTO 170
175 LET B=B-1
176 PRINT AT 0,30;B
180 RAND USR 16514
190 PRINT AT 21,0;" "
200 NEXT F
210 PRINT AT 0,10;"\..GAME OVER\.."
220 LET SCORE=0
230 FOR R=1 TO 4
240 LET SCORE=SCORE+(PEEK (DISP+R+1)-28)*10**(4-R)
250 NEXT R
260 IF SCORE>BEST THEN GOSUB 400
270 PRINT AT 9,1;" BEST SCORE IS ";BEST;AT 10,INT ((32-LEN Z$-3)/2);"BY ";Z$
280 PRINT AT 12,4;"%P%R%E%S%S% %"%P%"% %T%O% %P%L%A%Y% %A%G%A%I%N"
281 PRINT AT 0,10;"BRICK BUSTER"
282 FOR Q=0 TO 30
283 NEXT Q
284 PRINT AT 12,4;"PRESS ""P"" TO PLAY AGAIN"
285 PRINT AT 0,10;"\..GAME OVER\.."
286 FOR Q=0 TO 30
287 NEXT Q
290 IF INKEY$="P" THEN GOTO 15
300 GOTO 280
410 LET BEST=SCORE
420 PRINT AT 2,2;"YOU NOW HAVE THE BEST SCORE"
430 PRINT AT 4,1;"ENTER YOUR NAME (1-27 LETTERS)"
440 INPUT Z$
450 RETURN
500 SAVE "1010%0"
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
