Surge is a ZX81/TS1000 one-screen arcade game in which the player steers a character (“V”) upward through a scrolling field of obstacles while a machine-code routine checks for collisions. The program uses a 7-byte machine-code stub embedded in REM line 1 (loaded via POKE 16517 at line 10), which is called with USR 16514 to perform a character-code check at the player’s screen position. Scrolling is achieved with the SCROLL command, and the player’s horizontal movement is driven by INKEY$ with boundary clamping. The score accumulates as the number of rows the player climbs (line 120: S=S+U decrements as U approaches zero), and a high-score variable H is preserved across restarts.
Program Analysis
Program Structure
The program divides into three logical phases:
- Initialisation (lines 1–25): Machine code is embedded in
REMline 1, the POKE at line 10 patches the program area, and game variables are reset. - Main game loop (lines 30–130): Moves the player, scrolls the screen, checks for collision via
USR, prints obstacles, and accumulates score. - Game-over / restart (lines 200–230): Updates high score, displays result, pauses, and loops back to line 15 for a new game without re-running the machine-code setup.
Machine Code in REM Line 1
Line 1 holds the bytes Surge is a ZX81/TS1000 one-screen arcade game in which the player steers a character (“V”) upward through a scrolling field of obstacles while a machine-code routine checks for collisions. The program uses a 7-byte machine-code stub embedded in REM line 1 (loaded via POKE 16517 at line 10), which is called with USR 16514 to perform a character-code check at the player’s screen position. Scrolling is achieved with the SCROLL command, and the player’s horizontal movement is driven by INKEY$ with boundary clamping. The score accumulates as the number of rows the player climbs (line 120: S=S+U decrements as U approaches zero), and a high-score variable H is preserved across restarts. The program divides into three logical phases: Line 1 holds the bytes The machine-code routine at Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters. Surge is a ZX81/TS1000 one-screen arcade game in which the player steers a character (“V”) upward through a scrolling field of obstacles while a machine-code routine checks for collisions. The program uses a 7-byte machine-code stub embedded in REM line 1 (loaded via POKE 16517 at line 10), which is called with USR 16514 to perform a character-code check at the player’s screen position. Scrolling is achieved with the SCROLL command, and the player’s horizontal movement is driven by INKEY$ with boundary clamping. The score accumulates as the number of rows the player climbs (line 120: S=S+U decrements as U approaches zero), and a high-score variable H is preserved across restarts. The program divides into three logical phases: Line 1 holds the bytes The machine-code routine at Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters. Surge is a ZX81/TS1000 one-screen arcade game in which the player steers a character (“V”) upward through a scrolling field of obstacles while a machine-code routine checks for collisions. The program uses a 7-byte machine-code stub embedded in REM line 1 (loaded via POKE 16517 at line 10), which is called with USR 16514 to perform a character-code check at the player’s screen position. Scrolling is achieved with the SCROLL command, and the player’s horizontal movement is driven by INKEY$ with boundary clamping. The score accumulates as the number of rows the player climbs (line 120: S=S+U decrements as U approaches zero), and a high-score variable H is preserved across restarts. The program divides into three logical phases: Line 1 holds the bytes The machine-code routine at Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
Skip to content
(7 bytes). In Z80 mnemonics:Surge
Program Analysis
Program Structure
REM line 1, the POKE at line 10 patches the program area, and game variables are reset.USR, prints obstacles, and accumulates score.Machine Code in REM Line 1
\2A\0E\40\4E\06\00\C9 (7 bytes). In Z80 mnemonics:Offset Hex Mnemonic Notes 0 2A 0E 40 LD HL,(400Eh) Load HL with the word at address 400Eh (CHARS sysvar area) 3 4E LD C,(HL) Read byte at that address into C 4 06 00 LD B,0 Set B=0, so BC = character code read 6 C9 RET Return BC as the USR result POKE 16517,78 (line 10) writes 4Eh into the fifth byte of the REM payload, ensuring the LD C,(HL) opcode is correctly placed. The routine is called at USR 16514 (the start of the REM data area). It reads a byte from the display file address held at 400Eh and returns it as a numeric result, allowing the BASIC at line 80 to compare it with CODE "% " (the inverse-space character) to detect a collision with an obstacle.Variable Usage
Variable Purpose HHigh score (initialised to 1 at line 5; persists across restarts) SCurrent game score UPlayer’s row (counts down toward 0 = top of screen) TRight boundary / screen width limit (20) PPlayer’s column position Key BASIC Idioms
P=P-H/H*(P>H/H) — since H is always ≥1, H/H equals 1, so this reads P=P-1*(P>1), clamping P to a minimum of 1 without an IF statement.P whenever any key is held and P<T, giving a simple one-button rightward movement mechanic (releasing the key causes leftward drift).U to S each iteration; as the player moves upward, U decreases, so the score grows more slowly the nearer to the top the player reaches. This is a consequence of the accumulation, not deliberate progressive difficulty weighting."% % % % % ") at a random row and column, creating short horizontal barriers across the screen.SCROLL for forced upward motion: The SCROLL on line 65 shifts the entire screen display one line upward each loop iteration, creating the illusion of the player moving through a field of descending obstacles.Collision Detection
USR 16514 returns the character code of the cell at the player’s current position. Line 80 compares this to CODE "% " (inverse space, used as the obstacle tile). If they match, the player row U is decremented; when U reaches 0 (line 90), the game ends. Note that the collision logic decrements U on a hit rather than terminating immediately, so the player “climbs” faster through obstacles — this appears to be intentional for game feel but means the score accumulation in line 120 continues for one extra frame after a collision.Notable Anomalies
IF H<S THEN LET H=S — because H starts at 1 rather than 0, a player with a score of 0 will never overwrite the high score even on the first game, which is intentional as a safe guard against resetting to zero.STOP, two REMs describing how to start and save the program, and a stray RUN.SAVE at line 275 uses an inverse-digit filename which acts as an auto-run marker in the tape format.Content
Source Code
1 REM \2A\0E\40\4E\06\00\C9
2 REM SURGE %2%K
3 REM BY TIM ROGERS
4 CLS
5 LET H=1
10 POKE 16517,78
15 LET S=H-H
20 LET U=10
25 LET T=20
30 LET P=U
40 PRINT AT U,P;" "
50 LET P=P-H/H*(P>H/H)
60 LET P=P+(INKEY$<>"")*2*(P<T)
65 SCROLL
70 PRINT AT U,P;
80 IF USR 16514=CODE "% " THEN LET U=U-H/H
90 IF U=H-H THEN GOTO 200
100 PRINT AT U,P;"V"
110 PRINT AT CODE ")",RND*T;"% % % % % "
120 LET S=S+U
130 GOTO 40
200 IF H<S THEN LET H=S
210 PRINT AT U,P;"SURGE",H,S
220 PAUSE 4E4
230 GOTO 15
250 STOP
260 REM RAND USR 14336
270 REM SAVE "SURGE.B1"
275 SAVE "1021%8"
280 RUN
People
Surge
Program Analysis
Program Structure
REM line 1, the POKE at line 10 patches the program area, and game variables are reset.USR, prints obstacles, and accumulates score.Machine Code in REM Line 1
\2A\0E\40\4E\06\00\C9 (7 bytes). In Z80 mnemonics:Offset Hex Mnemonic Notes 0 2A 0E 40 LD HL,(400Eh) Load HL with the word at address 400Eh (CHARS sysvar area) 3 4E LD C,(HL) Read byte at that address into C 4 06 00 LD B,0 Set B=0, so BC = character code read 6 C9 RET Return BC as the USR result POKE 16517,78 (line 10) writes 4Eh into the fifth byte of the REM payload, ensuring the LD C,(HL) opcode is correctly placed. The routine is called at USR 16514 (the start of the REM data area). It reads a byte from the display file address held at 400Eh and returns it as a numeric result, allowing the BASIC at line 80 to compare it with CODE "% " (the inverse-space character) to detect a collision with an obstacle.Variable Usage
Variable Purpose HHigh score (initialised to 1 at line 5; persists across restarts) SCurrent game score UPlayer’s row (counts down toward 0 = top of screen) TRight boundary / screen width limit (20) PPlayer’s column position Key BASIC Idioms
P=P-H/H*(P>H/H) — since H is always ≥1, H/H equals 1, so this reads P=P-1*(P>1), clamping P to a minimum of 1 without an IF statement.P whenever any key is held and P<T, giving a simple one-button rightward movement mechanic (releasing the key causes leftward drift).U to S each iteration; as the player moves upward, U decreases, so the score grows more slowly the nearer to the top the player reaches. This is a consequence of the accumulation, not deliberate progressive difficulty weighting."% % % % % ") at a random row and column, creating short horizontal barriers across the screen.SCROLL for forced upward motion: The SCROLL on line 65 shifts the entire screen display one line upward each loop iteration, creating the illusion of the player moving through a field of descending obstacles.Collision Detection
USR 16514 returns the character code of the cell at the player’s current position. Line 80 compares this to CODE "% " (inverse space, used as the obstacle tile). If they match, the player row U is decremented; when U reaches 0 (line 90), the game ends. Note that the collision logic decrements U on a hit rather than terminating immediately, so the player “climbs” faster through obstacles — this appears to be intentional for game feel but means the score accumulation in line 120 continues for one extra frame after a collision.Notable Anomalies
IF H<S THEN LET H=S — because H starts at 1 rather than 0, a player with a score of 0 will never overwrite the high score even on the first game, which is intentional as a safe guard against resetting to zero.STOP, two REMs describing how to start and save the program, and a stray RUN.SAVE at line 275 uses an inverse-digit filename which acts as an auto-run marker in the tape format.Content
Source Code
1 REM \2A\0E\40\4E\06\00\C9
2 REM SURGE %2%K
3 REM BY TIM ROGERS
4 CLS
5 LET H=1
10 POKE 16517,78
15 LET S=H-H
20 LET U=10
25 LET T=20
30 LET P=U
40 PRINT AT U,P;" "
50 LET P=P-H/H*(P>H/H)
60 LET P=P+(INKEY$<>"")*2*(P<T)
65 SCROLL
70 PRINT AT U,P;
80 IF USR 16514=CODE "% " THEN LET U=U-H/H
90 IF U=H-H THEN GOTO 200
100 PRINT AT U,P;"V"
110 PRINT AT CODE ")",RND*T;"% % % % % "
120 LET S=S+U
130 GOTO 40
200 IF H<S THEN LET H=S
210 PRINT AT U,P;"SURGE",H,S
220 PAUSE 4E4
230 GOTO 15
250 STOP
260 REM RAND USR 14336
270 REM SAVE "SURGE.B1"
275 SAVE "1021%8"
280 RUN
People
Surge
Program Analysis
Program Structure
REM line 1, the POKE at line 10 patches the program area, and game variables are reset.USR, prints obstacles, and accumulates score.Machine Code in REM Line 1
\2A\0E\40\4E\06\00\C9 (7 bytes). In Z80 mnemonics:Offset Hex Mnemonic Notes 0 2A 0E 40 LD HL,(400Eh) Load HL with the word at address 400Eh (CHARS sysvar area) 3 4E LD C,(HL) Read byte at that address into C 4 06 00 LD B,0 Set B=0, so BC = character code read 6 C9 RET Return BC as the USR result POKE 16517,78 (line 10) writes 4Eh into the fifth byte of the REM payload, ensuring the LD C,(HL) opcode is correctly placed. The routine is called at USR 16514 (the start of the REM data area). It reads a byte from the display file address held at 400Eh and returns it as a numeric result, allowing the BASIC at line 80 to compare it with CODE "% " (the inverse-space character) to detect a collision with an obstacle.Variable Usage
Variable Purpose HHigh score (initialised to 1 at line 5; persists across restarts) SCurrent game score UPlayer’s row (counts down toward 0 = top of screen) TRight boundary / screen width limit (20) PPlayer’s column position Key BASIC Idioms
P=P-H/H*(P>H/H) — since H is always ≥1, H/H equals 1, so this reads P=P-1*(P>1), clamping P to a minimum of 1 without an IF statement.P whenever any key is held and P<T, giving a simple one-button rightward movement mechanic (releasing the key causes leftward drift).U to S each iteration; as the player moves upward, U decreases, so the score grows more slowly the nearer to the top the player reaches. This is a consequence of the accumulation, not deliberate progressive difficulty weighting."% % % % % ") at a random row and column, creating short horizontal barriers across the screen.SCROLL for forced upward motion: The SCROLL on line 65 shifts the entire screen display one line upward each loop iteration, creating the illusion of the player moving through a field of descending obstacles.Collision Detection
USR 16514 returns the character code of the cell at the player’s current position. Line 80 compares this to CODE "% " (inverse space, used as the obstacle tile). If they match, the player row U is decremented; when U reaches 0 (line 90), the game ends. Note that the collision logic decrements U on a hit rather than terminating immediately, so the player “climbs” faster through obstacles — this appears to be intentional for game feel but means the score accumulation in line 120 continues for one extra frame after a collision.Notable Anomalies
IF H<S THEN LET H=S — because H starts at 1 rather than 0, a player with a score of 0 will never overwrite the high score even on the first game, which is intentional as a safe guard against resetting to zero.STOP, two REMs describing how to start and save the program, and a stray RUN.SAVE at line 275 uses an inverse-digit filename which acts as an auto-run marker in the tape format.Content
Source Code
1 REM \2A\0E\40\4E\06\00\C9
2 REM SURGE %2%K
3 REM BY TIM ROGERS
4 CLS
5 LET H=1
10 POKE 16517,78
15 LET S=H-H
20 LET U=10
25 LET T=20
30 LET P=U
40 PRINT AT U,P;" "
50 LET P=P-H/H*(P>H/H)
60 LET P=P+(INKEY$<>"")*2*(P<T)
65 SCROLL
70 PRINT AT U,P;
80 IF USR 16514=CODE "% " THEN LET U=U-H/H
90 IF U=H-H THEN GOTO 200
100 PRINT AT U,P;"V"
110 PRINT AT CODE ")",RND*T;"% % % % % "
120 LET S=S+U
130 GOTO 40
200 IF H<S THEN LET H=S
210 PRINT AT U,P;"SURGE",H,S
220 PAUSE 4E4
230 GOTO 15
250 STOP
260 REM RAND USR 14336
270 REM SAVE "SURGE.B1"
275 SAVE "1021%8"
280 RUN
People
| Offset | Hex | Mnemonic | Notes |
|---|---|---|---|
| 0 | 2A 0E 40 | LD HL,(400Eh) | Load HL with the word at address 400Eh (CHARS sysvar area) |
| 3 | 4E | LD C,(HL) | Read byte at that address into C |
| 4 | 06 00 | LD B,0 | Set B=0, so BC = character code read |
| 6 | C9 | RET | Return BC as the USR result |
POKE 16517,78 (line 10) writes 4Eh into the fifth byte of the REM payload, ensuring the LD C,(HL) opcode is correctly placed. The routine is called at USR 16514 (the start of the REM data area). It reads a byte from the display file address held at 400Eh and returns it as a numeric result, allowing the BASIC at line 80 to compare it with CODE "% " (the inverse-space character) to detect a collision with an obstacle.
Variable Usage
| Variable | Purpose |
|---|---|
H | High score (initialised to 1 at line 5; persists across restarts) |
S | Current game score |
U | Player’s row (counts down toward 0 = top of screen) |
T | Right boundary / screen width limit (20) |
P | Player’s column position |
Key BASIC Idioms
- Boolean arithmetic for movement: Line 50 uses
P=P-H/H*(P>H/H)— sinceHis always ≥1,H/Hequals 1, so this readsP=P-1*(P>1), clampingPto a minimum of 1 without anIFstatement. - INKEY$ horizontal movement: Line 60 adds 2 to
Pwhenever any key is held andP<T, giving a simple one-button rightward movement mechanic (releasing the key causes leftward drift). - Score via row position: Line 120 adds the current row number
UtoSeach iteration; as the player moves upward,Udecreases, so the score grows more slowly the nearer to the top the player reaches. This is a consequence of the accumulation, not deliberate progressive difficulty weighting. - Obstacle rendering: Line 110 prints a string of five inverse-space characters (
"% % % % % ") at a random row and column, creating short horizontal barriers across the screen. SCROLLfor forced upward motion: TheSCROLLon line 65 shifts the entire screen display one line upward each loop iteration, creating the illusion of the player moving through a field of descending obstacles.
Collision Detection
The machine-code routine at USR 16514 returns the character code of the cell at the player’s current position. Line 80 compares this to CODE "% " (inverse space, used as the obstacle tile). If they match, the player row U is decremented; when U reaches 0 (line 90), the game ends. Note that the collision logic decrements U on a hit rather than terminating immediately, so the player “climbs” faster through obstacles — this appears to be intentional for game feel but means the score accumulation in line 120 continues for one extra frame after a collision.
Notable Anomalies
- Line 200 uses
IF H<S THEN LET H=S— becauseHstarts at 1 rather than 0, a player with a score of 0 will never overwrite the high score even on the first game, which is intentional as a safe guard against resetting to zero. - Lines 250–280 are unreachable dead code used for development notes:
STOP, twoREMs describing how to start and save the program, and a strayRUN. - The
SAVEat line 275 uses an inverse-digit filename which acts as an auto-run marker in the tape format.
Content
Source Code
1 REM
Skip to content
Surge
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
Surge is a ZX81/TS1000 one-screen arcade game in which the player steers a character (“V”) upward through a scrolling field of obstacles while a machine-code routine checks for collisions. The program uses a 7-byte machine-code stub embedded in REM line 1 (loaded via POKE 16517 at line 10), which is called with USR 16514 to perform a character-code check at the player’s screen position. Scrolling is achieved with the SCROLL command, and the player’s horizontal movement is driven by INKEY$ with boundary clamping. The score accumulates as the number of rows the player climbs (line 120: S=S+U decrements as U approaches zero), and a high-score variable H is preserved across restarts.
Program Analysis
Program Structure
The program divides into three logical phases:
- Initialisation (lines 1–25): Machine code is embedded in
REM line 1, the POKE at line 10 patches the program area, and game variables are reset.
- Main game loop (lines 30–130): Moves the player, scrolls the screen, checks for collision via
USR, prints obstacles, and accumulates score.
- Game-over / restart (lines 200–230): Updates high score, displays result, pauses, and loops back to line 15 for a new game without re-running the machine-code setup.
Machine Code in REM Line 1
Line 1 holds the bytes \2A\0E\40\4E\06\00\C9 (7 bytes). In Z80 mnemonics:
Offset Hex Mnemonic Notes 0 2A 0E 40 LD HL,(400Eh) Load HL with the word at address 400Eh (CHARS sysvar area) 3 4E LD C,(HL) Read byte at that address into C 4 06 00 LD B,0 Set B=0, so BC = character code read 6 C9 RET Return BC as the USR result
POKE 16517,78 (line 10) writes 4Eh into the fifth byte of the REM payload, ensuring the LD C,(HL) opcode is correctly placed. The routine is called at USR 16514 (the start of the REM data area). It reads a byte from the display file address held at 400Eh and returns it as a numeric result, allowing the BASIC at line 80 to compare it with CODE "% " (the inverse-space character) to detect a collision with an obstacle.
Variable Usage
Variable Purpose HHigh score (initialised to 1 at line 5; persists across restarts) SCurrent game score UPlayer’s row (counts down toward 0 = top of screen) TRight boundary / screen width limit (20) PPlayer’s column position
Key BASIC Idioms
- Boolean arithmetic for movement: Line 50 uses
P=P-H/H*(P>H/H) — since H is always ≥1, H/H equals 1, so this reads P=P-1*(P>1), clamping P to a minimum of 1 without an IF statement.
- INKEY$ horizontal movement: Line 60 adds 2 to
P whenever any key is held and P<T, giving a simple one-button rightward movement mechanic (releasing the key causes leftward drift).
- Score via row position: Line 120 adds the current row number
U to S each iteration; as the player moves upward, U decreases, so the score grows more slowly the nearer to the top the player reaches. This is a consequence of the accumulation, not deliberate progressive difficulty weighting.
- Obstacle rendering: Line 110 prints a string of five inverse-space characters (
"% % % % % ") at a random row and column, creating short horizontal barriers across the screen.
SCROLL for forced upward motion: The SCROLL on line 65 shifts the entire screen display one line upward each loop iteration, creating the illusion of the player moving through a field of descending obstacles.
Collision Detection
The machine-code routine at USR 16514 returns the character code of the cell at the player’s current position. Line 80 compares this to CODE "% " (inverse space, used as the obstacle tile). If they match, the player row U is decremented; when U reaches 0 (line 90), the game ends. Note that the collision logic decrements U on a hit rather than terminating immediately, so the player “climbs” faster through obstacles — this appears to be intentional for game feel but means the score accumulation in line 120 continues for one extra frame after a collision.
Notable Anomalies
- Line 200 uses
IF H<S THEN LET H=S — because H starts at 1 rather than 0, a player with a score of 0 will never overwrite the high score even on the first game, which is intentional as a safe guard against resetting to zero.
- Lines 250–280 are unreachable dead code used for development notes:
STOP, two REMs describing how to start and save the program, and a stray RUN.
- The
SAVE at line 275 uses an inverse-digit filename which acts as an auto-run marker in the tape format.
Content
Source Code
1 REM \2A\0E\40\4E\06\00\C9
2 REM SURGE %2%K
3 REM BY TIM ROGERS
4 CLS
5 LET H=1
10 POKE 16517,78
15 LET S=H-H
20 LET U=10
25 LET T=20
30 LET P=U
40 PRINT AT U,P;" "
50 LET P=P-H/H*(P>H/H)
60 LET P=P+(INKEY$<>"")*2*(P<T)
65 SCROLL
70 PRINT AT U,P;
80 IF USR 16514=CODE "% " THEN LET U=U-H/H
90 IF U=H-H THEN GOTO 200
100 PRINT AT U,P;"V"
110 PRINT AT CODE ")",RND*T;"% % % % % "
120 LET S=S+U
130 GOTO 40
200 IF H<S THEN LET H=S
210 PRINT AT U,P;"SURGE",H,S
220 PAUSE 4E4
230 GOTO 15
250 STOP
260 REM RAND USR 14336
270 REM SAVE "SURGE.B1"
275 SAVE "1021%8"
280 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
A
Skip to content
Surge
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
Surge is a ZX81/TS1000 one-screen arcade game in which the player steers a character (“V”) upward through a scrolling field of obstacles while a machine-code routine checks for collisions. The program uses a 7-byte machine-code stub embedded in REM line 1 (loaded via POKE 16517 at line 10), which is called with USR 16514 to perform a character-code check at the player’s screen position. Scrolling is achieved with the SCROLL command, and the player’s horizontal movement is driven by INKEY$ with boundary clamping. The score accumulates as the number of rows the player climbs (line 120: S=S+U decrements as U approaches zero), and a high-score variable H is preserved across restarts.
Program Analysis
Program Structure
The program divides into three logical phases:
- Initialisation (lines 1–25): Machine code is embedded in
REM line 1, the POKE at line 10 patches the program area, and game variables are reset.
- Main game loop (lines 30–130): Moves the player, scrolls the screen, checks for collision via
USR, prints obstacles, and accumulates score.
- Game-over / restart (lines 200–230): Updates high score, displays result, pauses, and loops back to line 15 for a new game without re-running the machine-code setup.
Machine Code in REM Line 1
Line 1 holds the bytes \2A\0E\40\4E\06\00\C9 (7 bytes). In Z80 mnemonics:
Offset Hex Mnemonic Notes 0 2A 0E 40 LD HL,(400Eh) Load HL with the word at address 400Eh (CHARS sysvar area) 3 4E LD C,(HL) Read byte at that address into C 4 06 00 LD B,0 Set B=0, so BC = character code read 6 C9 RET Return BC as the USR result
POKE 16517,78 (line 10) writes 4Eh into the fifth byte of the REM payload, ensuring the LD C,(HL) opcode is correctly placed. The routine is called at USR 16514 (the start of the REM data area). It reads a byte from the display file address held at 400Eh and returns it as a numeric result, allowing the BASIC at line 80 to compare it with CODE "% " (the inverse-space character) to detect a collision with an obstacle.
Variable Usage
Variable Purpose HHigh score (initialised to 1 at line 5; persists across restarts) SCurrent game score UPlayer’s row (counts down toward 0 = top of screen) TRight boundary / screen width limit (20) PPlayer’s column position
Key BASIC Idioms
- Boolean arithmetic for movement: Line 50 uses
P=P-H/H*(P>H/H) — since H is always ≥1, H/H equals 1, so this reads P=P-1*(P>1), clamping P to a minimum of 1 without an IF statement.
- INKEY$ horizontal movement: Line 60 adds 2 to
P whenever any key is held and P<T, giving a simple one-button rightward movement mechanic (releasing the key causes leftward drift).
- Score via row position: Line 120 adds the current row number
U to S each iteration; as the player moves upward, U decreases, so the score grows more slowly the nearer to the top the player reaches. This is a consequence of the accumulation, not deliberate progressive difficulty weighting.
- Obstacle rendering: Line 110 prints a string of five inverse-space characters (
"% % % % % ") at a random row and column, creating short horizontal barriers across the screen.
SCROLL for forced upward motion: The SCROLL on line 65 shifts the entire screen display one line upward each loop iteration, creating the illusion of the player moving through a field of descending obstacles.
Collision Detection
The machine-code routine at USR 16514 returns the character code of the cell at the player’s current position. Line 80 compares this to CODE "% " (inverse space, used as the obstacle tile). If they match, the player row U is decremented; when U reaches 0 (line 90), the game ends. Note that the collision logic decrements U on a hit rather than terminating immediately, so the player “climbs” faster through obstacles — this appears to be intentional for game feel but means the score accumulation in line 120 continues for one extra frame after a collision.
Notable Anomalies
- Line 200 uses
IF H<S THEN LET H=S — because H starts at 1 rather than 0, a player with a score of 0 will never overwrite the high score even on the first game, which is intentional as a safe guard against resetting to zero.
- Lines 250–280 are unreachable dead code used for development notes:
STOP, two REMs describing how to start and save the program, and a stray RUN.
- The
SAVE at line 275 uses an inverse-digit filename which acts as an auto-run marker in the tape format.
Content
Source Code
1 REM \2A\0E\40\4E\06\00\C9
2 REM SURGE %2%K
3 REM BY TIM ROGERS
4 CLS
5 LET H=1
10 POKE 16517,78
15 LET S=H-H
20 LET U=10
25 LET T=20
30 LET P=U
40 PRINT AT U,P;" "
50 LET P=P-H/H*(P>H/H)
60 LET P=P+(INKEY$<>"")*2*(P<T)
65 SCROLL
70 PRINT AT U,P;
80 IF USR 16514=CODE "% " THEN LET U=U-H/H
90 IF U=H-H THEN GOTO 200
100 PRINT AT U,P;"V"
110 PRINT AT CODE ")",RND*T;"% % % % % "
120 LET S=S+U
130 GOTO 40
200 IF H<S THEN LET H=S
210 PRINT AT U,P;"SURGE",H,S
220 PAUSE 4E4
230 GOTO 15
250 STOP
260 REM RAND USR 14336
270 REM SAVE "SURGE.B1"
275 SAVE "1021%8"
280 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
EE
Skip to content
Surge
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
Surge is a ZX81/TS1000 one-screen arcade game in which the player steers a character (“V”) upward through a scrolling field of obstacles while a machine-code routine checks for collisions. The program uses a 7-byte machine-code stub embedded in REM line 1 (loaded via POKE 16517 at line 10), which is called with USR 16514 to perform a character-code check at the player’s screen position. Scrolling is achieved with the SCROLL command, and the player’s horizontal movement is driven by INKEY$ with boundary clamping. The score accumulates as the number of rows the player climbs (line 120: S=S+U decrements as U approaches zero), and a high-score variable H is preserved across restarts.
Program Analysis
Program Structure
The program divides into three logical phases:
- Initialisation (lines 1–25): Machine code is embedded in
REM line 1, the POKE at line 10 patches the program area, and game variables are reset.
- Main game loop (lines 30–130): Moves the player, scrolls the screen, checks for collision via
USR, prints obstacles, and accumulates score.
- Game-over / restart (lines 200–230): Updates high score, displays result, pauses, and loops back to line 15 for a new game without re-running the machine-code setup.
Machine Code in REM Line 1
Line 1 holds the bytes \2A\0E\40\4E\06\00\C9 (7 bytes). In Z80 mnemonics:
Offset Hex Mnemonic Notes 0 2A 0E 40 LD HL,(400Eh) Load HL with the word at address 400Eh (CHARS sysvar area) 3 4E LD C,(HL) Read byte at that address into C 4 06 00 LD B,0 Set B=0, so BC = character code read 6 C9 RET Return BC as the USR result
POKE 16517,78 (line 10) writes 4Eh into the fifth byte of the REM payload, ensuring the LD C,(HL) opcode is correctly placed. The routine is called at USR 16514 (the start of the REM data area). It reads a byte from the display file address held at 400Eh and returns it as a numeric result, allowing the BASIC at line 80 to compare it with CODE "% " (the inverse-space character) to detect a collision with an obstacle.
Variable Usage
Variable Purpose HHigh score (initialised to 1 at line 5; persists across restarts) SCurrent game score UPlayer’s row (counts down toward 0 = top of screen) TRight boundary / screen width limit (20) PPlayer’s column position
Key BASIC Idioms
- Boolean arithmetic for movement: Line 50 uses
P=P-H/H*(P>H/H) — since H is always ≥1, H/H equals 1, so this reads P=P-1*(P>1), clamping P to a minimum of 1 without an IF statement.
- INKEY$ horizontal movement: Line 60 adds 2 to
P whenever any key is held and P<T, giving a simple one-button rightward movement mechanic (releasing the key causes leftward drift).
- Score via row position: Line 120 adds the current row number
U to S each iteration; as the player moves upward, U decreases, so the score grows more slowly the nearer to the top the player reaches. This is a consequence of the accumulation, not deliberate progressive difficulty weighting.
- Obstacle rendering: Line 110 prints a string of five inverse-space characters (
"% % % % % ") at a random row and column, creating short horizontal barriers across the screen.
SCROLL for forced upward motion: The SCROLL on line 65 shifts the entire screen display one line upward each loop iteration, creating the illusion of the player moving through a field of descending obstacles.
Collision Detection
The machine-code routine at USR 16514 returns the character code of the cell at the player’s current position. Line 80 compares this to CODE "% " (inverse space, used as the obstacle tile). If they match, the player row U is decremented; when U reaches 0 (line 90), the game ends. Note that the collision logic decrements U on a hit rather than terminating immediately, so the player “climbs” faster through obstacles — this appears to be intentional for game feel but means the score accumulation in line 120 continues for one extra frame after a collision.
Notable Anomalies
- Line 200 uses
IF H<S THEN LET H=S — because H starts at 1 rather than 0, a player with a score of 0 will never overwrite the high score even on the first game, which is intentional as a safe guard against resetting to zero.
- Lines 250–280 are unreachable dead code used for development notes:
STOP, two REMs describing how to start and save the program, and a stray RUN.
- The
SAVE at line 275 uses an inverse-digit filename which acts as an auto-run marker in the tape format.
Content
Source Code
1 REM \2A\0E\40\4E\06\00\C9
2 REM SURGE %2%K
3 REM BY TIM ROGERS
4 CLS
5 LET H=1
10 POKE 16517,78
15 LET S=H-H
20 LET U=10
25 LET T=20
30 LET P=U
40 PRINT AT U,P;" "
50 LET P=P-H/H*(P>H/H)
60 LET P=P+(INKEY$<>"")*2*(P<T)
65 SCROLL
70 PRINT AT U,P;
80 IF USR 16514=CODE "% " THEN LET U=U-H/H
90 IF U=H-H THEN GOTO 200
100 PRINT AT U,P;"V"
110 PRINT AT CODE ")",RND*T;"% % % % % "
120 LET S=S+U
130 GOTO 40
200 IF H<S THEN LET H=S
210 PRINT AT U,P;"SURGE",H,S
220 PAUSE 4E4
230 GOTO 15
250 STOP
260 REM RAND USR 14336
270 REM SAVE "SURGE.B1"
275 SAVE "1021%8"
280 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
\C9
2 REM SURGE %2%K
3 REM BY TIM ROGERS
4 CLS
5 LET H=1
10 POKE 16517,78
15 LET S=H-H
20 LET U=10
25 LET T=20
30 LET P=U
40 PRINT AT U,P;" "
50 LET P=P-H/H*(P>H/H)
60 LET P=P+(INKEY$<>"")*2*(P<T)
65 SCROLL
70 PRINT AT U,P;
80 IF USR 16514=CODE "% " THEN LET U=U-H/H
90 IF U=H-H THEN GOTO 200
100 PRINT AT U,P;"V"
110 PRINT AT CODE ")",RND*T;"% % % % % "
120 LET S=S+U
130 GOTO 40
200 IF H<S THEN LET H=S
210 PRINT AT U,P;"SURGE",H,S
220 PAUSE 4E4
230 GOTO 15
250 STOP
260 REM RAND USR 14336
270 REM SAVE "SURGE.B1"
275 SAVE "1021%8"
280 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
