Labyrinth 2

This file is part of and Synchro-Sette September 1983. Download the collection to get this file.
Developer(s): Gene G. Buza
Date: September 1983
Type: Program
Platform(s): TS 1000
Tags: Game, Software

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:

  1. 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).
  2. 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).
  3. 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.
  4. Screen fill subroutine (lines 300–340): Fills all 22 rows with the border/corridor template B$ at startup.
  5. 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:

BytesMnemonicNotes
01 D6 02LD BC, $02D6Byte count = 726 (22 rows × 33 bytes)
2A 0C 40LD HL, ($400C)Load display file start address
09ADD HL, BCHL → one row down from top
54LD D, H
5DLD E, LDE = source (one row down)
01 B5 02LD BC, $02B5Byte 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 B8LDDRBlock 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

Appears On

Cassette to accompany the September 1983 issue of Synchro-Sette.

Related Products

Related Articles

Related Content

Image Gallery

Labyrinth 2

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



Labyrinth 2

This file is part of and Synchro-Sette September 1983. Download the collection to get this file.
Developer(s): Gene G. Buza
Date: September 1983
Type: Program
Platform(s): TS 1000
Tags: Game, Software

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:

  1. 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).
  2. 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).
  3. 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.
  4. Screen fill subroutine (lines 300–340): Fills all 22 rows with the border/corridor template B$ at startup.
  5. 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:

BytesMnemonicNotes
01 D6 02LD BC, $02D6Byte count = 726 (22 rows × 33 bytes)
2A 0C 40LD HL, ($400C)Load display file start address
09ADD HL, BCHL → one row down from top
54LD D, H
5DLD E, LDE = source (one row down)
01 B5 02LD BC, $02B5Byte 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 B8LDDRBlock 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

Appears On

Cassette to accompany the September 1983 issue of Synchro-Sette.

Related Products

Related Articles

Related Content

Image Gallery

Labyrinth 2

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.

Scroll to Top

Labyrinth 2

This file is part of and Synchro-Sette September 1983. Download the collection to get this file.
Developer(s): Gene G. Buza
Date: September 1983
Type: Program
Platform(s): TS 1000
Tags: Game, Software

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:

  1. 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).
  2. 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).
  3. 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.
  4. Screen fill subroutine (lines 300–340): Fills all 22 rows with the border/corridor template B$ at startup.
  5. 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:

BytesMnemonicNotes
01 D6 02LD BC, $02D6Byte count = 726 (22 rows × 33 bytes)
2A 0C 40LD HL, ($400C)Load display file start address
09ADD HL, BCHL → one row down from top
54LD D, H
5DLD E, LDE = source (one row down)
01 B5 02LD BC, $02B5Byte 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 B8LDDRBlock 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

Appears On

Cassette to accompany the September 1983 issue of Synchro-Sette.

Related Products

Related Articles

Related Content

Image Gallery

Labyrinth 2

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.

Scroll to Top
A

Labyrinth 2

This file is part of and Synchro-Sette September 1983. Download the collection to get this file.
Developer(s): Gene G. Buza
Date: September 1983
Type: Program
Platform(s): TS 1000
Tags: Game, Software

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:

  1. 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).
  2. 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).
  3. 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.
  4. Screen fill subroutine (lines 300–340): Fills all 22 rows with the border/corridor template B$ at startup.
  5. 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:

BytesMnemonicNotes
01 D6 02LD BC, $02D6Byte count = 726 (22 rows × 33 bytes)
2A 0C 40LD HL, ($400C)Load display file start address
09ADD HL, BCHL → one row down from top
54LD D, H
5DLD E, LDE = source (one row down)
01 B5 02LD BC, $02B5Byte 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 B8LDDRBlock 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

Appears On

Cassette to accompany the September 1983 issue of Synchro-Sette.

Related Products

Related Articles

Related Content

Image Gallery

Labyrinth 2

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.

Scroll to Top
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

Labyrinth 2

This file is part of and Synchro-Sette September 1983. Download the collection to get this file.
Developer(s): Gene G. Buza
Date: September 1983
Type: Program
Platform(s): TS 1000
Tags: Game, Software

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:

  1. 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).
  2. 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).
  3. 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.
  4. Screen fill subroutine (lines 300–340): Fills all 22 rows with the border/corridor template B$ at startup.
  5. 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:

BytesMnemonicNotes
01 D6 02LD BC, $02D6Byte count = 726 (22 rows × 33 bytes)
2A 0C 40LD HL, ($400C)Load display file start address
09ADD HL, BCHL → one row down from top
54LD D, H
5DLD E, LDE = source (one row down)
01 B5 02LD BC, $02B5Byte 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 B8LDDRBlock 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

Appears On

Cassette to accompany the September 1983 issue of Synchro-Sette.

Related Products

Related Articles

Related Content

Image Gallery

Labyrinth 2

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.

Scroll to Top

Labyrinth 2

This file is part of and Synchro-Sette September 1983. Download the collection to get this file.
Developer(s): Gene G. Buza
Date: September 1983
Type: Program
Platform(s): TS 1000
Tags: Game, Software

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:

  1. 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).
  2. 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).
  3. 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.
  4. Screen fill subroutine (lines 300–340): Fills all 22 rows with the border/corridor template B$ at startup.
  5. 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:

BytesMnemonicNotes
01 D6 02LD BC, $02D6Byte count = 726 (22 rows × 33 bytes)
2A 0C 40LD HL, ($400C)Load display file start address
09ADD HL, BCHL → one row down from top
54LD D, H
5DLD E, LDE = source (one row down)
01 B5 02LD BC, $02B5Byte 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 B8LDDRBlock 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

Appears On

Cassette to accompany the September 1983 issue of Synchro-Sette.

Related Products

Related Articles

Related Content

Image Gallery

Labyrinth 2

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.

Scroll to Top
A

Labyrinth 2

This file is part of and Synchro-Sette September 1983. Download the collection to get this file.
Developer(s): Gene G. Buza
Date: September 1983
Type: Program
Platform(s): TS 1000
Tags: Game, Software

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:

  1. 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).
  2. 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).
  3. 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.
  4. Screen fill subroutine (lines 300–340): Fills all 22 rows with the border/corridor template B$ at startup.
  5. 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:

BytesMnemonicNotes
01 D6 02LD BC, $02D6Byte count = 726 (22 rows × 33 bytes)
2A 0C 40LD HL, ($400C)Load display file start address
09ADD HL, BCHL → one row down from top
54LD D, H
5DLD E, LDE = source (one row down)
01 B5 02LD BC, $02B5Byte 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 B8LDDRBlock 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

Appears On

Cassette to accompany the September 1983 issue of Synchro-Sette.

Related Products

Related Articles

Related Content

Image Gallery

Labyrinth 2

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.

Scroll to Top
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.

Scroll to Top