This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: AREMstatement containing the entire machine code routine as raw bytes.LINE 2:SLOW— switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.LINE 3:RAND USR 16514— calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past theREMtoken and the length bytes), effectively entering the routine directly.LINE 4: AREMcontaining user instructions about pressing SHIFT to reset the RNG.LINE 5:SAVEthe program.LINE 6:LIST 2— returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HLandDEregister pairs to track the ball’s position within the display file (which begins at a stored address in system variables). - A
DJNZloop (0x10 0xF8,0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation. - Comparison against
0x76(theHALTopcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges. - A call to
0x415A(likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE/0xA7/0x38), implementing the SHIFT-to-reseed behaviour described in line 4. - An
ED 52(SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator. - Storage of the ball’s current address at
0x403Cand related state variables at nearby addresses (0x4040,0x4044,0x4046), all within the user RAM area just above the system variables. - The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF,0x01 0x00,0x22 0x00,0x21 0x00,0x20 0x00,0xFF 0xFF,0xDE 0xFF,0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file. - A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeatedADD HL,HLshifts andADD HL,DEto multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: TheRANDkeyword is used purely to discard the return value ofUSR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.SLOWbefore the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.LIST 2at the end presents the program cleanly after aLOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
| Bytes (hex) | Signed 16-bit offset | Approximate direction |
|---|---|---|
| E0 FF | -32 | Left one cell |
| 01 00 | +1 | Right one byte |
| 22 00 | +34 | Down one row |
| 21 00 | +33 | Down-right diagonal |
| 20 00 | +32 | Down-left diagonal |
| FF FF | -1 | Left one byte |
| DE FF | -34 | Up one row |
| DF FF | -33 | Up-right diagonal |
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17repeated 21 times at the very end of the REM areRLA(rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before aRETor jump. - Address
0x4034referenced in the code (2A 34 40=LD HL,(0x4034)) is the ZX81FRAMESsystem variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E\F7
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\E5\E5\E1\F8 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57435 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"F
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\F9\E1\E5E\BE\FAE\BE\F5\EDB\E5\A7\ED\E1
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\CDA\FE\A7E itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57435 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"\AF\DB\E1
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
ACC
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
BC\B5\FB\CD
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\D0
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\EDBE\FE
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\DC\CDA\E6
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E\C6AFE\ED\FD\CB
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\CB
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\E0\FF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57435 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.7 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.5"
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\FF\FF\DE\FF\DF\FF\E5
Skip to content
Ball
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program implements a ball-bouncing simulation using a machine code routine embedded in a REM statement at line 1. The machine code is invoked directly via RAND USR 16514, which jumps into the bytes stored in the REM line’s data area. The routine uses the ZX81’s display file to track and animate a bouncing ball, with a pseudo-random number generator to vary the ball’s trajectory. A SHIFT keypress injects the frame counter value into the RNG to break repetitive patterns, a technique common in games of this era to add entropy.
Program Analysis
Program Structure
The program is minimal on the BASIC side — almost all logic lives in machine code. The BASIC lines serve only as a loader and launcher:
LINE 1: A REM statement containing the entire machine code routine as raw bytes.
LINE 2: SLOW — switches the display to slow (non-FAST) mode so the display file is active and the ball is visible.
LINE 3: RAND USR 16514 — calls the machine code at address 16514, which is 2 bytes into the REM line’s data (past the REM token and the length bytes), effectively entering the routine directly.
LINE 4: A REM containing user instructions about pressing SHIFT to reset the RNG.
LINE 5: SAVE the program.
LINE 6: LIST 2 — returns the display to line 2 after loading, hiding line 1’s raw bytes.
Machine Code Usage
The machine code is stored in the REM at line 1, starting at address 16514 (0x4082). RAND USR 16514 jumps directly into it. The routine is self-contained and runs in an infinite loop, animating a ball across the ZX81 display file.
Key features visible in the disassembly bytes include:
- Use of
HL and DE register pairs to track the ball’s position within the display file (which begins at a stored address in system variables).
- A
DJNZ loop (0x10 0xF8, 0x10 0xF9) for scanning surrounding cells — typical for collision detection in ZX81 display-file manipulation.
- Comparison against
0x76 (the HALT opcode, which the ZX81 uses as a newline/end-of-line marker in the display file) to detect screen edges.
- A call to
0x415A (likely a ROM keyboard scan routine) with a test for the SHIFT key (0xFE / 0xA7 / 0x38), implementing the SHIFT-to-reseed behaviour described in line 4.
- An
ED 52 (SBC HL,DE) instruction used to compute a displacement, feeding into the pseudo-random number generator.
- Storage of the ball’s current address at
0x403C and related state variables at nearby addresses (0x4040, 0x4044, 0x4046), all within the user RAM area just above the system variables.
- The tail of the REM contains a small lookup table with direction vectors (
0xE0 0xFF, 0x01 0x00, 0x22 0x00, 0x21 0x00, 0x20 0x00, 0xFF 0xFF, 0xDE 0xFF, 0xDF 0xFF) representing eight possible ball movement directions as 16-bit signed offsets into the display file.
- A subroutine near the end of the REM (
0xE5 0x2A 0x32 0x40 ...) computes the display file row offset using repeated ADD HL,HL shifts and ADD HL,DE to multiply by the line width — a standard ZX81 display address calculation.
Key BASIC Idioms
RAND USR 16514: The RAND keyword is used purely to discard the return value of USR; without it, the integer result would be assigned as the new random seed, which is harmless but tidy.
SLOW before the USR call ensures the display interrupt is running, which the routine relies on for timing and frame-counter entropy.
LIST 2 at the end presents the program cleanly after a LOAD, hiding the raw machine code bytes of line 1 from casual view.
RNG and Pattern-Breaking Technique
The pseudo-random number generator operates on a seed stored in RAM. Because the ZX81’s SLOW mode increments a frame counter (at system variable FRAMES, address 0x4034), pressing SHIFT causes the routine to XOR or mix the current frame count into the seed. This breaks any deterministic loop the ball may have entered, as described in the line 4 comment. The technique is a pragmatic solution to the limited entropy available on the platform.
Direction Vector Table
Bytes (hex) Signed 16-bit offset Approximate direction E0 FF -32 Left one cell 01 00 +1 Right one byte 22 00 +34 Down one row 21 00 +33 Down-right diagonal 20 00 +32 Down-left diagonal FF FF -1 Left one byte DE FF -34 Up one row DF FF -33 Up-right diagonal
These offsets correspond to movement within the ZX81 display file, where each row is 33 bytes wide (32 character cells plus a 0x76 newline byte), explaining the +34/−34 and related values.
Notable Anomalies
- The trailing bytes
0x17 repeated 21 times at the very end of the REM are RLA (rotate left through carry) instructions. These appear to be padding or part of the RNG shift chain and would execute harmlessly if the PC ever reached them before a RET or jump.
- Address
0x4034 referenced in the code (2A 34 40 = LD HL,(0x4034)) is the ZX81 FRAMES system variable — a 16-bit frame counter incremented by the display interrupt — confirming the entropy-injection mechanism.
Content
Source Code
1 REM \2A\34\40\22\32\40\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\E5\23\3E\08\BE\28\FA\3E\76\BE\28\F5\ED\5B\10\40\E5\A7\ED\52\E1\30\0F\CD\5A\41\FE\A7\38\04\3E\88\18\01\AF\77\18\DB\E1\11\27\00\19\22\3C\40\21\00\04\22\46\40\2A\3C\40\23\22\3C\40\22\40\40\36\34\21\22\00\22\44\40\2A\46\40\2B\7C\B5\20\FB\CD\46\0F\D0\00\00\2A\40\40\36\00\ED\5B\44\40\19\7E\FE\00\20\07\36\34\22\40\40\18\DC\CD\5A\41\E6\0E\C6\4A\6F\26\41\5E\23\56\ED\53\44\40\FD\CB\26\46\20\06\2A\34\40\22\32\40\18\CB\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\E0\FF\01\00\22\00\21\00\20\00\FF\FF\DE\FF\DF\FF\E5\2A\32\40\54\5D\29\29\19\29\29\29\19\22\32\40\7C\E1\C9\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
ADC\E1\C9
2 SLOW
3 RAND USR 16514
4 REM IF THE BALL APPEARS TO BE LOCKED IN A PATTERN PRESS "SHIFT". IT WILL INTRODUCE A NUMBER FROM THE FRAMES COUNTER INTO THE PSEUDO RANDOM NO. GENERATOR ROUTINE.
5 SAVE "1023%6"
6 LIST 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
