--- title: "Bomb Smasher" id: 56513 type: "computer_media" slug: "bomb-smasher" url: "http://localhost/computer_media/bomb-smasher/" markdown_url: "http://localhost/computer_media/bomb-smasher.md" published_at: "2024-08-11T01:32:40+00:00" modified_at: "2026-04-02T00:34:33+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/08/SCR-20240810-spgb.png" excerpt: "Launch a projectile upward to smash randomly scattered bombs in this fast-paced shooter that uses machine code for smooth gameplay." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" indiv: - name: "M. Hampson" slug: "m-hampson" taxonomy: "indiv" url: "http://localhost/indiv/m-hampson/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_type: "Cassette" programmers: - name: "M. Hampson" slug: "m-hampson" taxonomy: "indiv" url: "http://localhost/indiv/m-hampson/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Bomb%20Smasher%20%28198x%29%28TS1000%29%28US%29%28Cassette%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/08/SCR-20240810-spgb.png" - url: "http://localhost/wp-content/uploads/2024/08/BombSmasher.jpg" media_type_tags: "Game" --- Bomb Smasher is a vertically scrolling shooter in which the player launches a projectile upward from a fixed horizontal position to destroy randomly placed bomb targets. The program uses a machine code routine embedded in the REM statement at line 1, called via RAND USR 16514, to handle movement or display logic outside of BASIC’s speed constraints. Target bombs are scattered across the screen using RND at program start, rendered as inverse-video asterisk characters. The player fires by pressing any key, and the shot travels upward one row per loop iteration; collision is detected by PEEKing the display file address to check for a non-space character at the projectile’s current position. *** ## Program Analysis ### Program Structure The program is organized into several logical blocks: - **Lines 1–32:** Machine code storage, screen initialization, and random bomb placement. - **Lines 40–50:** Variable initialization (`B` = bullet active flag, `S` = score). - **Lines 100–190:** Main game loop — moves the bullet, checks collision, redraws. - **Lines 200–230:** Wait for keypress, launch bullet from row 22. - **Lines 300–330:** Game over screen, waits for SPACE (CHR$ 118), then restarts. - **Lines 400–420:** Score increment, bullet reset on hit. ### Machine Code Routine The `REM` statement at line 1 contains 31 bytes of Z80 machine code. It is invoked at line 110 with `RAND USR 16514`. The address 16514 corresponds to the start of the program in RAM (16509 for the system variable area start + a small offset into the REM data). Disassembling the bytes: - `\2A\0C\40` — `LD HL,(400Ch)`: loads a display-related address. - `\06\18` — `LD B,24`: sets a counter for 24 rows. - `\C5` — `PUSH BC` - `\23\7E\32\21\40` — increments HL, loads A from (HL), stores it to a fixed address. - `\5D\23\01\1F\00\ED\B0` — uses `LDIR` to copy 31 bytes, implementing a scroll or display-copy operation. - `\2B\3A\21\40\77\23\C1\10\E9` — loop back with `DJNZ`, effectively scrolling or shifting screen rows. - `\C9` — `RET` This routine most likely implements a one-row upward scroll of a portion of the display file, giving the visual effect of the bullet moving smoothly through the playfield without slow BASIC redraw overhead. ### Collision Detection Collision is detected at lines 150–170 using a direct display file PEEK. The system variables at addresses 16398 and 16399 hold the low and high bytes of the display file address (D_FILE). The code computes the character at the current bullet row and column 16 by reading `PEEK(PEEK 16398 + 256*PEEK 16399)`. A returned value of `8` (line 160) represents a newline character, indicating the bullet has gone off the top of the screen, triggering GAME OVER. Any other non-zero value (line 170) indicates a bomb character was hit, branching to the score routine at line 400. ### Screen Setup and Bomb Placement Line 20 fills the top portion of the screen with inverse space characters (`\@@`) to create a border or sky effect, then places an inverse-video paddle/base graphic at row 15. Lines 30–32 scatter 50 bomb markers (rendered as inverse `*` characters, i.e., `%*`) at random positions in rows 3–12 using `INT(RND*10)+3` and `INT(RND*32)`. ### Game Loop and Bullet Mechanics The main loop (lines 100–190) is entered repeatedly. The bullet position is tracked in variable `P`, and `B` is a Boolean flag (0 = no bullet, 1 = bullet active). Each iteration, `P` is decremented by 1 (line 135), moving the bullet up one row. The bullet is drawn at `AT P,16` (line 140/155) and erased at line 180. If no bullet is active, the loop waits at line 200 for any keypress before launching from row 22. ### Key Variables | Variable | Purpose | | --- | --- | | `B` | Bullet active flag (0 = none, 1 = in flight) | | `P` | Current bullet row position | | `S` | Player score (bombs destroyed) | | `Z` | Loop counter for bomb placement | | `N` | Display file character at bullet position | ### Notable Techniques and Anomalies - `POKE 16418,0` at line 10 clears the scroll counter (CDFLAG or similar system variable), suppressing the “scroll?” prompt. - The game over handler at line 310 waits for `CHR$ 118`, which is the ENTER key on the ZX81 keyboard, before restarting. - The bullet is always fired from column 16, so the entire game is a single vertical track — there is no horizontal movement of the player or the shot. - Because bombs are placed randomly at startup and never regenerated until `RUN` restarts the program, a full playthrough ends only when the bullet exits the top of the screen or a full restart is triggered. - The `RAND USR` call at line 110 inside the main loop means the machine code runs on every iteration, suggesting it performs per-frame display work rather than a one-time setup. ## Source Code ``` 1 REM \2A\0C\40\06\18\C5\23\7E\32\21\40\54\5D\23\01\1F\00\ED\B0\2B\3A\21\40\77\23\C1\10\E9\C9\25\1C\1D 10 POKE 16418,0 20 PRINT "\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@";AT 15,5;"% " 30 FOR Z=1 TO 50 31 PRINT AT INT (RND*10)+3,INT (RND*32);"%*" 32 NEXT Z 40 LET B=0 50 LET S=0 100 PRINT AT 22,15;" " 110 RAND USR 16514 120 PRINT AT 22,15;"\..% \.." 130 IF NOT B THEN GOTO 200 135 LET P=P-1 140 PRINT AT P,16; 150 LET N=PEEK (PEEK 16398+256*PEEK 16399) 155 PRINT "*" 160 IF N=8 THEN GOTO 300 170 IF N THEN GOTO 400 180 PRINT AT P,16;" " 190 GOTO 100 200 IF INKEY$="" THEN GOTO 100 210 LET P=22 220 LET B=1 230 GOTO 100 300 PRINT AT 1,1;"GAME OVER...YOUR SCORE->";S 310 IF INKEY$<>CHR$ 118 THEN GOTO 310 320 CLS 330 RUN 400 LET S=S+1 410 LET B=0 420 GOTO 180 ```