Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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"



Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
A\FE

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
E\AC\FE\C8\FE

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
E

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
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

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
D\AD

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
D\CDE\FE\CDAA\AC\FEE\ACE\AC\CD\E0\CD\CD\E0\CD

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
\AA

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
\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

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
D

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
C

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
A\FE

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
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"

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
D\CD

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
\CDA\AD\FE

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
C

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
FE\FE

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
AE

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
D\ADE\AC

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
E\FE

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
CE\AC\D9\C1\C5\D9

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
\ECA\AD\FE

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
D

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
FE\FE

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
AE

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
C\ADE\AC\C1\E1\C9\D5\C5

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
A

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
C\C5

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
\C1

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
\C1\D1\C9\F8\E5

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
A

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
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

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
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"

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top

Brick Buster

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. High-score entry (lines 410–450): Called as a subroutine when a new best is achieved; stores score in BEST and name in Z$.
  6. 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 / AddressPurpose
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)
16514Entry point of machine-code game engine in REM
16556 ($40AC)Ball X-direction state
16557 ($40AD)Ball Y-direction state
16773Speed 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

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.

Scroll to Top
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.

People

No people associated with this content.

Scroll to Top