This program implements a bouncing ball animation entirely in Z80 machine code, embedded in REM statements and executed via RAND USR 16908. The machine code manipulates display memory directly, using 16-bit address arithmetic to move a ball sprite around the screen and handle boundary collisions. Two REM lines carry the full binary payload: the first (line 0) contains the primary routine, and the second also line 0 (a known multi-line-zero trick) stores additional data tables and vectors. Line 2 contains patching notes for the developer, listing key addresses and byte values used to redirect execution flow. The program loops continuously via GOTO 1, re-entering the machine code on each pass.
Program Analysis
Program Structure
The listing is minimal at the BASIC level, with almost all logic residing in Z80 machine code stored in REM statements:
- Line 0 (first) — REM with an inverse-video title “BOUNCE”.
- Line 0 (second) — REM containing the full machine code payload (approximately 280+ bytes of Z80 opcodes encoded as hex escapes).
- Line 1 —
RAND USR 16908transfers control to the machine code at address 16908 (0x420C), which falls inside the second REM line’s data area. - Line 2 — Developer commentary listing patch addresses and byte values needed to relocate or hook the routine.
- Lines 3–4 —
SAVEfollowed byGOTO 1to continuously re-run the animation.
Machine Code Entry and Memory Layout
RAND USR 16908 (decimal) equals USR 0x420C. On a TS2068/ZX Spectrum, the system variables area ends well below this, so 0x420C lands squarely in the second REM line’s payload. The code sets up its own internal pointers using absolute 16-bit addresses (22 xx xx = LD (nnnn),HL; 2A xx xx = LD HL,(nnnn)), making the routine position-dependent at these fixed addresses.
Display Memory Access
The machine code accesses display RAM directly. Several instruction sequences load HL or DE with addresses in the 0x4000–0x5AFF range (the Spectrum/TS2068 display file and attribute area). The pattern 19 (ADD HL,DE) combined with 71 (LD (HL),C) and short DJNZ loops (10 Fx) is a classic tight sprite-drawing idiom, writing pixels row by row across display lines.
Key Z80 Idioms Identified
11 xx xx/19— Load DE with a stride value and repeatedly add to HL to step through display memory rows.10 Fx—DJNZshort loops for pixel/attribute row iteration.ED 5B xx xx—LD DE,(nnnn)to fetch ball position from a workspace variable.22 xx xx/2A xx xx— Store/recall 16-bit ball coordinates in fixed workspace locations.7E B7—LD A,(HL); OR Ato test a display cell for non-zero content (collision detection).C3 xx xx— UnconditionalJPused for main loop branches and dispatch.18 xx— RelativeJRfor short local branches.E5/E1—PUSH HL/POP HLused to preserve the ball’s address across sub-operations.
Bounce / Collision Logic
The routine reads the ball’s current screen address from a workspace cell, draws the ball, then tests the target cell’s content. When OR A finds the cell non-zero (another pixel already present, i.e., a wall or boundary), the velocity component is negated by branching to an alternate delta-add path. The direction vectors appear to be stored as signed 16-bit offsets (e.g., 0x004D, 0xFF B0) applied via ADD HL,DE to the current display address, giving horizontal and vertical movement independently.
Data Tables
Near the end of the second REM block, a sequence of values 21 22 23 24 25 1C 1D 1E 1F 20 21 22 23 24 25 1C appears to be a lookup table, likely encoding the ball sprite shape or a cyclic animation frame table, referenced by an index that increments on each frame.
Developer Patch Notes (Line 2)
Line 2 is a plain-text memo to the programmer listing addresses and patch bytes:
| Label | Address | Value/Note |
|---|---|---|
| CDE702 | — | Opcode bytes for a JP 0x02E7-style hook |
| Q 217D40 | 0x407D | Workspace pointer (ball position low byte?) |
| 222940 | 0x4029 | LD (0x4029),HL — stores a vector |
| C3FC02 | — | JP 0x02FC — likely a BASIC interpreter re-entry |
GOTO Loop
GOTO 1 at line 4 creates an infinite BASIC loop that re-executes RAND USR 16908 on each iteration. In practice the machine code itself contains an internal loop (18 C8, 18 C1, C3 91 40, etc.) and never returns to BASIC during normal animation; the GOTO serves as a safety net if the routine ever exits cleanly.
Potential Anomalies
- Two lines both numbered
0— the second silently shadows or appends to the first depending on the interpreter’s line-lookup behaviour; this is intentional to pack the code before line 1. - The routine uses absolute addresses throughout, so it is not relocatable without the patches documented in line 2.
- The
SAVE "1023%7"on line 3 is reached via fall-through from line 1 only ifRAND USRreturns, which under normal operation it does not.
Source Code
0 REM % %B%O%U%N%C%E%
0 REM \0E\08\06\20\11\F7\02\2A\0C\40\E5\23\E5\71\19\71\E1\10\F8\23\23\06\16\11\1F\00\71\19\71\23\23\10\F9\E1\11\4B\01\19\E5\11\84\00\06\20\E5\71\19\71\E1\23\10\F8\E1\23\0E\00\11\9F\00\06\03\E5\71\19\71\E1\23\10\F8\E5\11\C8\00\19\22\40\40\36\34\21\00\04\22\46\40\E1\E5\11\B0\FF\19\22\48\40\36\36\21\DE\FE\22\50\40\E1\11\4D\00\19\22\3E\40\36\1C\21\E0\FF\22\42\40\21\DE\FF\22\44\40\18\09\2A\34\40\22\32\40\2A\46\40\2B\7C\B5\20\FB\3A\26\40\FE\FE\C8\06\21\2A\48\40\36\00\ED\5B\50\40\19\7E\B7\20\05\36\36\22\48\40\B7\28\22\05\28\FB\E5\2A\32\40\54\5D\29\29\19\29\22\32\40\7C\E6\06\C6\95\6F\26\41\5E\23\56\ED\53\50\40\E1\18\C8\E5\2A\7B\40\7E\32\26\41\32\36\41\23\7E\32\2C\41\32\58\41\23\7E\32\34\41\FE\36\28\07\23\22\7B\40\E1\18\A3\21\8A\41\22\7B\40\E1\18\86\00\40\44\34\3E\42\1C\48\50\36\00\00\DE\FF\20\00\E0\FF\22\00\00\21\8D\41\22\7B\40\C3\91\40\00\00\00\00\00\00\56\ED\53\42\40\E1\18\C2\06\35\2A\48\40\36\00\ED\5B\50\40\19\7E\4F\E6\F7\20\05\36\36\22\48\40\B1\CA\22\41\05\28\FA\00\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E6\06\C6\91\6F\26\40\5E\23\56\ED\53\50\40\E1\18\C1\21\12\42\22\29\40\C3\FC\02\21\00\60\22\04\40\21\1C\42\22\29\40\C9\CD\2B\0F\C3\9E\41\00\00\06\00\F9\D4\C5\26\0D\76\00\00\02\00\FB\76\00\00\06\00\F9\D4\C5\27\0D\76\00\27\3E\00\27\34\27\00\32\2E\3D\00\00\21\22\23\24\25\1C\1D\1E\1F\20\21\22\23\24\25\1C
1 RAND USR 16908
2 REM STICK THIS SOMEWHERE AND CALL IT: CDE702 Q 217D40 222940 C3FC02
3 SAVE "1023%7"
4 GOTO 1
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
