TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM 



TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
A

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
C\E5

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
\D1 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57133 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.5 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

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
\ED\B0\C9

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
A

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
\ED\E5

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
\ED\D1 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57133 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.5 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

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
\ED\B8

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
A

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
C

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
\FB\C9

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
A

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
C\D6

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
BE

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
BE\FE

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
\F2\C9F\F1

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
A

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
CE

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
E\FE

TSUG Demo

This file is part of Timex Sinclair Public Domain Library Tape 1002 . Download the collection to get this file.
Developer(s): Tim Ward
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a demonstration/banner display for a Timex/Sinclair user group, cycling through eight machine code routines stored as addresses in array S. The REM line at line 0 contains a substantial block of Z80 machine code (approximately 100 bytes) that implements the eight display effect subroutines called via RAND USR. Each routine is called 32 times per screen fill, and the program loops endlessly through all eight effects after printing the group’s name 22 times to fill the display. The S() array holds direct entry-point addresses into the machine code embedded in the REM statement, which begins at address 16385 (the byte after the REM token on line 0).


Program Analysis

Program Structure

The program has two distinct layers: a BASIC driver (lines 1–20) and a library of Z80 machine code routines embedded in the REM statement at line 0. The BASIC layer fills the screen with the group name, invokes each machine code effect 32 times, clears the screen, then advances to the next effect in an infinite loop.

  1. Line 0REM containing raw Z80 opcodes (~100 bytes)
  2. Lines 1–9 — Initialise array S(8) with eight machine code entry-point addresses
  3. Lines 11–19 — Outer loop over 8 effects; inner loops fill screen then call the current effect 32 times
  4. Line 20GOTO 11 for perpetual looping
  5. Lines 21–22SAVE and RUN for distribution purposes only

Machine Code in the REM Statement

On the ZX81/TS1000, line 0’s REM body starts at address 16385 (0x4001). The eight entry points stored in S(1)S(8) are offsets into this block:

Array elementAddress (decimal)Offset into REM (hex)
S(1)16626+0xF1 (241)
S(2)16514+0x81 (129)
S(3)16633+0xF8 (248)
S(4)16560+0xAF (175)
S(5)16588+0xCB (203)
S(6)16619+0xEA (234)
S(7)16529+0x90 (144)
S(8)16612+0xE3 (227)

The machine code is called via RAND USR S(X), the standard ZX81 idiom for invoking Z80 routines from BASIC. The return value on the calculator stack is ignored.

Disassembly Notes

Tracing the byte sequence reveals several recognisable Z80 patterns:

  • 2A 0C 40LD HL,(400C): loads the display file address (D_FILE system variable at 0x400C)
  • ED B0 / ED B8LDIR / LDDR: block copy instructions, strongly suggesting scroll or copy screen effects
  • 11 21 00 19 D1 — sets DE to 0x0021 (33, one display row width) and loads it back, consistent with per-row addressing
  • 01 D6 02LD BC,02D6 = 726 bytes, which is 22 rows × 33 bytes (the full ZX81 display file size)
  • 36 00 / 10 FBLD (HL),00 / DJNZ: clearing loop, used in what appears to be a screen-clear or wipe effect
  • FE 76CP 76h (HALT): tests for the ZX81 NEWLINE character (0x76) used as a row terminator in the display file
  • CD CC 40 / CD 91 40 / CD 82 40 / CD B0 40 — internal CALLs between sub-routines within the REM block, confirming a modular design with shared helper routines

Key BASIC Idioms

  • RAND USR address — the canonical ZX81 method for calling machine code; RANDOMIZE discards the USR return value cleanly.
  • Pre-initialised address array — storing entry points in S() allows the outer loop to dispatch to any of the eight routines with a single RAND USR S(X) statement, avoiding a large IF/GOTO dispatch table.
  • Screen fill via PRINT — 22 repetitions of the 33-character banner string exactly fills the 22-row ZX81 display before the effect routines run.

Notable Techniques

Embedding machine code in a REM statement at line 0 is a well-established ZX81 technique: line 0 guarantees the code sits at the lowest possible address in the BASIC program area (0x4001 + a small header), making the absolute entry-point addresses predictable and stable regardless of other program content. The eight effects are likely scroll, wipe, invert, and similar display manipulations, each implemented as a small subroutine that shares helper code via internal CALLs, keeping the total footprint compact.

Potential Issues

  • The entry-point addresses in S() are hardcoded and will break if the REM line content or any preceding program line changes length, as this shifts the machine code to a different address.
  • There is no guard against BASIC editing inadvertently corrupting the machine code bytes in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

TSUG Demo

Source Code

   0 REM \2A\0C\40\E5\11\21\00\19\D1\01\D6\02\ED\B0\C9\2A\10\40\11\43\00\ED\52\E5\11\21\00\ED\52\D1\01\B5\02\ED\B8\2A\0C\40\06\20\23\36\00\10\FB\C9\2A\0C\40\11\D6\02\19\06\16\2B\4E\36\00\2B\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\2A\0C\40\06\16\23\4E\36\00\23\7E\FE\76\28\02\18\03\10\F2\C9\71\4F\18\F1\CD\CC\40\CD\91\40\C9\CD\B0\40\CD\91\40\C9\CD\B0\40\CD\82\40\C9\CD\CC\40\CD\82\40\C9
   1 DIM S(8)
   2 LET S(1)=16626
   3 LET S(2)=16514
   4 LET S(3)=16633
   5 LET S(4)=16560
   6 LET S(5)=16588
   7 LET S(6)=16619
   8 LET S(7)=16529
   9 LET S(8)=16612
  11 FOR X=1 TO 8
  12 FOR I=1 TO 22
  13 PRINT "==TIMEX/SINCLAIR USER""S GROUP=="
  14 NEXT I
  15 FOR I=1 TO 32
  16 RAND USR S(X)
  17 NEXT I
  18 CLS 
  19 NEXT X
  20 GOTO 11
  21 SAVE "1008%2"
  22 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top
\F2\C9F\F1\CD\CC\CD\C9\CD\B0\CD\C9\CD\B0\CD\C9\CD\CC\CD\C9 1 DIM S(8) 2 LET S(1)=16626 3 LET S(2)=16514 4 LET S(3)=16633 5 LET S(4)=16560 6 LET S(5)=16588 7 LET S(6)=16619 8 LET S(7)=16529 9 LET S(8)=16612 11 FOR X=1 TO 8 12 FOR I=1 TO 22 13 PRINT "==TIMEX/SINCLAIR USER""S GROUP==" 14 NEXT I 15 FOR I=1 TO 32 16 RAND USR S(X) 17 NEXT I 18 CLS 19 NEXT X 20 GOTO 11 21 SAVE "1008%2" 22 RUN

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top