This program implements a scrolling maze/labyrinth game where the player navigates a character horizontally along a corridor filled with obstacles. Line 1 contains a REM statement housing machine code: a LDIR-based routine that shifts screen memory, providing smooth vertical scrolling of the playfield. The player position is tracked via a direct PEEK of screen memory at address A, with INKEY$ “0” and “1” used for left/right movement. Obstacles (block graphic characters) are randomly distributed across each new row generated by the GOSUB 200 subroutine, and the score increments each cycle until a collision is detected.
Program Structure
The program is organized into a main loop and three subroutines:
- Initialization (lines 10–20): Calculates the player’s screen address, inputs difficulty
C, draws the initial screen, and sets the score counterBto-18(offsetting the pre-fill rows). - Main loop (lines 50–130): Generates a new row string, prints it, calls the machine code scroller, checks for collision, updates player position, then repeats from line 30 (note: line 30 does not exist — this is a bug; see below).
- Row generator subroutine (lines 200–240): Copies the template string
B$intoA$, then randomly placesCwall characters andCspace characters within it. - Screen fill subroutine (lines 300–340): Fills all 22 rows with the border/corridor template
B$at startup. - Game over handler (lines 1000–1030): Clears screen, prints final score, pauses, then restarts.
Machine Code Usage
Line 1 is a REM statement containing 18 bytes of Z80 machine code. The routine is called via RAND USR 16514 at line 75 (16514 = address of the first byte after the REM token). Disassembled:
| Bytes | Mnemonic | Notes |
|---|---|---|
01 D6 02 | LD BC, $02D6 | Byte count = 726 (22 rows × 33 bytes) |
2A 0C 40 | LD HL, ($400C) | Load display file start address |
09 | ADD HL, BC | HL → one row down from top |
54 | LD D, H | |
5D | LD E, L | DE = source (one row down) |
01 B5 02 | LD BC, $02B5 | Byte count = 693 (21 rows × 33) |
2A 0C 40 | LD HL, ($400C) | HL = destination (top of screen) |
09 | ADD HL, BC | (unused intermediate — likely HL points to end of copy region) |
ED B8 | LDDR | Block copy downward (scroll up) |
C9 | RET |
This LDDR-based scroll moves the entire display buffer up by one text row each game cycle, giving smooth vertical scrolling without redrawing the whole screen from BASIC.
Key BASIC Idioms
LET A=645+PEEK 16396+256*PEEK 16397— computes a screen address relative to the display file base (system variable at 16396/16397), placing the player 645 bytes (about 19 rows × 33 + offset) into the display.LET A=A+(INKEY$="0")-(INKEY$="1")— classic Sinclair idiom using Boolean arithmetic (+1 or -1) to update position in a single expression.LET A$(1+F)="%."andLET A$(1+F)="% "— two-character string slice assignment used to place block graphic pairs (wall/space) into the row template.- Score is initialized to
-18so that it reads 0 only after the 18 pre-scrolled setup rows have passed.
Display Template
The string B$ (line 16) is 33 characters wide. It consists of border characters (\: = ▌ and \ : = ▐ style blocks) at each end, with 28 interior positions filled with \@@ (inverse spaces / solid blocks), forming a solid wall corridor. The row generator (lines 200–240) punches C gaps and C walls randomly into this template to create the navigable maze rows.
Collision Detection
Collision is detected at line 80 by PEEK A: the player’s current screen cell is read directly from display memory. Character code 136 represents an inverse space (solid block — a wall). If the cell is not 136, the game-over subroutine at line 1000 is called. Line 90 then writes 151 (the player character) to that address, and lines 100–104 write wall characters to the three adjacent cells (offsets +32, +33, +34 — i.e., the row below), effectively drawing the player sprite and the approaching wall simultaneously.
Bugs and Anomalies
- LDDR direction: LDDR copies from high to low address. The setup places HL at (base + 693) and DE at (base + 726), but both source and destination adjustments in the machine code warrant careful scrutiny — the exact scroll direction and pixel-row vs. character-row granularity depends on whether the display file is linear (as on the TS2068 in certain modes).
- Score display condition: Line 72 only prints the score when
B>0, consistent with the-18initialization, so the score appears clean from zero.
Content
Source Code
1 REM itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57651 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"\D6
Skip to content
Labyrinth 2
This file is part of and Synchro-Sette September 1983. Download the collection to get this file.
This program implements a scrolling maze/labyrinth game where the player navigates a character horizontally along a corridor filled with obstacles. Line 1 contains a REM statement housing machine code: a LDIR-based routine that shifts screen memory, providing smooth vertical scrolling of the playfield. The player position is tracked via a direct PEEK of screen memory at address A, with INKEY$ “0” and “1” used for left/right movement. Obstacles (block graphic characters) are randomly distributed across each new row generated by the GOSUB 200 subroutine, and the score increments each cycle until a collision is detected.
Program Structure
The program is organized into a main loop and three subroutines:
- Initialization (lines 10–20): Calculates the player’s screen address, inputs difficulty
C, draws the initial screen, and sets the score counter B to -18 (offsetting the pre-fill rows).
- Main loop (lines 50–130): Generates a new row string, prints it, calls the machine code scroller, checks for collision, updates player position, then repeats from line 30 (note: line 30 does not exist — this is a bug; see below).
- Row generator subroutine (lines 200–240): Copies the template string
B$ into A$, then randomly places C wall characters and C space characters within it.
- Screen fill subroutine (lines 300–340): Fills all 22 rows with the border/corridor template
B$ at startup.
- Game over handler (lines 1000–1030): Clears screen, prints final score, pauses, then restarts.
Machine Code Usage
Line 1 is a REM statement containing 18 bytes of Z80 machine code. The routine is called via RAND USR 16514 at line 75 (16514 = address of the first byte after the REM token). Disassembled:
Bytes Mnemonic Notes 01 D6 02LD BC, $02D6 Byte count = 726 (22 rows × 33 bytes) 2A 0C 40LD HL, ($400C) Load display file start address 09ADD HL, BC HL → one row down from top 54LD D, H 5DLD E, L DE = source (one row down) 01 B5 02LD BC, $02B5 Byte count = 693 (21 rows × 33) 2A 0C 40LD HL, ($400C) HL = destination (top of screen) 09ADD HL, BC (unused intermediate — likely HL points to end of copy region) ED B8LDDR Block copy downward (scroll up) C9RET
This LDDR-based scroll moves the entire display buffer up by one text row each game cycle, giving smooth vertical scrolling without redrawing the whole screen from BASIC.
Key BASIC Idioms
LET A=645+PEEK 16396+256*PEEK 16397 — computes a screen address relative to the display file base (system variable at 16396/16397), placing the player 645 bytes (about 19 rows × 33 + offset) into the display.
LET A=A+(INKEY$="0")-(INKEY$="1") — classic Sinclair idiom using Boolean arithmetic (+1 or -1) to update position in a single expression.
LET A$(1+F)="%." and LET A$(1+F)="% " — two-character string slice assignment used to place block graphic pairs (wall/space) into the row template.
- Score is initialized to
-18 so that it reads 0 only after the 18 pre-scrolled setup rows have passed.
Display Template
The string B$ (line 16) is 33 characters wide. It consists of border characters (\: = ▌ and \ : = ▐ style blocks) at each end, with 28 interior positions filled with \@@ (inverse spaces / solid blocks), forming a solid wall corridor. The row generator (lines 200–240) punches C gaps and C walls randomly into this template to create the navigable maze rows.
Collision Detection
Collision is detected at line 80 by PEEK A: the player’s current screen cell is read directly from display memory. Character code 136 represents an inverse space (solid block — a wall). If the cell is not 136, the game-over subroutine at line 1000 is called. Line 90 then writes 151 (the player character) to that address, and lines 100–104 write wall characters to the three adjacent cells (offsets +32, +33, +34 — i.e., the row below), effectively drawing the player sprite and the approaching wall simultaneously.
Bugs and Anomalies
- LDDR direction: LDDR copies from high to low address. The setup places HL at (base + 693) and DE at (base + 726), but both source and destination adjustments in the machine code warrant careful scrutiny — the exact scroll direction and pixel-row vs. character-row granularity depends on whether the display file is linear (as on the TS2068 in certain modes).
- Score display condition: Line 72 only prints the score when
B>0, consistent with the -18 initialization, so the score appears clean from zero.
Content
Source Code
1 REM \01\D6\02\2A\0C\40\09\54\5D\01\B5\02\2A\0C\40\09\ED\B8\C9
10 LET A=645+PEEK 16396+256*PEEK 16397
15 INPUT C
16 LET B$="% \: \@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\ :% "
17 GOSUB 300
20 LET B=-18
50 GOSUB 200
70 PRINT AT 0,0;A$
72 IF B>0 THEN PRINT AT 18,30;B;AT 19,30;"\ :% "
75 RAND USR 16514
80 IF PEEK A<>136 THEN GOSUB 1000
90 POKE A,151
100 POKE A+33,136
102 POKE A+32,136
104 POKE A+34,136
110 LET B=B+1
120 LET A=A+(INKEY$="0")-(INKEY$="1")
130 GOTO 30
200 LET A$=B$
205 FOR N=1 TO C
206 LET F=INT (RND*28)+2
210 LET A$(1+F)="%."
215 LET F=INT (RND*28)+2
220 LET A$(1+F)="% "
230 NEXT N
240 RETURN
300 FOR N=0 TO 21
310 PRINT AT N,0;B$
330 NEXT N
340 RETURN
1000 CLS
1010 PRINT AT 10,4;"GAME OVER - FINAL SCORE = ";B
1020 PAUSE 1000
1030 RUN
9998 SAVE "LABYRINTH-%2"
9999 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
Skip to content
Labyrinth 2
This file is part of and Synchro-Sette September 1983. Download the collection to get this file.
This program implements a scrolling maze/labyrinth game where the player navigates a character horizontally along a corridor filled with obstacles. Line 1 contains a REM statement housing machine code: a LDIR-based routine that shifts screen memory, providing smooth vertical scrolling of the playfield. The player position is tracked via a direct PEEK of screen memory at address A, with INKEY$ “0” and “1” used for left/right movement. Obstacles (block graphic characters) are randomly distributed across each new row generated by the GOSUB 200 subroutine, and the score increments each cycle until a collision is detected.
Program Structure
The program is organized into a main loop and three subroutines:
- Initialization (lines 10–20): Calculates the player’s screen address, inputs difficulty
C, draws the initial screen, and sets the score counter B to -18 (offsetting the pre-fill rows).
- Main loop (lines 50–130): Generates a new row string, prints it, calls the machine code scroller, checks for collision, updates player position, then repeats from line 30 (note: line 30 does not exist — this is a bug; see below).
- Row generator subroutine (lines 200–240): Copies the template string
B$ into A$, then randomly places C wall characters and C space characters within it.
- Screen fill subroutine (lines 300–340): Fills all 22 rows with the border/corridor template
B$ at startup.
- Game over handler (lines 1000–1030): Clears screen, prints final score, pauses, then restarts.
Machine Code Usage
Line 1 is a REM statement containing 18 bytes of Z80 machine code. The routine is called via RAND USR 16514 at line 75 (16514 = address of the first byte after the REM token). Disassembled:
Bytes Mnemonic Notes 01 D6 02LD BC, $02D6 Byte count = 726 (22 rows × 33 bytes) 2A 0C 40LD HL, ($400C) Load display file start address 09ADD HL, BC HL → one row down from top 54LD D, H 5DLD E, L DE = source (one row down) 01 B5 02LD BC, $02B5 Byte count = 693 (21 rows × 33) 2A 0C 40LD HL, ($400C) HL = destination (top of screen) 09ADD HL, BC (unused intermediate — likely HL points to end of copy region) ED B8LDDR Block copy downward (scroll up) C9RET
This LDDR-based scroll moves the entire display buffer up by one text row each game cycle, giving smooth vertical scrolling without redrawing the whole screen from BASIC.
Key BASIC Idioms
LET A=645+PEEK 16396+256*PEEK 16397 — computes a screen address relative to the display file base (system variable at 16396/16397), placing the player 645 bytes (about 19 rows × 33 + offset) into the display.
LET A=A+(INKEY$="0")-(INKEY$="1") — classic Sinclair idiom using Boolean arithmetic (+1 or -1) to update position in a single expression.
LET A$(1+F)="%." and LET A$(1+F)="% " — two-character string slice assignment used to place block graphic pairs (wall/space) into the row template.
- Score is initialized to
-18 so that it reads 0 only after the 18 pre-scrolled setup rows have passed.
Display Template
The string B$ (line 16) is 33 characters wide. It consists of border characters (\: = ▌ and \ : = ▐ style blocks) at each end, with 28 interior positions filled with \@@ (inverse spaces / solid blocks), forming a solid wall corridor. The row generator (lines 200–240) punches C gaps and C walls randomly into this template to create the navigable maze rows.
Collision Detection
Collision is detected at line 80 by PEEK A: the player’s current screen cell is read directly from display memory. Character code 136 represents an inverse space (solid block — a wall). If the cell is not 136, the game-over subroutine at line 1000 is called. Line 90 then writes 151 (the player character) to that address, and lines 100–104 write wall characters to the three adjacent cells (offsets +32, +33, +34 — i.e., the row below), effectively drawing the player sprite and the approaching wall simultaneously.
Bugs and Anomalies
- LDDR direction: LDDR copies from high to low address. The setup places HL at (base + 693) and DE at (base + 726), but both source and destination adjustments in the machine code warrant careful scrutiny — the exact scroll direction and pixel-row vs. character-row granularity depends on whether the display file is linear (as on the TS2068 in certain modes).
- Score display condition: Line 72 only prints the score when
B>0, consistent with the -18 initialization, so the score appears clean from zero.
Content
Source Code
1 REM \01\D6\02\2A\0C\40\09\54\5D\01\B5\02\2A\0C\40\09\ED\B8\C9
10 LET A=645+PEEK 16396+256*PEEK 16397
15 INPUT C
16 LET B$="% \: \@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\ :% "
17 GOSUB 300
20 LET B=-18
50 GOSUB 200
70 PRINT AT 0,0;A$
72 IF B>0 THEN PRINT AT 18,30;B;AT 19,30;"\ :% "
75 RAND USR 16514
80 IF PEEK A<>136 THEN GOSUB 1000
90 POKE A,151
100 POKE A+33,136
102 POKE A+32,136
104 POKE A+34,136
110 LET B=B+1
120 LET A=A+(INKEY$="0")-(INKEY$="1")
130 GOTO 30
200 LET A$=B$
205 FOR N=1 TO C
206 LET F=INT (RND*28)+2
210 LET A$(1+F)="%."
215 LET F=INT (RND*28)+2
220 LET A$(1+F)="% "
230 NEXT N
240 RETURN
300 FOR N=0 TO 21
310 PRINT AT N,0;B$
330 NEXT N
340 RETURN
1000 CLS
1010 PRINT AT 10,4;"GAME OVER - FINAL SCORE = ";B
1020 PAUSE 1000
1030 RUN
9998 SAVE "LABYRINTH-%2"
9999 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
A
Skip to content
Labyrinth 2
This file is part of and Synchro-Sette September 1983. Download the collection to get this file.
This program implements a scrolling maze/labyrinth game where the player navigates a character horizontally along a corridor filled with obstacles. Line 1 contains a REM statement housing machine code: a LDIR-based routine that shifts screen memory, providing smooth vertical scrolling of the playfield. The player position is tracked via a direct PEEK of screen memory at address A, with INKEY$ “0” and “1” used for left/right movement. Obstacles (block graphic characters) are randomly distributed across each new row generated by the GOSUB 200 subroutine, and the score increments each cycle until a collision is detected.
Program Structure
The program is organized into a main loop and three subroutines:
- Initialization (lines 10–20): Calculates the player’s screen address, inputs difficulty
C, draws the initial screen, and sets the score counter B to -18 (offsetting the pre-fill rows).
- Main loop (lines 50–130): Generates a new row string, prints it, calls the machine code scroller, checks for collision, updates player position, then repeats from line 30 (note: line 30 does not exist — this is a bug; see below).
- Row generator subroutine (lines 200–240): Copies the template string
B$ into A$, then randomly places C wall characters and C space characters within it.
- Screen fill subroutine (lines 300–340): Fills all 22 rows with the border/corridor template
B$ at startup.
- Game over handler (lines 1000–1030): Clears screen, prints final score, pauses, then restarts.
Machine Code Usage
Line 1 is a REM statement containing 18 bytes of Z80 machine code. The routine is called via RAND USR 16514 at line 75 (16514 = address of the first byte after the REM token). Disassembled:
Bytes Mnemonic Notes 01 D6 02LD BC, $02D6 Byte count = 726 (22 rows × 33 bytes) 2A 0C 40LD HL, ($400C) Load display file start address 09ADD HL, BC HL → one row down from top 54LD D, H 5DLD E, L DE = source (one row down) 01 B5 02LD BC, $02B5 Byte count = 693 (21 rows × 33) 2A 0C 40LD HL, ($400C) HL = destination (top of screen) 09ADD HL, BC (unused intermediate — likely HL points to end of copy region) ED B8LDDR Block copy downward (scroll up) C9RET
This LDDR-based scroll moves the entire display buffer up by one text row each game cycle, giving smooth vertical scrolling without redrawing the whole screen from BASIC.
Key BASIC Idioms
LET A=645+PEEK 16396+256*PEEK 16397 — computes a screen address relative to the display file base (system variable at 16396/16397), placing the player 645 bytes (about 19 rows × 33 + offset) into the display.
LET A=A+(INKEY$="0")-(INKEY$="1") — classic Sinclair idiom using Boolean arithmetic (+1 or -1) to update position in a single expression.
LET A$(1+F)="%." and LET A$(1+F)="% " — two-character string slice assignment used to place block graphic pairs (wall/space) into the row template.
- Score is initialized to
-18 so that it reads 0 only after the 18 pre-scrolled setup rows have passed.
Display Template
The string B$ (line 16) is 33 characters wide. It consists of border characters (\: = ▌ and \ : = ▐ style blocks) at each end, with 28 interior positions filled with \@@ (inverse spaces / solid blocks), forming a solid wall corridor. The row generator (lines 200–240) punches C gaps and C walls randomly into this template to create the navigable maze rows.
Collision Detection
Collision is detected at line 80 by PEEK A: the player’s current screen cell is read directly from display memory. Character code 136 represents an inverse space (solid block — a wall). If the cell is not 136, the game-over subroutine at line 1000 is called. Line 90 then writes 151 (the player character) to that address, and lines 100–104 write wall characters to the three adjacent cells (offsets +32, +33, +34 — i.e., the row below), effectively drawing the player sprite and the approaching wall simultaneously.
Bugs and Anomalies
- LDDR direction: LDDR copies from high to low address. The setup places HL at (base + 693) and DE at (base + 726), but both source and destination adjustments in the machine code warrant careful scrutiny — the exact scroll direction and pixel-row vs. character-row granularity depends on whether the display file is linear (as on the TS2068 in certain modes).
- Score display condition: Line 72 only prints the score when
B>0, consistent with the -18 initialization, so the score appears clean from zero.
Content
Source Code
1 REM \01\D6\02\2A\0C\40\09\54\5D\01\B5\02\2A\0C\40\09\ED\B8\C9
10 LET A=645+PEEK 16396+256*PEEK 16397
15 INPUT C
16 LET B$="% \: \@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\ :% "
17 GOSUB 300
20 LET B=-18
50 GOSUB 200
70 PRINT AT 0,0;A$
72 IF B>0 THEN PRINT AT 18,30;B;AT 19,30;"\ :% "
75 RAND USR 16514
80 IF PEEK A<>136 THEN GOSUB 1000
90 POKE A,151
100 POKE A+33,136
102 POKE A+32,136
104 POKE A+34,136
110 LET B=B+1
120 LET A=A+(INKEY$="0")-(INKEY$="1")
130 GOTO 30
200 LET A$=B$
205 FOR N=1 TO C
206 LET F=INT (RND*28)+2
210 LET A$(1+F)="%."
215 LET F=INT (RND*28)+2
220 LET A$(1+F)="% "
230 NEXT N
240 RETURN
300 FOR N=0 TO 21
310 PRINT AT N,0;B$
330 NEXT N
340 RETURN
1000 CLS
1010 PRINT AT 10,4;"GAME OVER - FINAL SCORE = ";B
1020 PAUSE 1000
1030 RUN
9998 SAVE "LABYRINTH-%2"
9999 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
CD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57651 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"\B5
Skip to content
Labyrinth 2
This file is part of and Synchro-Sette September 1983. Download the collection to get this file.
This program implements a scrolling maze/labyrinth game where the player navigates a character horizontally along a corridor filled with obstacles. Line 1 contains a REM statement housing machine code: a LDIR-based routine that shifts screen memory, providing smooth vertical scrolling of the playfield. The player position is tracked via a direct PEEK of screen memory at address A, with INKEY$ “0” and “1” used for left/right movement. Obstacles (block graphic characters) are randomly distributed across each new row generated by the GOSUB 200 subroutine, and the score increments each cycle until a collision is detected.
Program Structure
The program is organized into a main loop and three subroutines:
- Initialization (lines 10–20): Calculates the player’s screen address, inputs difficulty
C, draws the initial screen, and sets the score counter B to -18 (offsetting the pre-fill rows).
- Main loop (lines 50–130): Generates a new row string, prints it, calls the machine code scroller, checks for collision, updates player position, then repeats from line 30 (note: line 30 does not exist — this is a bug; see below).
- Row generator subroutine (lines 200–240): Copies the template string
B$ into A$, then randomly places C wall characters and C space characters within it.
- Screen fill subroutine (lines 300–340): Fills all 22 rows with the border/corridor template
B$ at startup.
- Game over handler (lines 1000–1030): Clears screen, prints final score, pauses, then restarts.
Machine Code Usage
Line 1 is a REM statement containing 18 bytes of Z80 machine code. The routine is called via RAND USR 16514 at line 75 (16514 = address of the first byte after the REM token). Disassembled:
Bytes Mnemonic Notes 01 D6 02LD BC, $02D6 Byte count = 726 (22 rows × 33 bytes) 2A 0C 40LD HL, ($400C) Load display file start address 09ADD HL, BC HL → one row down from top 54LD D, H 5DLD E, L DE = source (one row down) 01 B5 02LD BC, $02B5 Byte count = 693 (21 rows × 33) 2A 0C 40LD HL, ($400C) HL = destination (top of screen) 09ADD HL, BC (unused intermediate — likely HL points to end of copy region) ED B8LDDR Block copy downward (scroll up) C9RET
This LDDR-based scroll moves the entire display buffer up by one text row each game cycle, giving smooth vertical scrolling without redrawing the whole screen from BASIC.
Key BASIC Idioms
LET A=645+PEEK 16396+256*PEEK 16397 — computes a screen address relative to the display file base (system variable at 16396/16397), placing the player 645 bytes (about 19 rows × 33 + offset) into the display.
LET A=A+(INKEY$="0")-(INKEY$="1") — classic Sinclair idiom using Boolean arithmetic (+1 or -1) to update position in a single expression.
LET A$(1+F)="%." and LET A$(1+F)="% " — two-character string slice assignment used to place block graphic pairs (wall/space) into the row template.
- Score is initialized to
-18 so that it reads 0 only after the 18 pre-scrolled setup rows have passed.
Display Template
The string B$ (line 16) is 33 characters wide. It consists of border characters (\: = ▌ and \ : = ▐ style blocks) at each end, with 28 interior positions filled with \@@ (inverse spaces / solid blocks), forming a solid wall corridor. The row generator (lines 200–240) punches C gaps and C walls randomly into this template to create the navigable maze rows.
Collision Detection
Collision is detected at line 80 by PEEK A: the player’s current screen cell is read directly from display memory. Character code 136 represents an inverse space (solid block — a wall). If the cell is not 136, the game-over subroutine at line 1000 is called. Line 90 then writes 151 (the player character) to that address, and lines 100–104 write wall characters to the three adjacent cells (offsets +32, +33, +34 — i.e., the row below), effectively drawing the player sprite and the approaching wall simultaneously.
Bugs and Anomalies
- LDDR direction: LDDR copies from high to low address. The setup places HL at (base + 693) and DE at (base + 726), but both source and destination adjustments in the machine code warrant careful scrutiny — the exact scroll direction and pixel-row vs. character-row granularity depends on whether the display file is linear (as on the TS2068 in certain modes).
- Score display condition: Line 72 only prints the score when
B>0, consistent with the -18 initialization, so the score appears clean from zero.
Content
Source Code
1 REM \01\D6\02\2A\0C\40\09\54\5D\01\B5\02\2A\0C\40\09\ED\B8\C9
10 LET A=645+PEEK 16396+256*PEEK 16397
15 INPUT C
16 LET B$="% \: \@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\ :% "
17 GOSUB 300
20 LET B=-18
50 GOSUB 200
70 PRINT AT 0,0;A$
72 IF B>0 THEN PRINT AT 18,30;B;AT 19,30;"\ :% "
75 RAND USR 16514
80 IF PEEK A<>136 THEN GOSUB 1000
90 POKE A,151
100 POKE A+33,136
102 POKE A+32,136
104 POKE A+34,136
110 LET B=B+1
120 LET A=A+(INKEY$="0")-(INKEY$="1")
130 GOTO 30
200 LET A$=B$
205 FOR N=1 TO C
206 LET F=INT (RND*28)+2
210 LET A$(1+F)="%."
215 LET F=INT (RND*28)+2
220 LET A$(1+F)="% "
230 NEXT N
240 RETURN
300 FOR N=0 TO 21
310 PRINT AT N,0;B$
330 NEXT N
340 RETURN
1000 CLS
1010 PRINT AT 10,4;"GAME OVER - FINAL SCORE = ";B
1020 PAUSE 1000
1030 RUN
9998 SAVE "LABYRINTH-%2"
9999 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
Skip to content
Labyrinth 2
This file is part of and Synchro-Sette September 1983. Download the collection to get this file.
This program implements a scrolling maze/labyrinth game where the player navigates a character horizontally along a corridor filled with obstacles. Line 1 contains a REM statement housing machine code: a LDIR-based routine that shifts screen memory, providing smooth vertical scrolling of the playfield. The player position is tracked via a direct PEEK of screen memory at address A, with INKEY$ “0” and “1” used for left/right movement. Obstacles (block graphic characters) are randomly distributed across each new row generated by the GOSUB 200 subroutine, and the score increments each cycle until a collision is detected.
Program Structure
The program is organized into a main loop and three subroutines:
- Initialization (lines 10–20): Calculates the player’s screen address, inputs difficulty
C, draws the initial screen, and sets the score counter B to -18 (offsetting the pre-fill rows).
- Main loop (lines 50–130): Generates a new row string, prints it, calls the machine code scroller, checks for collision, updates player position, then repeats from line 30 (note: line 30 does not exist — this is a bug; see below).
- Row generator subroutine (lines 200–240): Copies the template string
B$ into A$, then randomly places C wall characters and C space characters within it.
- Screen fill subroutine (lines 300–340): Fills all 22 rows with the border/corridor template
B$ at startup.
- Game over handler (lines 1000–1030): Clears screen, prints final score, pauses, then restarts.
Machine Code Usage
Line 1 is a REM statement containing 18 bytes of Z80 machine code. The routine is called via RAND USR 16514 at line 75 (16514 = address of the first byte after the REM token). Disassembled:
Bytes Mnemonic Notes 01 D6 02LD BC, $02D6 Byte count = 726 (22 rows × 33 bytes) 2A 0C 40LD HL, ($400C) Load display file start address 09ADD HL, BC HL → one row down from top 54LD D, H 5DLD E, L DE = source (one row down) 01 B5 02LD BC, $02B5 Byte count = 693 (21 rows × 33) 2A 0C 40LD HL, ($400C) HL = destination (top of screen) 09ADD HL, BC (unused intermediate — likely HL points to end of copy region) ED B8LDDR Block copy downward (scroll up) C9RET
This LDDR-based scroll moves the entire display buffer up by one text row each game cycle, giving smooth vertical scrolling without redrawing the whole screen from BASIC.
Key BASIC Idioms
LET A=645+PEEK 16396+256*PEEK 16397 — computes a screen address relative to the display file base (system variable at 16396/16397), placing the player 645 bytes (about 19 rows × 33 + offset) into the display.
LET A=A+(INKEY$="0")-(INKEY$="1") — classic Sinclair idiom using Boolean arithmetic (+1 or -1) to update position in a single expression.
LET A$(1+F)="%." and LET A$(1+F)="% " — two-character string slice assignment used to place block graphic pairs (wall/space) into the row template.
- Score is initialized to
-18 so that it reads 0 only after the 18 pre-scrolled setup rows have passed.
Display Template
The string B$ (line 16) is 33 characters wide. It consists of border characters (\: = ▌ and \ : = ▐ style blocks) at each end, with 28 interior positions filled with \@@ (inverse spaces / solid blocks), forming a solid wall corridor. The row generator (lines 200–240) punches C gaps and C walls randomly into this template to create the navigable maze rows.
Collision Detection
Collision is detected at line 80 by PEEK A: the player’s current screen cell is read directly from display memory. Character code 136 represents an inverse space (solid block — a wall). If the cell is not 136, the game-over subroutine at line 1000 is called. Line 90 then writes 151 (the player character) to that address, and lines 100–104 write wall characters to the three adjacent cells (offsets +32, +33, +34 — i.e., the row below), effectively drawing the player sprite and the approaching wall simultaneously.
Bugs and Anomalies
- LDDR direction: LDDR copies from high to low address. The setup places HL at (base + 693) and DE at (base + 726), but both source and destination adjustments in the machine code warrant careful scrutiny — the exact scroll direction and pixel-row vs. character-row granularity depends on whether the display file is linear (as on the TS2068 in certain modes).
- Score display condition: Line 72 only prints the score when
B>0, consistent with the -18 initialization, so the score appears clean from zero.
Content
Source Code
1 REM \01\D6\02\2A\0C\40\09\54\5D\01\B5\02\2A\0C\40\09\ED\B8\C9
10 LET A=645+PEEK 16396+256*PEEK 16397
15 INPUT C
16 LET B$="% \: \@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\ :% "
17 GOSUB 300
20 LET B=-18
50 GOSUB 200
70 PRINT AT 0,0;A$
72 IF B>0 THEN PRINT AT 18,30;B;AT 19,30;"\ :% "
75 RAND USR 16514
80 IF PEEK A<>136 THEN GOSUB 1000
90 POKE A,151
100 POKE A+33,136
102 POKE A+32,136
104 POKE A+34,136
110 LET B=B+1
120 LET A=A+(INKEY$="0")-(INKEY$="1")
130 GOTO 30
200 LET A$=B$
205 FOR N=1 TO C
206 LET F=INT (RND*28)+2
210 LET A$(1+F)="%."
215 LET F=INT (RND*28)+2
220 LET A$(1+F)="% "
230 NEXT N
240 RETURN
300 FOR N=0 TO 21
310 PRINT AT N,0;B$
330 NEXT N
340 RETURN
1000 CLS
1010 PRINT AT 10,4;"GAME OVER - FINAL SCORE = ";B
1020 PAUSE 1000
1030 RUN
9998 SAVE "LABYRINTH-%2"
9999 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
A
Skip to content
Labyrinth 2
This file is part of and Synchro-Sette September 1983. Download the collection to get this file.
This program implements a scrolling maze/labyrinth game where the player navigates a character horizontally along a corridor filled with obstacles. Line 1 contains a REM statement housing machine code: a LDIR-based routine that shifts screen memory, providing smooth vertical scrolling of the playfield. The player position is tracked via a direct PEEK of screen memory at address A, with INKEY$ “0” and “1” used for left/right movement. Obstacles (block graphic characters) are randomly distributed across each new row generated by the GOSUB 200 subroutine, and the score increments each cycle until a collision is detected.
Program Structure
The program is organized into a main loop and three subroutines:
- Initialization (lines 10–20): Calculates the player’s screen address, inputs difficulty
C, draws the initial screen, and sets the score counter B to -18 (offsetting the pre-fill rows).
- Main loop (lines 50–130): Generates a new row string, prints it, calls the machine code scroller, checks for collision, updates player position, then repeats from line 30 (note: line 30 does not exist — this is a bug; see below).
- Row generator subroutine (lines 200–240): Copies the template string
B$ into A$, then randomly places C wall characters and C space characters within it.
- Screen fill subroutine (lines 300–340): Fills all 22 rows with the border/corridor template
B$ at startup.
- Game over handler (lines 1000–1030): Clears screen, prints final score, pauses, then restarts.
Machine Code Usage
Line 1 is a REM statement containing 18 bytes of Z80 machine code. The routine is called via RAND USR 16514 at line 75 (16514 = address of the first byte after the REM token). Disassembled:
Bytes Mnemonic Notes 01 D6 02LD BC, $02D6 Byte count = 726 (22 rows × 33 bytes) 2A 0C 40LD HL, ($400C) Load display file start address 09ADD HL, BC HL → one row down from top 54LD D, H 5DLD E, L DE = source (one row down) 01 B5 02LD BC, $02B5 Byte count = 693 (21 rows × 33) 2A 0C 40LD HL, ($400C) HL = destination (top of screen) 09ADD HL, BC (unused intermediate — likely HL points to end of copy region) ED B8LDDR Block copy downward (scroll up) C9RET
This LDDR-based scroll moves the entire display buffer up by one text row each game cycle, giving smooth vertical scrolling without redrawing the whole screen from BASIC.
Key BASIC Idioms
LET A=645+PEEK 16396+256*PEEK 16397 — computes a screen address relative to the display file base (system variable at 16396/16397), placing the player 645 bytes (about 19 rows × 33 + offset) into the display.
LET A=A+(INKEY$="0")-(INKEY$="1") — classic Sinclair idiom using Boolean arithmetic (+1 or -1) to update position in a single expression.
LET A$(1+F)="%." and LET A$(1+F)="% " — two-character string slice assignment used to place block graphic pairs (wall/space) into the row template.
- Score is initialized to
-18 so that it reads 0 only after the 18 pre-scrolled setup rows have passed.
Display Template
The string B$ (line 16) is 33 characters wide. It consists of border characters (\: = ▌ and \ : = ▐ style blocks) at each end, with 28 interior positions filled with \@@ (inverse spaces / solid blocks), forming a solid wall corridor. The row generator (lines 200–240) punches C gaps and C walls randomly into this template to create the navigable maze rows.
Collision Detection
Collision is detected at line 80 by PEEK A: the player’s current screen cell is read directly from display memory. Character code 136 represents an inverse space (solid block — a wall). If the cell is not 136, the game-over subroutine at line 1000 is called. Line 90 then writes 151 (the player character) to that address, and lines 100–104 write wall characters to the three adjacent cells (offsets +32, +33, +34 — i.e., the row below), effectively drawing the player sprite and the approaching wall simultaneously.
Bugs and Anomalies
- LDDR direction: LDDR copies from high to low address. The setup places HL at (base + 693) and DE at (base + 726), but both source and destination adjustments in the machine code warrant careful scrutiny — the exact scroll direction and pixel-row vs. character-row granularity depends on whether the display file is linear (as on the TS2068 in certain modes).
- Score display condition: Line 72 only prints the score when
B>0, consistent with the -18 initialization, so the score appears clean from zero.
Content
Source Code
1 REM \01\D6\02\2A\0C\40\09\54\5D\01\B5\02\2A\0C\40\09\ED\B8\C9
10 LET A=645+PEEK 16396+256*PEEK 16397
15 INPUT C
16 LET B$="% \: \@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\ :% "
17 GOSUB 300
20 LET B=-18
50 GOSUB 200
70 PRINT AT 0,0;A$
72 IF B>0 THEN PRINT AT 18,30;B;AT 19,30;"\ :% "
75 RAND USR 16514
80 IF PEEK A<>136 THEN GOSUB 1000
90 POKE A,151
100 POKE A+33,136
102 POKE A+32,136
104 POKE A+34,136
110 LET B=B+1
120 LET A=A+(INKEY$="0")-(INKEY$="1")
130 GOTO 30
200 LET A$=B$
205 FOR N=1 TO C
206 LET F=INT (RND*28)+2
210 LET A$(1+F)="%."
215 LET F=INT (RND*28)+2
220 LET A$(1+F)="% "
230 NEXT N
240 RETURN
300 FOR N=0 TO 21
310 PRINT AT N,0;B$
330 NEXT N
340 RETURN
1000 CLS
1010 PRINT AT 10,4;"GAME OVER - FINAL SCORE = ";B
1020 PAUSE 1000
1030 RUN
9998 SAVE "LABYRINTH-%2"
9999 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
C\ED\B8\C9
10 LET A=645+PEEK 16396+256*PEEK 16397
15 INPUT C
16 LET B$="% \: \@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\ :% "
17 GOSUB 300
20 LET B=-18
50 GOSUB 200
70 PRINT AT 0,0;A$
72 IF B>0 THEN PRINT AT 18,30;B;AT 19,30;"\ :% "
75 RAND USR 16514
80 IF PEEK A<>136 THEN GOSUB 1000
90 POKE A,151
100 POKE A+33,136
102 POKE A+32,136
104 POKE A+34,136
110 LET B=B+1
120 LET A=A+(INKEY$="0")-(INKEY$="1")
130 GOTO 30
200 LET A$=B$
205 FOR N=1 TO C
206 LET F=INT (RND*28)+2
210 LET A$(1+F)="%."
215 LET F=INT (RND*28)+2
220 LET A$(1+F)="% "
230 NEXT N
240 RETURN
300 FOR N=0 TO 21
310 PRINT AT N,0;B$
330 NEXT N
340 RETURN
\n1000 CLS
\n1010 PRINT AT 10,4;"GAME OVER - FINAL SCORE = ";B
\n1020 PAUSE 1000
\n1030 RUN
\n9998 SAVE "LABYRINTH-%2"
\n9999 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
