This is a two-phase runway landing game where the player guides an aircraft symbol along the ZX81 display file using keyboard controls. The program embeds a machine-code routine in the REM statement at line 1 that performs a fast block-copy of display data, called repeatedly via USR to scroll the runway. The game uses direct PEEK and POKE operations on the display file (base address from system variables at 16396–16397) to detect collisions with obstacles (character codes 3 and 52) and to place the plane sprite (character code 23). Obstacles are injected at calculated positions using modular arithmetic tied to the score variable S, and the game transitions from a horizontal taxiing phase (Z/M keys) to a vertical landing phase (5/8 keys) at score 250.
Program Analysis
Program Structure
The program divides into four logical sections:
- Initialisation (lines 1–6): Machine code stored in the REM, variables set up, display file base address computed.
- Phase 1 – Taxiing (lines 10–50): Player moves horizontally along the runway using Z/M keys; obstacles are periodically placed; score increments each loop.
- Phase 2 – Landing (lines 250–320): Triggered at
S=250; control switches to 5/8 keys for vertical movement; score continues to increment. - End states (lines 100–140, 400–430): Collision leads to a “TOO BAD YOU’RE DEAD” prompt; reaching
S=270leads to a “WELL DONE” prompt. Both offer Y/N replay viaRUN.
Machine Code in the REM (Line 1)
The REM statement at line 1 contains a hand-assembled Z80 routine. Called from BASIC via USR (T) where T=16514 (two bytes past the REM token at the start of the BASIC area), it acts as a scrolling engine that copies display-file rows to produce the runway movement effect. The trailing bytes (ASCII spaces) pad the REM to provide a clean source buffer for the copy loop. The routine ends with C9 (RET), returning control cleanly to BASIC, and its return value is captured in A (though unused).
Decoded Z80 bytes of interest:
Skip to content–A Skip to contentRunway
This file is part of and Timex Sinclair Public Domain Library Tape 1006. Download the collection to get this file.This is a two-phase runway landing game where the player guides an aircraft symbol along the ZX81 display file using keyboard controls. The program embeds a machine-code routine in the REM statement at line 1 that performs a fast block-copy of display data, called repeatedly via USR to scroll the runway. The game uses direct PEEK and POKE operations on the display file (base address from system variables at 16396–16397) to detect collisions with obstacles (character codes 3 and 52) and to place the plane sprite (character code 23). Obstacles are injected at calculated positions using modular arithmetic tied to the score variable S, and the game transitions from a horizontal taxiing phase (Z/M keys) to a vertical landing phase (5/8 keys) at score 250.
Program Analysis
Program Structure
The program divides into four logical sections:
- Initialisation (lines 1–6): Machine code stored in the REM, variables set up, display file base address computed.
- Phase 1 – Taxiing (lines 10–50): Player moves horizontally along the runway using Z/M keys; obstacles are periodically placed; score increments each loop.
- Phase 2 – Landing (lines 250–320): Triggered at
S=250; control switches to 5/8 keys for vertical movement; score continues to increment. - End states (lines 100–140, 400–430): Collision leads to a “TOO BAD YOU’RE DEAD” prompt; reaching
S=270leads to a “WELL DONE” prompt. Both offer Y/N replay viaRUN.
Machine Code in the REM (Line 1)
The REM statement at line 1 contains a hand-assembled Z80 routine. Called from BASIC via
USR (T)whereT=16514(two bytes past the REM token at the start of the BASIC area), it acts as a scrolling engine that copies display-file rows to produce the runway movement effect. The trailing\32bytes (ASCII spaces) pad the REM to provide a clean source buffer for the copy loop. The routine ends withC9(RET), returning control cleanly to BASIC, and its return value is captured inA(though unused).Decoded Z80 bytes of interest:
\2A\0C\40–LD HL,(4012H): loads display file address\11\72\02–LD DE,0272H: sets destination offset (one row down)\E5/\D1/\E1– stack-based register juggling for block copy\10\FD–DJNZinner loop;\0D\20\F5–DEC C; JR NZouter loopC9–RET
Display File Addressing
W(line 5) is computed asPEEK 16396 + 256*PEEK 16397, the standard ZX81 method for reading the system variable D_FILE (address 16396). All subsequent character placement and collision detection is performed by adding offsetVtoW. The modular expressionW+V-33*INT(V/33)at line 22 converts the flat offset into a column position within a 33-byte-wide display row (32 characters + newline), used to inject obstacles at the correct screen column.Key BASIC Idioms
- Boolean arithmetic for movement:
V=V+(INKEY$="M")-(INKEY$="Z")(line 30) andV=V+(INKEY$="8")-(INKEY$="5")(line 260) exploit the ZX81’s 0/1 boolean results to update the plane position in a single expression without IF statements. - Collision detection by character code:
PEEK(W+V)=3tests for the newline character (column boundary / wall) and=52tests for the obstacle character, implementing boundary and hazard detection purely through display memory reads. - Score-driven level progression: Milestones at
S=100,150,200(lines 41–43) subtract multiples of 33 fromVto jump the plane up one or more display rows, simulating approach descent;S=250triggers phase 2.
Obstacle Generation
Line 22 checks whether the units digit of
S(computed asS-R*10whereR=INT(S/10)) equals 9, 6, or 4, and if so POKEs character 52 at a display position derived fromVmodulo 33 offset by 99 (three rows ahead). This creates a deterministic but varied obstacle pattern timed to the score counter rather than real time.Plane and Obstacle Characters
Code Character Role 23Inverse-video block graphic Player plane sprite 52Block graphic / obstacle Runway hazard 3Newline (display file) Edge/wall boundary 61Explosion/crash glyph Crash marker (line 100) Notable Anomalies
- Lines 440–460 (
CLEAR,SAVE "1025%5",RUN) appear after all reachable game logic and are never executed during normal play; they are likely a loader/auto-save remnant left over from development. - The replay prompt loop (lines 120–140 and 410–430) uses
INPUT Y$/INPUT X$, which on the ZX81 requires the user to press ENTER after the key, making single-keypress replay impossible without modification. LET A=USR(T)is called in both phase loops (lines 20 and 310) but the return value inAis never subsequently read, suggesting the call is made purely for its side-effect of running the scroll routine.
Content
Source Code
1 REM \2A\0C\40\11\72\02\19\E5\06\21\23\10\FD\E5\D1\E1\0E\13\06\21\7E\12\1B\2B\10\FA\0D\20\F5\C9\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32 2 LET S=0 3 LET T=16514 4 LET V=411 5 LET W=PEEK 16396+256*PEEK 16397 6 CLS 7 PRINT AT 20,9;"**%R%U%N%W%A%Y**" 10 PRINT AT 1,10;"\'' \. \''" 20 LET A=USR (T) 21 LET R=INT (S/10) 22 IF S-R*10=9 OR S-R*10=6 OR S-R*10=4 THEN POKE W+V-33*INT (V/33)+99,52 30 LET V=V+(INKEY$="M")-(INKEY$="Z") 35 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100 40 POKE W+V,23 41 IF S=100 THEN LET V=V-66 42 IF S=150 THEN LET V=V-33 43 IF S=200 THEN LET V=V-99 44 IF S=250 THEN GOTO 250 45 LET S=S+1 50 GOTO 10 100 POKE W+V,61 110 PRINT AT 21,0;"%T%O%O% %B%A%D% %Y%O%U%R% %D%E%A%D REPLAY Y/N ?" 120 INPUT Y$ 130 IF Y$="Y" THEN RUN 140 GOTO 120 250 PRINT AT 1,10;" " 260 LET V=V+(INKEY$="8")-(INKEY$="5") 270 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100 280 POKE W+V,23 290 LET S=S+1 300 IF S=270 THEN GOTO 400 310 LET A=USR (T) 320 GOTO 250 400 PRINT AT 21,0;"%W%E%L%L% %D%O%N%E REPLAY Y/N ?" 410 INPUT X$ 420 IF X$="Y" THEN RUN 430 GOTO 410 440 CLEAR 450 SAVE "1025%5" 460 RUNNote: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
CRunway
This file is part of and Timex Sinclair Public Domain Library Tape 1006. Download the collection to get this file.This is a two-phase runway landing game where the player guides an aircraft symbol along the ZX81 display file using keyboard controls. The program embeds a machine-code routine in the REM statement at line 1 that performs a fast block-copy of display data, called repeatedly via USR to scroll the runway. The game uses direct PEEK and POKE operations on the display file (base address from system variables at 16396–16397) to detect collisions with obstacles (character codes 3 and 52) and to place the plane sprite (character code 23). Obstacles are injected at calculated positions using modular arithmetic tied to the score variable S, and the game transitions from a horizontal taxiing phase (Z/M keys) to a vertical landing phase (5/8 keys) at score 250.
Program Analysis
Program Structure
The program divides into four logical sections:
- Initialisation (lines 1–6): Machine code stored in the REM, variables set up, display file base address computed.
- Phase 1 – Taxiing (lines 10–50): Player moves horizontally along the runway using Z/M keys; obstacles are periodically placed; score increments each loop.
- Phase 2 – Landing (lines 250–320): Triggered at
S=250; control switches to 5/8 keys for vertical movement; score continues to increment. - End states (lines 100–140, 400–430): Collision leads to a “TOO BAD YOU’RE DEAD” prompt; reaching
S=270leads to a “WELL DONE” prompt. Both offer Y/N replay viaRUN.
Machine Code in the REM (Line 1)
The REM statement at line 1 contains a hand-assembled Z80 routine. Called from BASIC via
USR (T)whereT=16514(two bytes past the REM token at the start of the BASIC area), it acts as a scrolling engine that copies display-file rows to produce the runway movement effect. The trailing\32bytes (ASCII spaces) pad the REM to provide a clean source buffer for the copy loop. The routine ends withC9(RET), returning control cleanly to BASIC, and its return value is captured inA(though unused).Decoded Z80 bytes of interest:
\2A\0C\40–LD HL,(4012H): loads display file address\11\72\02–LD DE,0272H: sets destination offset (one row down)\E5/\D1/\E1– stack-based register juggling for block copy\10\FD–DJNZinner loop;\0D\20\F5–DEC C; JR NZouter loopC9–RET
Display File Addressing
W(line 5) is computed asPEEK 16396 + 256*PEEK 16397, the standard ZX81 method for reading the system variable D_FILE (address 16396). All subsequent character placement and collision detection is performed by adding offsetVtoW. The modular expressionW+V-33*INT(V/33)at line 22 converts the flat offset into a column position within a 33-byte-wide display row (32 characters + newline), used to inject obstacles at the correct screen column.Key BASIC Idioms
- Boolean arithmetic for movement:
V=V+(INKEY$="M")-(INKEY$="Z")(line 30) andV=V+(INKEY$="8")-(INKEY$="5")(line 260) exploit the ZX81’s 0/1 boolean results to update the plane position in a single expression without IF statements. - Collision detection by character code:
PEEK(W+V)=3tests for the newline character (column boundary / wall) and=52tests for the obstacle character, implementing boundary and hazard detection purely through display memory reads. - Score-driven level progression: Milestones at
S=100,150,200(lines 41–43) subtract multiples of 33 fromVto jump the plane up one or more display rows, simulating approach descent;S=250triggers phase 2.
Obstacle Generation
Line 22 checks whether the units digit of
S(computed asS-R*10whereR=INT(S/10)) equals 9, 6, or 4, and if so POKEs character 52 at a display position derived fromVmodulo 33 offset by 99 (three rows ahead). This creates a deterministic but varied obstacle pattern timed to the score counter rather than real time.Plane and Obstacle Characters
Code Character Role 23Inverse-video block graphic Player plane sprite 52Block graphic / obstacle Runway hazard 3Newline (display file) Edge/wall boundary 61Explosion/crash glyph Crash marker (line 100) Notable Anomalies
- Lines 440–460 (
CLEAR,SAVE "1025%5",RUN) appear after all reachable game logic and are never executed during normal play; they are likely a loader/auto-save remnant left over from development. - The replay prompt loop (lines 120–140 and 410–430) uses
INPUT Y$/INPUT X$, which on the ZX81 requires the user to press ENTER after the key, making single-keypress replay impossible without modification. LET A=USR(T)is called in both phase loops (lines 20 and 310) but the return value inAis never subsequently read, suggesting the call is made purely for its side-effect of running the scroll routine.
Content
Source Code
1 REM \2A\0C\40\11\72\02\19\E5\06\21\23\10\FD\E5\D1\E1\0E\13\06\21\7E\12\1B\2B\10\FA\0D\20\F5\C9\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32 2 LET S=0 3 LET T=16514 4 LET V=411 5 LET W=PEEK 16396+256*PEEK 16397 6 CLS 7 PRINT AT 20,9;"**%R%U%N%W%A%Y**" 10 PRINT AT 1,10;"\'' \. \''" 20 LET A=USR (T) 21 LET R=INT (S/10) 22 IF S-R*10=9 OR S-R*10=6 OR S-R*10=4 THEN POKE W+V-33*INT (V/33)+99,52 30 LET V=V+(INKEY$="M")-(INKEY$="Z") 35 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100 40 POKE W+V,23 41 IF S=100 THEN LET V=V-66 42 IF S=150 THEN LET V=V-33 43 IF S=200 THEN LET V=V-99 44 IF S=250 THEN GOTO 250 45 LET S=S+1 50 GOTO 10 100 POKE W+V,61 110 PRINT AT 21,0;"%T%O%O% %B%A%D% %Y%O%U%R% %D%E%A%D REPLAY Y/N ?" 120 INPUT Y$ 130 IF Y$="Y" THEN RUN 140 GOTO 120 250 PRINT AT 1,10;" " 260 LET V=V+(INKEY$="8")-(INKEY$="5") 270 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100 280 POKE W+V,23 290 LET S=S+1 300 IF S=270 THEN GOTO 400 310 LET A=USR (T) 320 GOTO 250 400 PRINT AT 21,0;"%W%E%L%L% %D%O%N%E REPLAY Y/N ?" 410 INPUT X$ 420 IF X$="Y" THEN RUN 430 GOTO 410 440 CLEAR 450 SAVE "1025%5" 460 RUNNote: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
LD HL,(4012H): loads display file addressSkip to content–Runway
This file is part of and Timex Sinclair Public Domain Library Tape 1006. Download the collection to get this file.This is a two-phase runway landing game where the player guides an aircraft symbol along the ZX81 display file using keyboard controls. The program embeds a machine-code routine in the REM statement at line 1 that performs a fast block-copy of display data, called repeatedly via USR to scroll the runway. The game uses direct PEEK and POKE operations on the display file (base address from system variables at 16396–16397) to detect collisions with obstacles (character codes 3 and 52) and to place the plane sprite (character code 23). Obstacles are injected at calculated positions using modular arithmetic tied to the score variable S, and the game transitions from a horizontal taxiing phase (Z/M keys) to a vertical landing phase (5/8 keys) at score 250.
Program Analysis
Program Structure
The program divides into four logical sections:
- Initialisation (lines 1–6): Machine code stored in the REM, variables set up, display file base address computed.
- Phase 1 – Taxiing (lines 10–50): Player moves horizontally along the runway using Z/M keys; obstacles are periodically placed; score increments each loop.
- Phase 2 – Landing (lines 250–320): Triggered at
S=250; control switches to 5/8 keys for vertical movement; score continues to increment. - End states (lines 100–140, 400–430): Collision leads to a “TOO BAD YOU’RE DEAD” prompt; reaching
S=270leads to a “WELL DONE” prompt. Both offer Y/N replay viaRUN.
Machine Code in the REM (Line 1)
The REM statement at line 1 contains a hand-assembled Z80 routine. Called from BASIC via
USR (T)whereT=16514(two bytes past the REM token at the start of the BASIC area), it acts as a scrolling engine that copies display-file rows to produce the runway movement effect. The trailing\32bytes (ASCII spaces) pad the REM to provide a clean source buffer for the copy loop. The routine ends withC9(RET), returning control cleanly to BASIC, and its return value is captured inA(though unused).Decoded Z80 bytes of interest:
\2A\0C\40–LD HL,(4012H): loads display file address\11\72\02–LD DE,0272H: sets destination offset (one row down)\E5/\D1/\E1– stack-based register juggling for block copy\10\FD–DJNZinner loop;\0D\20\F5–DEC C; JR NZouter loopC9–RET
Display File Addressing
W(line 5) is computed asPEEK 16396 + 256*PEEK 16397, the standard ZX81 method for reading the system variable D_FILE (address 16396). All subsequent character placement and collision detection is performed by adding offsetVtoW. The modular expressionW+V-33*INT(V/33)at line 22 converts the flat offset into a column position within a 33-byte-wide display row (32 characters + newline), used to inject obstacles at the correct screen column.Key BASIC Idioms
- Boolean arithmetic for movement:
V=V+(INKEY$="M")-(INKEY$="Z")(line 30) andV=V+(INKEY$="8")-(INKEY$="5")(line 260) exploit the ZX81’s 0/1 boolean results to update the plane position in a single expression without IF statements. - Collision detection by character code:
PEEK(W+V)=3tests for the newline character (column boundary / wall) and=52tests for the obstacle character, implementing boundary and hazard detection purely through display memory reads. - Score-driven level progression: Milestones at
S=100,150,200(lines 41–43) subtract multiples of 33 fromVto jump the plane up one or more display rows, simulating approach descent;S=250triggers phase 2.
Obstacle Generation
Line 22 checks whether the units digit of
S(computed asS-R*10whereR=INT(S/10)) equals 9, 6, or 4, and if so POKEs character 52 at a display position derived fromVmodulo 33 offset by 99 (three rows ahead). This creates a deterministic but varied obstacle pattern timed to the score counter rather than real time.Plane and Obstacle Characters
Code Character Role 23Inverse-video block graphic Player plane sprite 52Block graphic / obstacle Runway hazard 3Newline (display file) Edge/wall boundary 61Explosion/crash glyph Crash marker (line 100) Notable Anomalies
- Lines 440–460 (
CLEAR,SAVE "1025%5",RUN) appear after all reachable game logic and are never executed during normal play; they are likely a loader/auto-save remnant left over from development. - The replay prompt loop (lines 120–140 and 410–430) uses
INPUT Y$/INPUT X$, which on the ZX81 requires the user to press ENTER after the key, making single-keypress replay impossible without modification. LET A=USR(T)is called in both phase loops (lines 20 and 310) but the return value inAis never subsequently read, suggesting the call is made purely for its side-effect of running the scroll routine.
Content
Source Code
1 REM \2A\0C\40\11\72\02\19\E5\06\21\23\10\FD\E5\D1\E1\0E\13\06\21\7E\12\1B\2B\10\FA\0D\20\F5\C9\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32 2 LET S=0 3 LET T=16514 4 LET V=411 5 LET W=PEEK 16396+256*PEEK 16397 6 CLS 7 PRINT AT 20,9;"**%R%U%N%W%A%Y**" 10 PRINT AT 1,10;"\'' \. \''" 20 LET A=USR (T) 21 LET R=INT (S/10) 22 IF S-R*10=9 OR S-R*10=6 OR S-R*10=4 THEN POKE W+V-33*INT (V/33)+99,52 30 LET V=V+(INKEY$="M")-(INKEY$="Z") 35 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100 40 POKE W+V,23 41 IF S=100 THEN LET V=V-66 42 IF S=150 THEN LET V=V-33 43 IF S=200 THEN LET V=V-99 44 IF S=250 THEN GOTO 250 45 LET S=S+1 50 GOTO 10 100 POKE W+V,61 110 PRINT AT 21,0;"%T%O%O% %B%A%D% %Y%O%U%R% %D%E%A%D REPLAY Y/N ?" 120 INPUT Y$ 130 IF Y$="Y" THEN RUN 140 GOTO 120 250 PRINT AT 1,10;" " 260 LET V=V+(INKEY$="8")-(INKEY$="5") 270 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100 280 POKE W+V,23 290 LET S=S+1 300 IF S=270 THEN GOTO 400 310 LET A=USR (T) 320 GOTO 250 400 PRINT AT 21,0;"%W%E%L%L% %D%O%N%E REPLAY Y/N ?" 410 INPUT X$ 420 IF X$="Y" THEN RUN 430 GOTO 410 440 CLEAR 450 SAVE "1025%5" 460 RUNNote: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
LD DE,0272H: sets destination offset (one row down)\E5/\D1/\E1– stack-based register juggling for block copy\FD–DJNZinner loop;Skip to content–D\F5Runway
This file is part of and Timex Sinclair Public Domain Library Tape 1006. Download the collection to get this file.This is a two-phase runway landing game where the player guides an aircraft symbol along the ZX81 display file using keyboard controls. The program embeds a machine-code routine in the REM statement at line 1 that performs a fast block-copy of display data, called repeatedly via USR to scroll the runway. The game uses direct PEEK and POKE operations on the display file (base address from system variables at 16396–16397) to detect collisions with obstacles (character codes 3 and 52) and to place the plane sprite (character code 23). Obstacles are injected at calculated positions using modular arithmetic tied to the score variable S, and the game transitions from a horizontal taxiing phase (Z/M keys) to a vertical landing phase (5/8 keys) at score 250.
Program Analysis
Program Structure
The program divides into four logical sections:
- Initialisation (lines 1–6): Machine code stored in the REM, variables set up, display file base address computed.
- Phase 1 – Taxiing (lines 10–50): Player moves horizontally along the runway using Z/M keys; obstacles are periodically placed; score increments each loop.
- Phase 2 – Landing (lines 250–320): Triggered at
S=250; control switches to 5/8 keys for vertical movement; score continues to increment. - End states (lines 100–140, 400–430): Collision leads to a “TOO BAD YOU’RE DEAD” prompt; reaching
S=270leads to a “WELL DONE” prompt. Both offer Y/N replay viaRUN.
Machine Code in the REM (Line 1)
The REM statement at line 1 contains a hand-assembled Z80 routine. Called from BASIC via
USR (T)whereT=16514(two bytes past the REM token at the start of the BASIC area), it acts as a scrolling engine that copies display-file rows to produce the runway movement effect. The trailing\32bytes (ASCII spaces) pad the REM to provide a clean source buffer for the copy loop. The routine ends withC9(RET), returning control cleanly to BASIC, and its return value is captured inA(though unused).Decoded Z80 bytes of interest:
\2A\0C\40–LD HL,(4012H): loads display file address\11\72\02–LD DE,0272H: sets destination offset (one row down)\E5/\D1/\E1– stack-based register juggling for block copy\10\FD–DJNZinner loop;\0D\20\F5–DEC C; JR NZouter loopC9–RET
Display File Addressing
W(line 5) is computed asPEEK 16396 + 256*PEEK 16397, the standard ZX81 method for reading the system variable D_FILE (address 16396). All subsequent character placement and collision detection is performed by adding offsetVtoW. The modular expressionW+V-33*INT(V/33)at line 22 converts the flat offset into a column position within a 33-byte-wide display row (32 characters + newline), used to inject obstacles at the correct screen column.Key BASIC Idioms
- Boolean arithmetic for movement:
V=V+(INKEY$="M")-(INKEY$="Z")(line 30) andV=V+(INKEY$="8")-(INKEY$="5")(line 260) exploit the ZX81’s 0/1 boolean results to update the plane position in a single expression without IF statements. - Collision detection by character code:
PEEK(W+V)=3tests for the newline character (column boundary / wall) and=52tests for the obstacle character, implementing boundary and hazard detection purely through display memory reads. - Score-driven level progression: Milestones at
S=100,150,200(lines 41–43) subtract multiples of 33 fromVto jump the plane up one or more display rows, simulating approach descent;S=250triggers phase 2.
Obstacle Generation
Line 22 checks whether the units digit of
S(computed asS-R*10whereR=INT(S/10)) equals 9, 6, or 4, and if so POKEs character 52 at a display position derived fromVmodulo 33 offset by 99 (three rows ahead). This creates a deterministic but varied obstacle pattern timed to the score counter rather than real time.Plane and Obstacle Characters
Code Character Role 23Inverse-video block graphic Player plane sprite 52Block graphic / obstacle Runway hazard 3Newline (display file) Edge/wall boundary 61Explosion/crash glyph Crash marker (line 100) Notable Anomalies
- Lines 440–460 (
CLEAR,SAVE "1025%5",RUN) appear after all reachable game logic and are never executed during normal play; they are likely a loader/auto-save remnant left over from development. - The replay prompt loop (lines 120–140 and 410–430) uses
INPUT Y$/INPUT X$, which on the ZX81 requires the user to press ENTER after the key, making single-keypress replay impossible without modification. LET A=USR(T)is called in both phase loops (lines 20 and 310) but the return value inAis never subsequently read, suggesting the call is made purely for its side-effect of running the scroll routine.
Content
Source Code
1 REM \2A\0C\40\11\72\02\19\E5\06\21\23\10\FD\E5\D1\E1\0E\13\06\21\7E\12\1B\2B\10\FA\0D\20\F5\C9\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32 2 LET S=0 3 LET T=16514 4 LET V=411 5 LET W=PEEK 16396+256*PEEK 16397 6 CLS 7 PRINT AT 20,9;"**%R%U%N%W%A%Y**" 10 PRINT AT 1,10;"\'' \. \''" 20 LET A=USR (T) 21 LET R=INT (S/10) 22 IF S-R*10=9 OR S-R*10=6 OR S-R*10=4 THEN POKE W+V-33*INT (V/33)+99,52 30 LET V=V+(INKEY$="M")-(INKEY$="Z") 35 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100 40 POKE W+V,23 41 IF S=100 THEN LET V=V-66 42 IF S=150 THEN LET V=V-33 43 IF S=200 THEN LET V=V-99 44 IF S=250 THEN GOTO 250 45 LET S=S+1 50 GOTO 10 100 POKE W+V,61 110 PRINT AT 21,0;"%T%O%O% %B%A%D% %Y%O%U%R% %D%E%A%D REPLAY Y/N ?" 120 INPUT Y$ 130 IF Y$="Y" THEN RUN 140 GOTO 120 250 PRINT AT 1,10;" " 260 LET V=V+(INKEY$="8")-(INKEY$="5") 270 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100 280 POKE W+V,23 290 LET S=S+1 300 IF S=270 THEN GOTO 400 310 LET A=USR (T) 320 GOTO 250 400 PRINT AT 21,0;"%W%E%L%L% %D%O%N%E REPLAY Y/N ?" 410 INPUT X$ 420 IF X$="Y" THEN RUN 430 GOTO 410 440 CLEAR 450 SAVE "1025%5" 460 RUNNote: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
DEC C; JR NZouter loopC9–RET
Display File Addressing
W (line 5) is computed as PEEK 16396 + 256*PEEK 16397, the standard ZX81 method for reading the system variable D_FILE (address 16396). All subsequent character placement and collision detection is performed by adding offset V to W. The modular expression W+V-33*INT(V/33) at line 22 converts the flat offset into a column position within a 33-byte-wide display row (32 characters + newline), used to inject obstacles at the correct screen column.
Key BASIC Idioms
- Boolean arithmetic for movement:
V=V+(INKEY$="M")-(INKEY$="Z")(line 30) andV=V+(INKEY$="8")-(INKEY$="5")(line 260) exploit the ZX81’s 0/1 boolean results to update the plane position in a single expression without IF statements. - Collision detection by character code:
PEEK(W+V)=3tests for the newline character (column boundary / wall) and=52tests for the obstacle character, implementing boundary and hazard detection purely through display memory reads. - Score-driven level progression: Milestones at
S=100,150,200(lines 41–43) subtract multiples of 33 fromVto jump the plane up one or more display rows, simulating approach descent;S=250triggers phase 2.
Obstacle Generation
Line 22 checks whether the units digit of S (computed as S-R*10 where R=INT(S/10)) equals 9, 6, or 4, and if so POKEs character 52 at a display position derived from V modulo 33 offset by 99 (three rows ahead). This creates a deterministic but varied obstacle pattern timed to the score counter rather than real time.
Plane and Obstacle Characters
| Code | Character | Role |
|---|---|---|
23 | Inverse-video block graphic | Player plane sprite |
52 | Block graphic / obstacle | Runway hazard |
3 | Newline (display file) | Edge/wall boundary |
61 | Explosion/crash glyph | Crash marker (line 100) |
Notable Anomalies
- Lines 440–460 (
CLEAR,SAVE "1025%5",RUN) appear after all reachable game logic and are never executed during normal play; they are likely a loader/auto-save remnant left over from development. - The replay prompt loop (lines 120–140 and 410–430) uses
INPUT Y$/INPUT X$, which on the ZX81 requires the user to press ENTER after the key, making single-keypress replay impossible without modification. LET A=USR(T)is called in both phase loops (lines 20 and 310) but the return value inAis never subsequently read, suggesting the call is made purely for its side-effect of running the scroll routine.
Content
Source Code
1 REM
Skip to content
Runway
This file is part of and Timex Sinclair Public Domain Library Tape 1006. Download the collection to get this file.
This is a two-phase runway landing game where the player guides an aircraft symbol along the ZX81 display file using keyboard controls. The program embeds a machine-code routine in the REM statement at line 1 that performs a fast block-copy of display data, called repeatedly via USR to scroll the runway. The game uses direct PEEK and POKE operations on the display file (base address from system variables at 16396–16397) to detect collisions with obstacles (character codes 3 and 52) and to place the plane sprite (character code 23). Obstacles are injected at calculated positions using modular arithmetic tied to the score variable S, and the game transitions from a horizontal taxiing phase (Z/M keys) to a vertical landing phase (5/8 keys) at score 250.
Program Analysis
Program Structure
The program divides into four logical sections:
- Initialisation (lines 1–6): Machine code stored in the REM, variables set up, display file base address computed.
- Phase 1 – Taxiing (lines 10–50): Player moves horizontally along the runway using Z/M keys; obstacles are periodically placed; score increments each loop.
- Phase 2 – Landing (lines 250–320): Triggered at
S=250; control switches to 5/8 keys for vertical movement; score continues to increment.
- End states (lines 100–140, 400–430): Collision leads to a “TOO BAD YOU’RE DEAD” prompt; reaching
S=270 leads to a “WELL DONE” prompt. Both offer Y/N replay via RUN.
Machine Code in the REM (Line 1)
The REM statement at line 1 contains a hand-assembled Z80 routine. Called from BASIC via USR (T) where T=16514 (two bytes past the REM token at the start of the BASIC area), it acts as a scrolling engine that copies display-file rows to produce the runway movement effect. The trailing \32 bytes (ASCII spaces) pad the REM to provide a clean source buffer for the copy loop. The routine ends with C9 (RET), returning control cleanly to BASIC, and its return value is captured in A (though unused).
Decoded Z80 bytes of interest:
\2A\0C\40 – LD HL,(4012H): loads display file address
\11\72\02 – LD DE,0272H: sets destination offset (one row down)
\E5 / \D1 / \E1 – stack-based register juggling for block copy
\10\FD – DJNZ inner loop; \0D\20\F5 – DEC C; JR NZ outer loop
C9 – RET
Display File Addressing
W (line 5) is computed as PEEK 16396 + 256*PEEK 16397, the standard ZX81 method for reading the system variable D_FILE (address 16396). All subsequent character placement and collision detection is performed by adding offset V to W. The modular expression W+V-33*INT(V/33) at line 22 converts the flat offset into a column position within a 33-byte-wide display row (32 characters + newline), used to inject obstacles at the correct screen column.
Key BASIC Idioms
- Boolean arithmetic for movement:
V=V+(INKEY$="M")-(INKEY$="Z") (line 30) and V=V+(INKEY$="8")-(INKEY$="5") (line 260) exploit the ZX81’s 0/1 boolean results to update the plane position in a single expression without IF statements.
- Collision detection by character code:
PEEK(W+V)=3 tests for the newline character (column boundary / wall) and =52 tests for the obstacle character, implementing boundary and hazard detection purely through display memory reads.
- Score-driven level progression: Milestones at
S=100, 150, 200 (lines 41–43) subtract multiples of 33 from V to jump the plane up one or more display rows, simulating approach descent; S=250 triggers phase 2.
Obstacle Generation
Line 22 checks whether the units digit of S (computed as S-R*10 where R=INT(S/10)) equals 9, 6, or 4, and if so POKEs character 52 at a display position derived from V modulo 33 offset by 99 (three rows ahead). This creates a deterministic but varied obstacle pattern timed to the score counter rather than real time.
Plane and Obstacle Characters
Code Character Role 23Inverse-video block graphic Player plane sprite 52Block graphic / obstacle Runway hazard 3Newline (display file) Edge/wall boundary 61Explosion/crash glyph Crash marker (line 100)
Notable Anomalies
- Lines 440–460 (
CLEAR, SAVE "1025%5", RUN) appear after all reachable game logic and are never executed during normal play; they are likely a loader/auto-save remnant left over from development.
- The replay prompt loop (lines 120–140 and 410–430) uses
INPUT Y$/INPUT X$, which on the ZX81 requires the user to press ENTER after the key, making single-keypress replay impossible without modification.
LET A=USR(T) is called in both phase loops (lines 20 and 310) but the return value in A is never subsequently read, suggesting the call is made purely for its side-effect of running the scroll routine.
Content
Source Code
1 REM \2A\0C\40\11\72\02\19\E5\06\21\23\10\FD\E5\D1\E1\0E\13\06\21\7E\12\1B\2B\10\FA\0D\20\F5\C9\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32
2 LET S=0
3 LET T=16514
4 LET V=411
5 LET W=PEEK 16396+256*PEEK 16397
6 CLS
7 PRINT AT 20,9;"**%R%U%N%W%A%Y**"
10 PRINT AT 1,10;"\'' \. \''"
20 LET A=USR (T)
21 LET R=INT (S/10)
22 IF S-R*10=9 OR S-R*10=6 OR S-R*10=4 THEN POKE W+V-33*INT (V/33)+99,52
30 LET V=V+(INKEY$="M")-(INKEY$="Z")
35 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100
40 POKE W+V,23
41 IF S=100 THEN LET V=V-66
42 IF S=150 THEN LET V=V-33
43 IF S=200 THEN LET V=V-99
44 IF S=250 THEN GOTO 250
45 LET S=S+1
50 GOTO 10
100 POKE W+V,61
110 PRINT AT 21,0;"%T%O%O% %B%A%D% %Y%O%U%R% %D%E%A%D REPLAY Y/N ?"
120 INPUT Y$
130 IF Y$="Y" THEN RUN
140 GOTO 120
250 PRINT AT 1,10;" "
260 LET V=V+(INKEY$="8")-(INKEY$="5")
270 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100
280 POKE W+V,23
290 LET S=S+1
300 IF S=270 THEN GOTO 400
310 LET A=USR (T)
320 GOTO 250
400 PRINT AT 21,0;"%W%E%L%L% %D%O%N%E REPLAY Y/N ?"
410 INPUT X$
420 IF X$="Y" THEN RUN
430 GOTO 410
440 CLEAR
450 SAVE "1025%5"
460 RUN
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
Runway
This file is part of and Timex Sinclair Public Domain Library Tape 1006. Download the collection to get this file.
This is a two-phase runway landing game where the player guides an aircraft symbol along the ZX81 display file using keyboard controls. The program embeds a machine-code routine in the REM statement at line 1 that performs a fast block-copy of display data, called repeatedly via USR to scroll the runway. The game uses direct PEEK and POKE operations on the display file (base address from system variables at 16396–16397) to detect collisions with obstacles (character codes 3 and 52) and to place the plane sprite (character code 23). Obstacles are injected at calculated positions using modular arithmetic tied to the score variable S, and the game transitions from a horizontal taxiing phase (Z/M keys) to a vertical landing phase (5/8 keys) at score 250.
Program Analysis
Program Structure
The program divides into four logical sections:
- Initialisation (lines 1–6): Machine code stored in the REM, variables set up, display file base address computed.
- Phase 1 – Taxiing (lines 10–50): Player moves horizontally along the runway using Z/M keys; obstacles are periodically placed; score increments each loop.
- Phase 2 – Landing (lines 250–320): Triggered at
S=250; control switches to 5/8 keys for vertical movement; score continues to increment.
- End states (lines 100–140, 400–430): Collision leads to a “TOO BAD YOU’RE DEAD” prompt; reaching
S=270 leads to a “WELL DONE” prompt. Both offer Y/N replay via RUN.
Machine Code in the REM (Line 1)
The REM statement at line 1 contains a hand-assembled Z80 routine. Called from BASIC via USR (T) where T=16514 (two bytes past the REM token at the start of the BASIC area), it acts as a scrolling engine that copies display-file rows to produce the runway movement effect. The trailing \32 bytes (ASCII spaces) pad the REM to provide a clean source buffer for the copy loop. The routine ends with C9 (RET), returning control cleanly to BASIC, and its return value is captured in A (though unused).
Decoded Z80 bytes of interest:
\2A\0C\40 – LD HL,(4012H): loads display file address
\11\72\02 – LD DE,0272H: sets destination offset (one row down)
\E5 / \D1 / \E1 – stack-based register juggling for block copy
\10\FD – DJNZ inner loop; \0D\20\F5 – DEC C; JR NZ outer loop
C9 – RET
Display File Addressing
W (line 5) is computed as PEEK 16396 + 256*PEEK 16397, the standard ZX81 method for reading the system variable D_FILE (address 16396). All subsequent character placement and collision detection is performed by adding offset V to W. The modular expression W+V-33*INT(V/33) at line 22 converts the flat offset into a column position within a 33-byte-wide display row (32 characters + newline), used to inject obstacles at the correct screen column.
Key BASIC Idioms
- Boolean arithmetic for movement:
V=V+(INKEY$="M")-(INKEY$="Z") (line 30) and V=V+(INKEY$="8")-(INKEY$="5") (line 260) exploit the ZX81’s 0/1 boolean results to update the plane position in a single expression without IF statements.
- Collision detection by character code:
PEEK(W+V)=3 tests for the newline character (column boundary / wall) and =52 tests for the obstacle character, implementing boundary and hazard detection purely through display memory reads.
- Score-driven level progression: Milestones at
S=100, 150, 200 (lines 41–43) subtract multiples of 33 from V to jump the plane up one or more display rows, simulating approach descent; S=250 triggers phase 2.
Obstacle Generation
Line 22 checks whether the units digit of S (computed as S-R*10 where R=INT(S/10)) equals 9, 6, or 4, and if so POKEs character 52 at a display position derived from V modulo 33 offset by 99 (three rows ahead). This creates a deterministic but varied obstacle pattern timed to the score counter rather than real time.
Plane and Obstacle Characters
Code Character Role 23Inverse-video block graphic Player plane sprite 52Block graphic / obstacle Runway hazard 3Newline (display file) Edge/wall boundary 61Explosion/crash glyph Crash marker (line 100)
Notable Anomalies
- Lines 440–460 (
CLEAR, SAVE "1025%5", RUN) appear after all reachable game logic and are never executed during normal play; they are likely a loader/auto-save remnant left over from development.
- The replay prompt loop (lines 120–140 and 410–430) uses
INPUT Y$/INPUT X$, which on the ZX81 requires the user to press ENTER after the key, making single-keypress replay impossible without modification.
LET A=USR(T) is called in both phase loops (lines 20 and 310) but the return value in A is never subsequently read, suggesting the call is made purely for its side-effect of running the scroll routine.
Content
Source Code
1 REM \2A\0C\40\11\72\02\19\E5\06\21\23\10\FD\E5\D1\E1\0E\13\06\21\7E\12\1B\2B\10\FA\0D\20\F5\C9\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32
2 LET S=0
3 LET T=16514
4 LET V=411
5 LET W=PEEK 16396+256*PEEK 16397
6 CLS
7 PRINT AT 20,9;"**%R%U%N%W%A%Y**"
10 PRINT AT 1,10;"\'' \. \''"
20 LET A=USR (T)
21 LET R=INT (S/10)
22 IF S-R*10=9 OR S-R*10=6 OR S-R*10=4 THEN POKE W+V-33*INT (V/33)+99,52
30 LET V=V+(INKEY$="M")-(INKEY$="Z")
35 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100
40 POKE W+V,23
41 IF S=100 THEN LET V=V-66
42 IF S=150 THEN LET V=V-33
43 IF S=200 THEN LET V=V-99
44 IF S=250 THEN GOTO 250
45 LET S=S+1
50 GOTO 10
100 POKE W+V,61
110 PRINT AT 21,0;"%T%O%O% %B%A%D% %Y%O%U%R% %D%E%A%D REPLAY Y/N ?"
120 INPUT Y$
130 IF Y$="Y" THEN RUN
140 GOTO 120
250 PRINT AT 1,10;" "
260 LET V=V+(INKEY$="8")-(INKEY$="5")
270 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100
280 POKE W+V,23
290 LET S=S+1
300 IF S=270 THEN GOTO 400
310 LET A=USR (T)
320 GOTO 250
400 PRINT AT 21,0;"%W%E%L%L% %D%O%N%E REPLAY Y/N ?"
410 INPUT X$
420 IF X$="Y" THEN RUN
430 GOTO 410
440 CLEAR
450 SAVE "1025%5"
460 RUN
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
Runway
This file is part of and Timex Sinclair Public Domain Library Tape 1006. Download the collection to get this file.
This is a two-phase runway landing game where the player guides an aircraft symbol along the ZX81 display file using keyboard controls. The program embeds a machine-code routine in the REM statement at line 1 that performs a fast block-copy of display data, called repeatedly via USR to scroll the runway. The game uses direct PEEK and POKE operations on the display file (base address from system variables at 16396–16397) to detect collisions with obstacles (character codes 3 and 52) and to place the plane sprite (character code 23). Obstacles are injected at calculated positions using modular arithmetic tied to the score variable S, and the game transitions from a horizontal taxiing phase (Z/M keys) to a vertical landing phase (5/8 keys) at score 250.
Program Analysis
Program Structure
The program divides into four logical sections:
- Initialisation (lines 1–6): Machine code stored in the REM, variables set up, display file base address computed.
- Phase 1 – Taxiing (lines 10–50): Player moves horizontally along the runway using Z/M keys; obstacles are periodically placed; score increments each loop.
- Phase 2 – Landing (lines 250–320): Triggered at
S=250; control switches to 5/8 keys for vertical movement; score continues to increment.
- End states (lines 100–140, 400–430): Collision leads to a “TOO BAD YOU’RE DEAD” prompt; reaching
S=270 leads to a “WELL DONE” prompt. Both offer Y/N replay via RUN.
Machine Code in the REM (Line 1)
The REM statement at line 1 contains a hand-assembled Z80 routine. Called from BASIC via USR (T) where T=16514 (two bytes past the REM token at the start of the BASIC area), it acts as a scrolling engine that copies display-file rows to produce the runway movement effect. The trailing \32 bytes (ASCII spaces) pad the REM to provide a clean source buffer for the copy loop. The routine ends with C9 (RET), returning control cleanly to BASIC, and its return value is captured in A (though unused).
Decoded Z80 bytes of interest:
\2A\0C\40 – LD HL,(4012H): loads display file address
\11\72\02 – LD DE,0272H: sets destination offset (one row down)
\E5 / \D1 / \E1 – stack-based register juggling for block copy
\10\FD – DJNZ inner loop; \0D\20\F5 – DEC C; JR NZ outer loop
C9 – RET
Display File Addressing
W (line 5) is computed as PEEK 16396 + 256*PEEK 16397, the standard ZX81 method for reading the system variable D_FILE (address 16396). All subsequent character placement and collision detection is performed by adding offset V to W. The modular expression W+V-33*INT(V/33) at line 22 converts the flat offset into a column position within a 33-byte-wide display row (32 characters + newline), used to inject obstacles at the correct screen column.
Key BASIC Idioms
- Boolean arithmetic for movement:
V=V+(INKEY$="M")-(INKEY$="Z") (line 30) and V=V+(INKEY$="8")-(INKEY$="5") (line 260) exploit the ZX81’s 0/1 boolean results to update the plane position in a single expression without IF statements.
- Collision detection by character code:
PEEK(W+V)=3 tests for the newline character (column boundary / wall) and =52 tests for the obstacle character, implementing boundary and hazard detection purely through display memory reads.
- Score-driven level progression: Milestones at
S=100, 150, 200 (lines 41–43) subtract multiples of 33 from V to jump the plane up one or more display rows, simulating approach descent; S=250 triggers phase 2.
Obstacle Generation
Line 22 checks whether the units digit of S (computed as S-R*10 where R=INT(S/10)) equals 9, 6, or 4, and if so POKEs character 52 at a display position derived from V modulo 33 offset by 99 (three rows ahead). This creates a deterministic but varied obstacle pattern timed to the score counter rather than real time.
Plane and Obstacle Characters
Code Character Role 23Inverse-video block graphic Player plane sprite 52Block graphic / obstacle Runway hazard 3Newline (display file) Edge/wall boundary 61Explosion/crash glyph Crash marker (line 100)
Notable Anomalies
- Lines 440–460 (
CLEAR, SAVE "1025%5", RUN) appear after all reachable game logic and are never executed during normal play; they are likely a loader/auto-save remnant left over from development.
- The replay prompt loop (lines 120–140 and 410–430) uses
INPUT Y$/INPUT X$, which on the ZX81 requires the user to press ENTER after the key, making single-keypress replay impossible without modification.
LET A=USR(T) is called in both phase loops (lines 20 and 310) but the return value in A is never subsequently read, suggesting the call is made purely for its side-effect of running the scroll routine.
Content
Source Code
1 REM \2A\0C\40\11\72\02\19\E5\06\21\23\10\FD\E5\D1\E1\0E\13\06\21\7E\12\1B\2B\10\FA\0D\20\F5\C9\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32
2 LET S=0
3 LET T=16514
4 LET V=411
5 LET W=PEEK 16396+256*PEEK 16397
6 CLS
7 PRINT AT 20,9;"**%R%U%N%W%A%Y**"
10 PRINT AT 1,10;"\'' \. \''"
20 LET A=USR (T)
21 LET R=INT (S/10)
22 IF S-R*10=9 OR S-R*10=6 OR S-R*10=4 THEN POKE W+V-33*INT (V/33)+99,52
30 LET V=V+(INKEY$="M")-(INKEY$="Z")
35 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100
40 POKE W+V,23
41 IF S=100 THEN LET V=V-66
42 IF S=150 THEN LET V=V-33
43 IF S=200 THEN LET V=V-99
44 IF S=250 THEN GOTO 250
45 LET S=S+1
50 GOTO 10
100 POKE W+V,61
110 PRINT AT 21,0;"%T%O%O% %B%A%D% %Y%O%U%R% %D%E%A%D REPLAY Y/N ?"
120 INPUT Y$
130 IF Y$="Y" THEN RUN
140 GOTO 120
250 PRINT AT 1,10;" "
260 LET V=V+(INKEY$="8")-(INKEY$="5")
270 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100
280 POKE W+V,23
290 LET S=S+1
300 IF S=270 THEN GOTO 400
310 LET A=USR (T)
320 GOTO 250
400 PRINT AT 21,0;"%W%E%L%L% %D%O%N%E REPLAY Y/N ?"
410 INPUT X$
420 IF X$="Y" THEN RUN
430 GOTO 410
440 CLEAR
450 SAVE "1025%5"
460 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\E5\FD\E5\D1\E1
Skip to content
Runway
This file is part of and Timex Sinclair Public Domain Library Tape 1006. Download the collection to get this file.
This is a two-phase runway landing game where the player guides an aircraft symbol along the ZX81 display file using keyboard controls. The program embeds a machine-code routine in the REM statement at line 1 that performs a fast block-copy of display data, called repeatedly via USR to scroll the runway. The game uses direct PEEK and POKE operations on the display file (base address from system variables at 16396–16397) to detect collisions with obstacles (character codes 3 and 52) and to place the plane sprite (character code 23). Obstacles are injected at calculated positions using modular arithmetic tied to the score variable S, and the game transitions from a horizontal taxiing phase (Z/M keys) to a vertical landing phase (5/8 keys) at score 250.
Program Analysis
Program Structure
The program divides into four logical sections:
- Initialisation (lines 1–6): Machine code stored in the REM, variables set up, display file base address computed.
- Phase 1 – Taxiing (lines 10–50): Player moves horizontally along the runway using Z/M keys; obstacles are periodically placed; score increments each loop.
- Phase 2 – Landing (lines 250–320): Triggered at
S=250; control switches to 5/8 keys for vertical movement; score continues to increment.
- End states (lines 100–140, 400–430): Collision leads to a “TOO BAD YOU’RE DEAD” prompt; reaching
S=270 leads to a “WELL DONE” prompt. Both offer Y/N replay via RUN.
Machine Code in the REM (Line 1)
The REM statement at line 1 contains a hand-assembled Z80 routine. Called from BASIC via USR (T) where T=16514 (two bytes past the REM token at the start of the BASIC area), it acts as a scrolling engine that copies display-file rows to produce the runway movement effect. The trailing \32 bytes (ASCII spaces) pad the REM to provide a clean source buffer for the copy loop. The routine ends with C9 (RET), returning control cleanly to BASIC, and its return value is captured in A (though unused).
Decoded Z80 bytes of interest:
\2A\0C\40 – LD HL,(4012H): loads display file address
\11\72\02 – LD DE,0272H: sets destination offset (one row down)
\E5 / \D1 / \E1 – stack-based register juggling for block copy
\10\FD – DJNZ inner loop; \0D\20\F5 – DEC C; JR NZ outer loop
C9 – RET
Display File Addressing
W (line 5) is computed as PEEK 16396 + 256*PEEK 16397, the standard ZX81 method for reading the system variable D_FILE (address 16396). All subsequent character placement and collision detection is performed by adding offset V to W. The modular expression W+V-33*INT(V/33) at line 22 converts the flat offset into a column position within a 33-byte-wide display row (32 characters + newline), used to inject obstacles at the correct screen column.
Key BASIC Idioms
- Boolean arithmetic for movement:
V=V+(INKEY$="M")-(INKEY$="Z") (line 30) and V=V+(INKEY$="8")-(INKEY$="5") (line 260) exploit the ZX81’s 0/1 boolean results to update the plane position in a single expression without IF statements.
- Collision detection by character code:
PEEK(W+V)=3 tests for the newline character (column boundary / wall) and =52 tests for the obstacle character, implementing boundary and hazard detection purely through display memory reads.
- Score-driven level progression: Milestones at
S=100, 150, 200 (lines 41–43) subtract multiples of 33 from V to jump the plane up one or more display rows, simulating approach descent; S=250 triggers phase 2.
Obstacle Generation
Line 22 checks whether the units digit of S (computed as S-R*10 where R=INT(S/10)) equals 9, 6, or 4, and if so POKEs character 52 at a display position derived from V modulo 33 offset by 99 (three rows ahead). This creates a deterministic but varied obstacle pattern timed to the score counter rather than real time.
Plane and Obstacle Characters
Code Character Role 23Inverse-video block graphic Player plane sprite 52Block graphic / obstacle Runway hazard 3Newline (display file) Edge/wall boundary 61Explosion/crash glyph Crash marker (line 100)
Notable Anomalies
- Lines 440–460 (
CLEAR, SAVE "1025%5", RUN) appear after all reachable game logic and are never executed during normal play; they are likely a loader/auto-save remnant left over from development.
- The replay prompt loop (lines 120–140 and 410–430) uses
INPUT Y$/INPUT X$, which on the ZX81 requires the user to press ENTER after the key, making single-keypress replay impossible without modification.
LET A=USR(T) is called in both phase loops (lines 20 and 310) but the return value in A is never subsequently read, suggesting the call is made purely for its side-effect of running the scroll routine.
Content
Source Code
1 REM \2A\0C\40\11\72\02\19\E5\06\21\23\10\FD\E5\D1\E1\0E\13\06\21\7E\12\1B\2B\10\FA\0D\20\F5\C9\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32
2 LET S=0
3 LET T=16514
4 LET V=411
5 LET W=PEEK 16396+256*PEEK 16397
6 CLS
7 PRINT AT 20,9;"**%R%U%N%W%A%Y**"
10 PRINT AT 1,10;"\'' \. \''"
20 LET A=USR (T)
21 LET R=INT (S/10)
22 IF S-R*10=9 OR S-R*10=6 OR S-R*10=4 THEN POKE W+V-33*INT (V/33)+99,52
30 LET V=V+(INKEY$="M")-(INKEY$="Z")
35 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100
40 POKE W+V,23
41 IF S=100 THEN LET V=V-66
42 IF S=150 THEN LET V=V-33
43 IF S=200 THEN LET V=V-99
44 IF S=250 THEN GOTO 250
45 LET S=S+1
50 GOTO 10
100 POKE W+V,61
110 PRINT AT 21,0;"%T%O%O% %B%A%D% %Y%O%U%R% %D%E%A%D REPLAY Y/N ?"
120 INPUT Y$
130 IF Y$="Y" THEN RUN
140 GOTO 120
250 PRINT AT 1,10;" "
260 LET V=V+(INKEY$="8")-(INKEY$="5")
270 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100
280 POKE W+V,23
290 LET S=S+1
300 IF S=270 THEN GOTO 400
310 LET A=USR (T)
320 GOTO 250
400 PRINT AT 21,0;"%W%E%L%L% %D%O%N%E REPLAY Y/N ?"
410 INPUT X$
420 IF X$="Y" THEN RUN
430 GOTO 410
440 CLEAR
450 SAVE "1025%5"
460 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57500 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.6 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.4"B
Skip to content
Runway
This file is part of and Timex Sinclair Public Domain Library Tape 1006. Download the collection to get this file.
This is a two-phase runway landing game where the player guides an aircraft symbol along the ZX81 display file using keyboard controls. The program embeds a machine-code routine in the REM statement at line 1 that performs a fast block-copy of display data, called repeatedly via USR to scroll the runway. The game uses direct PEEK and POKE operations on the display file (base address from system variables at 16396–16397) to detect collisions with obstacles (character codes 3 and 52) and to place the plane sprite (character code 23). Obstacles are injected at calculated positions using modular arithmetic tied to the score variable S, and the game transitions from a horizontal taxiing phase (Z/M keys) to a vertical landing phase (5/8 keys) at score 250.
Program Analysis
Program Structure
The program divides into four logical sections:
- Initialisation (lines 1–6): Machine code stored in the REM, variables set up, display file base address computed.
- Phase 1 – Taxiing (lines 10–50): Player moves horizontally along the runway using Z/M keys; obstacles are periodically placed; score increments each loop.
- Phase 2 – Landing (lines 250–320): Triggered at
S=250; control switches to 5/8 keys for vertical movement; score continues to increment.
- End states (lines 100–140, 400–430): Collision leads to a “TOO BAD YOU’RE DEAD” prompt; reaching
S=270 leads to a “WELL DONE” prompt. Both offer Y/N replay via RUN.
Machine Code in the REM (Line 1)
The REM statement at line 1 contains a hand-assembled Z80 routine. Called from BASIC via USR (T) where T=16514 (two bytes past the REM token at the start of the BASIC area), it acts as a scrolling engine that copies display-file rows to produce the runway movement effect. The trailing \32 bytes (ASCII spaces) pad the REM to provide a clean source buffer for the copy loop. The routine ends with C9 (RET), returning control cleanly to BASIC, and its return value is captured in A (though unused).
Decoded Z80 bytes of interest:
\2A\0C\40 – LD HL,(4012H): loads display file address
\11\72\02 – LD DE,0272H: sets destination offset (one row down)
\E5 / \D1 / \E1 – stack-based register juggling for block copy
\10\FD – DJNZ inner loop; \0D\20\F5 – DEC C; JR NZ outer loop
C9 – RET
Display File Addressing
W (line 5) is computed as PEEK 16396 + 256*PEEK 16397, the standard ZX81 method for reading the system variable D_FILE (address 16396). All subsequent character placement and collision detection is performed by adding offset V to W. The modular expression W+V-33*INT(V/33) at line 22 converts the flat offset into a column position within a 33-byte-wide display row (32 characters + newline), used to inject obstacles at the correct screen column.
Key BASIC Idioms
- Boolean arithmetic for movement:
V=V+(INKEY$="M")-(INKEY$="Z") (line 30) and V=V+(INKEY$="8")-(INKEY$="5") (line 260) exploit the ZX81’s 0/1 boolean results to update the plane position in a single expression without IF statements.
- Collision detection by character code:
PEEK(W+V)=3 tests for the newline character (column boundary / wall) and =52 tests for the obstacle character, implementing boundary and hazard detection purely through display memory reads.
- Score-driven level progression: Milestones at
S=100, 150, 200 (lines 41–43) subtract multiples of 33 from V to jump the plane up one or more display rows, simulating approach descent; S=250 triggers phase 2.
Obstacle Generation
Line 22 checks whether the units digit of S (computed as S-R*10 where R=INT(S/10)) equals 9, 6, or 4, and if so POKEs character 52 at a display position derived from V modulo 33 offset by 99 (three rows ahead). This creates a deterministic but varied obstacle pattern timed to the score counter rather than real time.
Plane and Obstacle Characters
Code Character Role 23Inverse-video block graphic Player plane sprite 52Block graphic / obstacle Runway hazard 3Newline (display file) Edge/wall boundary 61Explosion/crash glyph Crash marker (line 100)
Notable Anomalies
- Lines 440–460 (
CLEAR, SAVE "1025%5", RUN) appear after all reachable game logic and are never executed during normal play; they are likely a loader/auto-save remnant left over from development.
- The replay prompt loop (lines 120–140 and 410–430) uses
INPUT Y$/INPUT X$, which on the ZX81 requires the user to press ENTER after the key, making single-keypress replay impossible without modification.
LET A=USR(T) is called in both phase loops (lines 20 and 310) but the return value in A is never subsequently read, suggesting the call is made purely for its side-effect of running the scroll routine.
Content
Source Code
1 REM \2A\0C\40\11\72\02\19\E5\06\21\23\10\FD\E5\D1\E1\0E\13\06\21\7E\12\1B\2B\10\FA\0D\20\F5\C9\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32
2 LET S=0
3 LET T=16514
4 LET V=411
5 LET W=PEEK 16396+256*PEEK 16397
6 CLS
7 PRINT AT 20,9;"**%R%U%N%W%A%Y**"
10 PRINT AT 1,10;"\'' \. \''"
20 LET A=USR (T)
21 LET R=INT (S/10)
22 IF S-R*10=9 OR S-R*10=6 OR S-R*10=4 THEN POKE W+V-33*INT (V/33)+99,52
30 LET V=V+(INKEY$="M")-(INKEY$="Z")
35 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100
40 POKE W+V,23
41 IF S=100 THEN LET V=V-66
42 IF S=150 THEN LET V=V-33
43 IF S=200 THEN LET V=V-99
44 IF S=250 THEN GOTO 250
45 LET S=S+1
50 GOTO 10
100 POKE W+V,61
110 PRINT AT 21,0;"%T%O%O% %B%A%D% %Y%O%U%R% %D%E%A%D REPLAY Y/N ?"
120 INPUT Y$
130 IF Y$="Y" THEN RUN
140 GOTO 120
250 PRINT AT 1,10;" "
260 LET V=V+(INKEY$="8")-(INKEY$="5")
270 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100
280 POKE W+V,23
290 LET S=S+1
300 IF S=270 THEN GOTO 400
310 LET A=USR (T)
320 GOTO 250
400 PRINT AT 21,0;"%W%E%L%L% %D%O%N%E REPLAY Y/N ?"
410 INPUT X$
420 IF X$="Y" THEN RUN
430 GOTO 410
440 CLEAR
450 SAVE "1025%5"
460 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\FA
Skip to content
Runway
This file is part of and Timex Sinclair Public Domain Library Tape 1006. Download the collection to get this file.
This is a two-phase runway landing game where the player guides an aircraft symbol along the ZX81 display file using keyboard controls. The program embeds a machine-code routine in the REM statement at line 1 that performs a fast block-copy of display data, called repeatedly via USR to scroll the runway. The game uses direct PEEK and POKE operations on the display file (base address from system variables at 16396–16397) to detect collisions with obstacles (character codes 3 and 52) and to place the plane sprite (character code 23). Obstacles are injected at calculated positions using modular arithmetic tied to the score variable S, and the game transitions from a horizontal taxiing phase (Z/M keys) to a vertical landing phase (5/8 keys) at score 250.
Program Analysis
Program Structure
The program divides into four logical sections:
- Initialisation (lines 1–6): Machine code stored in the REM, variables set up, display file base address computed.
- Phase 1 – Taxiing (lines 10–50): Player moves horizontally along the runway using Z/M keys; obstacles are periodically placed; score increments each loop.
- Phase 2 – Landing (lines 250–320): Triggered at
S=250; control switches to 5/8 keys for vertical movement; score continues to increment.
- End states (lines 100–140, 400–430): Collision leads to a “TOO BAD YOU’RE DEAD” prompt; reaching
S=270 leads to a “WELL DONE” prompt. Both offer Y/N replay via RUN.
Machine Code in the REM (Line 1)
The REM statement at line 1 contains a hand-assembled Z80 routine. Called from BASIC via USR (T) where T=16514 (two bytes past the REM token at the start of the BASIC area), it acts as a scrolling engine that copies display-file rows to produce the runway movement effect. The trailing \32 bytes (ASCII spaces) pad the REM to provide a clean source buffer for the copy loop. The routine ends with C9 (RET), returning control cleanly to BASIC, and its return value is captured in A (though unused).
Decoded Z80 bytes of interest:
\2A\0C\40 – LD HL,(4012H): loads display file address
\11\72\02 – LD DE,0272H: sets destination offset (one row down)
\E5 / \D1 / \E1 – stack-based register juggling for block copy
\10\FD – DJNZ inner loop; \0D\20\F5 – DEC C; JR NZ outer loop
C9 – RET
Display File Addressing
W (line 5) is computed as PEEK 16396 + 256*PEEK 16397, the standard ZX81 method for reading the system variable D_FILE (address 16396). All subsequent character placement and collision detection is performed by adding offset V to W. The modular expression W+V-33*INT(V/33) at line 22 converts the flat offset into a column position within a 33-byte-wide display row (32 characters + newline), used to inject obstacles at the correct screen column.
Key BASIC Idioms
- Boolean arithmetic for movement:
V=V+(INKEY$="M")-(INKEY$="Z") (line 30) and V=V+(INKEY$="8")-(INKEY$="5") (line 260) exploit the ZX81’s 0/1 boolean results to update the plane position in a single expression without IF statements.
- Collision detection by character code:
PEEK(W+V)=3 tests for the newline character (column boundary / wall) and =52 tests for the obstacle character, implementing boundary and hazard detection purely through display memory reads.
- Score-driven level progression: Milestones at
S=100, 150, 200 (lines 41–43) subtract multiples of 33 from V to jump the plane up one or more display rows, simulating approach descent; S=250 triggers phase 2.
Obstacle Generation
Line 22 checks whether the units digit of S (computed as S-R*10 where R=INT(S/10)) equals 9, 6, or 4, and if so POKEs character 52 at a display position derived from V modulo 33 offset by 99 (three rows ahead). This creates a deterministic but varied obstacle pattern timed to the score counter rather than real time.
Plane and Obstacle Characters
Code Character Role 23Inverse-video block graphic Player plane sprite 52Block graphic / obstacle Runway hazard 3Newline (display file) Edge/wall boundary 61Explosion/crash glyph Crash marker (line 100)
Notable Anomalies
- Lines 440–460 (
CLEAR, SAVE "1025%5", RUN) appear after all reachable game logic and are never executed during normal play; they are likely a loader/auto-save remnant left over from development.
- The replay prompt loop (lines 120–140 and 410–430) uses
INPUT Y$/INPUT X$, which on the ZX81 requires the user to press ENTER after the key, making single-keypress replay impossible without modification.
LET A=USR(T) is called in both phase loops (lines 20 and 310) but the return value in A is never subsequently read, suggesting the call is made purely for its side-effect of running the scroll routine.
Content
Source Code
1 REM \2A\0C\40\11\72\02\19\E5\06\21\23\10\FD\E5\D1\E1\0E\13\06\21\7E\12\1B\2B\10\FA\0D\20\F5\C9\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32
2 LET S=0
3 LET T=16514
4 LET V=411
5 LET W=PEEK 16396+256*PEEK 16397
6 CLS
7 PRINT AT 20,9;"**%R%U%N%W%A%Y**"
10 PRINT AT 1,10;"\'' \. \''"
20 LET A=USR (T)
21 LET R=INT (S/10)
22 IF S-R*10=9 OR S-R*10=6 OR S-R*10=4 THEN POKE W+V-33*INT (V/33)+99,52
30 LET V=V+(INKEY$="M")-(INKEY$="Z")
35 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100
40 POKE W+V,23
41 IF S=100 THEN LET V=V-66
42 IF S=150 THEN LET V=V-33
43 IF S=200 THEN LET V=V-99
44 IF S=250 THEN GOTO 250
45 LET S=S+1
50 GOTO 10
100 POKE W+V,61
110 PRINT AT 21,0;"%T%O%O% %B%A%D% %Y%O%U%R% %D%E%A%D REPLAY Y/N ?"
120 INPUT Y$
130 IF Y$="Y" THEN RUN
140 GOTO 120
250 PRINT AT 1,10;" "
260 LET V=V+(INKEY$="8")-(INKEY$="5")
270 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100
280 POKE W+V,23
290 LET S=S+1
300 IF S=270 THEN GOTO 400
310 LET A=USR (T)
320 GOTO 250
400 PRINT AT 21,0;"%W%E%L%L% %D%O%N%E REPLAY Y/N ?"
410 INPUT X$
420 IF X$="Y" THEN RUN
430 GOTO 410
440 CLEAR
450 SAVE "1025%5"
460 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\F5\C9
2 LET S=0
3 LET T=16514
4 LET V=411
5 LET W=PEEK 16396+256*PEEK 16397
6 CLS
7 PRINT AT 20,9;"**%R%U%N%W%A%Y**"
10 PRINT AT 1,10;"\'' \. \''"
20 LET A=USR (T)
21 LET R=INT (S/10)
22 IF S-R*10=9 OR S-R*10=6 OR S-R*10=4 THEN POKE W+V-33*INT (V/33)+99,52
30 LET V=V+(INKEY$="M")-(INKEY$="Z")
35 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100
40 POKE W+V,23
41 IF S=100 THEN LET V=V-66
42 IF S=150 THEN LET V=V-33
43 IF S=200 THEN LET V=V-99
44 IF S=250 THEN GOTO 250
45 LET S=S+1
50 GOTO 10
100 POKE W+V,61
110 PRINT AT 21,0;"%T%O%O% %B%A%D% %Y%O%U%R% %D%E%A%D REPLAY Y/N ?"
120 INPUT Y$
130 IF Y$="Y" THEN RUN
140 GOTO 120
250 PRINT AT 1,10;" "
260 LET V=V+(INKEY$="8")-(INKEY$="5")
270 IF PEEK (W+V)=3 OR PEEK (W+V)=52 THEN GOTO 100
280 POKE W+V,23
290 LET S=S+1
300 IF S=270 THEN GOTO 400
310 LET A=USR (T)
320 GOTO 250
400 PRINT AT 21,0;"%W%E%L%L% %D%O%N%E REPLAY Y/N ?"
410 INPUT X$
420 IF X$="Y" THEN RUN
430 GOTO 410
440 CLEAR
450 SAVE "1025%5"
460 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
