ZXLR8

Products: Z-XLR8
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Tape

ZXLR8 is a machine code cassette storage accelerator that saves and loads data at 6 to 10 times the normal tape speed, with built-in error checking. The bulk of the program is a large machine code payload embedded in line 1’s REM statement, which is relocated and executed via RAND USR calls. The BASIC loader prompts the user for a timing value (POKEd to address 16961), a calibration value (POKEd to 17107), and a starting memory location, then patches several system variables and jump vectors before handing control to the machine code at address 18141. After setup, a NEW command clears the BASIC workspace, leaving only the resident machine code routine in memory. The error-checking routine is verified by testing USR 18520 against the value 8 after the initial load.


Program Analysis

Program Structure

The program consists of two distinct layers: a large machine code payload hidden inside the REM statement at line 1, and a BASIC loader spanning lines 90009082 that installs, configures, and then self-destructs. The REM data begins with

ZXLR8

Products: Z-XLR8
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Tape

ZXLR8 is a machine code cassette storage accelerator that saves and loads data at 6 to 10 times the normal tape speed, with built-in error checking. The bulk of the program is a large machine code payload embedded in line 1’s REM statement, which is relocated and executed via RAND USR calls. The BASIC loader prompts the user for a timing value (POKEd to address 16961), a calibration value (POKEd to 17107), and a starting memory location, then patches several system variables and jump vectors before handing control to the machine code at address 18141. After setup, a NEW command clears the BASIC workspace, leaving only the resident machine code routine in memory. The error-checking routine is verified by testing USR 18520 against the value 8 after the initial load.


Program Analysis

Program Structure

The program consists of two distinct layers: a large machine code payload hidden inside the REM statement at line 1, and a BASIC loader spanning lines 90009082 that installs, configures, and then self-destructs. The REM data begins with \00\C3\19\43 — a NOP followed by a JP 4319h — establishing an entry point immediately after the REM opcode byte itself. The machine code occupies several hundred bytes and implements the complete fast-tape save/load engine.

Load and Verification Sequence

Line 9001 calls USR 18520 and checks whether the return value equals 8. Address 18520 (decimal) falls within the REM payload and acts as a checksum or integrity probe; a return value other than 8 triggers the BAD LOAD error message at lines 90029003 and halts execution. This provides a simple but effective post-load sanity check before any system modifications are made.

User-Configurable Parameters

The loader collects three values interactively:

  • Timing value — entered at line 9006, POKEd to address 16961 (system variable area). This controls the bit-cell duration of the fast tape protocol.
  • Calibration value — entered at line 9014, POKEd to address 17107. This fine-tunes the read threshold or pulse discrimination for the tape input circuit.
  • Starting location — entered at line 9022 as variable L. A value of 0 aborts installation (IF L=0 THEN STOP).

The separation of timing and calibration into two distinct parameters allows the routine to be tuned for different tape decks and recording conditions, which is the primary reason the speed improvement spans a range (6–10×) rather than a fixed multiplier.

System Variable Patching

Lines 90249050 perform the relocation setup. The target address TA is computed as L + 1760, and the high and low bytes are split and POKEd to addresses 16631 and 16630 respectively — the system variable PROG pointer, redirecting where the ZX81 believes BASIC starts. A further block of six POKEs to addresses 1645016455 patches what appears to be a jump table or call vector inside the machine code itself, encoding the load address L as a 16-bit little-endian word at 16454/16455 and constants 131, 64, 23, 72 at the preceding four bytes.

Activation and Self-Removal

Line 9080 uses RAND USR 18141 to transfer control to the machine code entry point within the REM payload. On return (if the routine returns at all during normal operation), line 9082 executes NEW, wiping the BASIC program from memory. This leaves the fast-tape machine code resident as a standalone routine without the BASIC overhead, a classic self-installing loader pattern.

Machine Code Architecture Highlights

Inspection of the REM byte sequence reveals several notable Z80 constructs:

  • ED B0 (LDIR) appears multiple times, indicating block memory moves used for code relocation or buffer transfers.
  • DB FE (IN A,(254)) is the standard ZX81 tape/keyboard port read instruction, appearing repeatedly in the tight timing loops that sample the EAR line.
  • D3 FF (OUT (255),A) drives the MIC output for tape writing.
  • ED 53 / ED 5B (LD (nn),DE / LD DE,(nn)) are used extensively for 16-bit pointer manipulation, consistent with tracking tape buffer start/end addresses.
  • The alternating register set is used (D9 = EXX) to preserve counters across interrupt-sensitive sections.
  • A substantial data table embedded near the end of the REM block (the sequence of bytes in the range 0x180x3E) appears to be text or menu strings encoded with a fixed offset, possibly displayed during operation prompts.

Address Reference Table

AddressPurpose
16630/16631PROG system variable (low/high byte of BASIC program start)
1645016455Machine code jump/address table patched by loader
16961Timing parameter storage
17107Calibration parameter storage
18141Main entry point of fast-tape routine (RAND USR target)
18520Integrity check entry point (USR returns 8 on good load)

Notable Techniques and Idioms

  • The 16-bit address split idiom INT(X/256) and X - 256*INT(X/256) is used for both the TA and L values, the standard ZX81 BASIC method for computing high and low bytes without bitwise operators.
  • Using RAND USR rather than PRINT USR discards the return value cleanly and avoids a screen print side-effect.
  • The NEW at line 9082 is the self-erasing loader pattern: once machine code is resident, the BASIC is no longer needed and its memory is reclaimed.
  • The SAVE "%Z" at line 9000 allows the loader itself to be re-saved to tape before installation begins, ensuring the distribution copy is always accessible.

Content

Appears On

Related Products

Cassette storage system that SAVES/LOADS 6-10x faster than normal, with error checking. Fast array variable and binary data save/load independent...

Related Articles

Related Content

Image Gallery

ZXLR8

Source Code

   1 REM 0C31943CDDD40CD2BF2AC40233680E5CDB840E1FE76204CD23FC9FE7720B3602B7EFE762012B18E277237EFE7620DB2318D8CD2BF213B40CB7ECC292CB4628FCED4B2540CD4BFCDBD77EFE77C8FE76C8FE4030DCC92AC4011D6219142023B78B1C87EFE7628F636018F2216347227B40CDDD4061CDD45CD9040CDFF44170113E40EDB0CDDD4062CDD45CD9040CDFF447E324540237EFE31CA4642FE38CA3241C311413A4540FE37CA00FE27CA5341FE35CAA343FE29CAE343FE2CCA2B44FE2DCA3D44CDDD4063CD7241ED534740CDDD4064CD7241ED534940ED535840C38941CD7F417EFEDCC4E45C42B45C9CDD45CD9040CDFF44C9CDDD4065CD7F413EFD213C40772377CD7745324B40CD8145324C40325B40C3AB41DBFECDD541CDE54111110213C40CDF141CDFD41ED5B49402A4740CDF141CDD944CDDD4066CD7F41C9DBFE6611001B7AB320FB520F8C911E83CD6421B7AB320F8C97ECD13421B237AB3C2F141C91EFFCD6421D20FAC947DBFE78CD4042D3FFCD4042C9CD2742E87DC2742D4642DC21842CD642C947DBFE78CD4042CD4042CD4042D3FFCD4042CD4042CD4042C96FF520FDC9D9C5D5E53A4540FE2ECA9445FE27CA7142FE35CA4E44FE29CA7544FE2CCAC444FE2DCAD64463C5C35B43CDDD4063CD7241ED534740CDDD4065CD7F41CD9E42CD36432A47407CB5283225640CD4843CD6E43C39243CDD1421EF214D40CDE042FEFD20F9CDE042FEFD20F2CDE04277231DC2B442213E40114D40E71ABEC29E42D2313C2C542C9D9EFF1EFBD9C9D9E1E1E1D1C1D9C9D9CD46FD2D8426016FF15DBFEA7F2EB427BBADAE9427A91781747D2E942D9C9210281183401F87EDB0C921834011E02E1FA0EDB0C9F5D5C52A3B40E5CDF540E13E40A5283CD2BFC1D1F1C362B120F8C9214D401ED9786231D20FBBEC861DC35B432A5640ED5B5840CDE04277231B7AB3C24F43C9C5CDDD4067CDD45C17023C1CD9040C392432BED5B584097862B1B477AB378C274433278402A5B40227940ED5B5B40BBC861EC35B43D9E1D1C1D9CDD944CDDD4066CD7F41C911040ED5347402A1440A7ED5223224940225840CDDD4065CD7F413EFD213C40772377CD7745324B403E0324C40325B40CD8145ED44324C40325B40C3AB41CDDD4068CD7F41CD444235E2356ED53784023224740ED534940324640C389417ED62047237EFED3E80202CBF7B0472A10407EB8C8FE8020561FC35B43C5CDF29C1EB18ECED5BC40ED53474011D72ED534940C3894111020ED53474011018ED534940C38941CD5A44CD4843CD6E43C39243CDDD4065CD7F41CD9E42CD36432145403A5440BEC8620C35B43CDDD4068CD7F41CD444235E235623224740ED534940324640CD5A442146403A554086CB77286621C5C35B432A4940ED5B5840A7ED52306622C5C35B432A4740225640CD4843CD6E43C39243CD5A442AC40225640CD4843CD6E43C39243C34E44DBFE64C3D94150E52A7B401FF03E18EDB11520FB4E60EBE192B4713231AB8C87718F82AC4011F8219237EFE028FAC92AC4011D7219E5CDE044E11130019C9237EFE1C30FA2B2B1100EBC9CD1E45110CD6C451A0CD6C451640CD6C451E83CD6C4511027CD6C45EBC9CD1E45110CD6C451100CD6C45101CD6C451010CD6C45EB97C91A1BD61DD83C93D20FCC96D3E02386520FBC92A4740ED5B49403E0861B23477AB378C818F6E1D1C1223C40ED533E40ED434040C5D5E5CDDD4065CD7F41CDDD4069CDD45CDC8456ACDD45CDC845CDDA45CD934618F52AC40EB1321210191F72EDB0CDDD40C9CDD1421EF214D40CDE042FEFD20F9CDE042FEFD20F2CDE04277231D20F8CDA746CD1D46CD5246CD304611D0193A544077FE29205CD39463E0FE27203CDBC46C9CD304667114C4023131AFE80C8775C818F32AC402311D6219C9CD3046111C0193A5540E63FC62077233A5540CB77C836DC9CD30461113019224D40111027CD7B4611E83CD7B4611640CD7B4611A0CD7B461110CD7B46C92A58403E1B3CA7ED5230FA192258402A4D407723224D40C9D92A3C40ED5B3E40ED4B4040D91F00CD35FC91ED214D403E086231D20FB215A40BEC8E1C3DA452A5640225840CD3046111B019C359462A4640E5ED5B4240A7ED52224840C31748CDCC467EFEC3CA947FECDCA947E6C7FEC2CA947FEC4CA9477E121323ED4B4440A7E5ED42E138DAC333477E1213234E234623E52A4240A73ED42B30E2A4440A7ED423862A484094D44E1EB71237023EB18C82A4640118211936C9233647C351471936C923362A1117019362B23362BED5B46402A1440A7ED52D01BED53440C9761892E33353A3902B2E312A03326322A18A2E33353A3902834323226332918A2E33353A390262929372A383818A2E33353A390312A332C392D18B383926373903926352A18C3839343503926352A18E2A373734371872E33353A390292E3203B26372E2627312A1812B2E312A03326322A00393E352A00312A332C392D003839263739018033333333333333333333333333333333180ED5BB5421922B54222F145D12A4240C9282631310311F1928263131D1C2B1E2719312902D311B101D221F252211192E332802D3119E312131290102D31113E01947218340865FB78B17B2320F7604FC90FF0CF8202100EF0BF8008200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035
 9000 SAVE "%Z"
 9001 IF USR 18520=8 THEN GOTO 9004
 9002 PRINT AT 10,11;"BAD LOAD"
 9003 STOP 
 9004 CLS 
 9005 PRINT AT 10,7;"INPUT TIMING VALUE"
 9006 INPUT N
 9008 POKE 16961,N
 9010 CLS 
 9012 PRINT AT 10,4;"INPUT CALIBRATION VALUE"
 9014 INPUT N
 9016 POKE 17107,N
 9018 CLS 
 9020 PRINT AT 10,2;"INPUT Z-XLR8 STARTING LOCATION"
 9022 INPUT L
 9023 IF L=0 THEN STOP 
 9024 LET TA=L+1760
 9030 POKE 16631,INT (TA/256)
 9032 POKE 16630,TA-256*INT (TA/256)
 9040 POKE 16450,131
 9042 POKE 16451,64
 9044 POKE 16452,23
 9046 POKE 16453,72
 9048 POKE 16455,INT (L/256)
 9050 POKE 16454,L-256*INT (L/256)
 9080 RAND USR 18141
 9082 NEW 

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

People

No people associated with this content.

Scroll to Top
\C3
— a NOP followed by a JP 4319h — establishing an entry point immediately after the REM opcode byte itself. The machine code occupies several hundred bytes and implements the complete fast-tape save/load engine.

Load and Verification Sequence

Line 9001 calls USR 18520 and checks whether the return value equals 8. Address 18520 (decimal) falls within the REM payload and acts as a checksum or integrity probe; a return value other than 8 triggers the BAD LOAD error message at lines 90029003 and halts execution. This provides a simple but effective post-load sanity check before any system modifications are made.

User-Configurable Parameters

The loader collects three values interactively:

  • Timing value — entered at line 9006, POKEd to address 16961 (system variable area). This controls the bit-cell duration of the fast tape protocol.
  • Calibration value — entered at line 9014, POKEd to address 17107. This fine-tunes the read threshold or pulse discrimination for the tape input circuit.
  • Starting location — entered at line 9022 as variable L. A value of 0 aborts installation (IF L=0 THEN STOP).

The separation of timing and calibration into two distinct parameters allows the routine to be tuned for different tape decks and recording conditions, which is the primary reason the speed improvement spans a range (6–10×) rather than a fixed multiplier.

System Variable Patching

Lines 90249050 perform the relocation setup. The target address TA is computed as L + 1760, and the high and low bytes are split and POKEd to addresses 16631 and 16630 respectively — the system variable PROG pointer, redirecting where the ZX81 believes BASIC starts. A further block of six POKEs to addresses 1645016455 patches what appears to be a jump table or call vector inside the machine code itself, encoding the load address L as a 16-bit little-endian word at 16454/16455 and constants 131, 64, 23, 72 at the preceding four bytes.

Activation and Self-Removal

Line 9080 uses RAND USR 18141 to transfer control to the machine code entry point within the REM payload. On return (if the routine returns at all during normal operation), line 9082 executes NEW, wiping the BASIC program from memory. This leaves the fast-tape machine code resident as a standalone routine without the BASIC overhead, a classic self-installing loader pattern.

Machine Code Architecture Highlights

Inspection of the REM byte sequence reveals several notable Z80 constructs:

  • ED B0 (LDIR) appears multiple times, indicating block memory moves used for code relocation or buffer transfers.
  • DB FE (IN A,(254)) is the standard ZX81 tape/keyboard port read instruction, appearing repeatedly in the tight timing loops that sample the EAR line.
  • D3 FF (OUT (255),A) drives the MIC output for tape writing.
  • ED 53 / ED 5B (LD (nn),DE / LD DE,(nn)) are used extensively for 16-bit pointer manipulation, consistent with tracking tape buffer start/end addresses.
  • The alternating register set is used (D9 = EXX) to preserve counters across interrupt-sensitive sections.
  • A substantial data table embedded near the end of the REM block (the sequence of bytes in the range 0x180x3E) appears to be text or menu strings encoded with a fixed offset, possibly displayed during operation prompts.

Address Reference Table

AddressPurpose
16630/16631PROG system variable (low/high byte of BASIC program start)
1645016455Machine code jump/address table patched by loader
16961Timing parameter storage
17107Calibration parameter storage
18141Main entry point of fast-tape routine (RAND USR target)
18520Integrity check entry point (USR returns 8 on good load)

Notable Techniques and Idioms

  • The 16-bit address split idiom INT(X/256) and X - 256*INT(X/256) is used for both the TA and L values, the standard ZX81 BASIC method for computing high and low bytes without bitwise operators.
  • Using RAND USR rather than PRINT USR discards the return value cleanly and avoids a screen print side-effect.
  • The NEW at line 9082 is the self-erasing loader pattern: once machine code is resident, the BASIC is no longer needed and its memory is reclaimed.
  • The SAVE "%Z" at line 9000 allows the loader itself to be re-saved to tape before installation begins, ensuring the distribution copy is always accessible.

Content

Appears On

Related Products

Cassette storage system that SAVES/LOADS 6-10x faster than normal, with error checking. Fast array variable and binary data save/load independent...

Related Articles

Related Content

Image Gallery

ZXLR8

Source Code

   1 REM 0C31943CDDD40CD2BF2AC40233680E5CDB840E1FE76204CD23FC9FE7720B3602B7EFE762012B18E277237EFE7620DB2318D8CD2BF213B40CB7ECC292CB4628FCED4B2540CD4BFCDBD77EFE77C8FE76C8FE4030DCC92AC4011D6219142023B78B1C87EFE7628F636018F2216347227B40CDDD4061CDD45CD9040CDFF44170113E40EDB0CDDD4062CDD45CD9040CDFF447E324540237EFE31CA4642FE38CA3241C311413A4540FE37CA00FE27CA5341FE35CAA343FE29CAE343FE2CCA2B44FE2DCA3D44CDDD4063CD7241ED534740CDDD4064CD7241ED534940ED535840C38941CD7F417EFEDCC4E45C42B45C9CDD45CD9040CDFF44C9CDDD4065CD7F413EFD213C40772377CD7745324B40CD8145324C40325B40C3AB41DBFECDD541CDE54111110213C40CDF141CDFD41ED5B49402A4740CDF141CDD944CDDD4066CD7F41C9DBFE6611001B7AB320FB520F8C911E83CD6421B7AB320F8C97ECD13421B237AB3C2F141C91EFFCD6421D20FAC947DBFE78CD4042D3FFCD4042C9CD2742E87DC2742D4642DC21842CD642C947DBFE78CD4042CD4042CD4042D3FFCD4042CD4042CD4042C96FF520FDC9D9C5D5E53A4540FE2ECA9445FE27CA7142FE35CA4E44FE29CA7544FE2CCAC444FE2DCAD64463C5C35B43CDDD4063CD7241ED534740CDDD4065CD7F41CD9E42CD36432A47407CB5283225640CD4843CD6E43C39243CDD1421EF214D40CDE042FEFD20F9CDE042FEFD20F2CDE04277231DC2B442213E40114D40E71ABEC29E42D2313C2C542C9D9EFF1EFBD9C9D9E1E1E1D1C1D9C9D9CD46FD2D8426016FF15DBFEA7F2EB427BBADAE9427A91781747D2E942D9C9210281183401F87EDB0C921834011E02E1FA0EDB0C9F5D5C52A3B40E5CDF540E13E40A5283CD2BFC1D1F1C362B120F8C9214D401ED9786231D20FBBEC861DC35B432A5640ED5B5840CDE04277231B7AB3C24F43C9C5CDDD4067CDD45C17023C1CD9040C392432BED5B584097862B1B477AB378C274433278402A5B40227940ED5B5B40BBC861EC35B43D9E1D1C1D9CDD944CDDD4066CD7F41C911040ED5347402A1440A7ED5223224940225840CDDD4065CD7F413EFD213C40772377CD7745324B403E0324C40325B40CD8145ED44324C40325B40C3AB41CDDD4068CD7F41CD444235E2356ED53784023224740ED534940324640C389417ED62047237EFED3E80202CBF7B0472A10407EB8C8FE8020561FC35B43C5CDF29C1EB18ECED5BC40ED53474011D72ED534940C3894111020ED53474011018ED534940C38941CD5A44CD4843CD6E43C39243CDDD4065CD7F41CD9E42CD36432145403A5440BEC8620C35B43CDDD4068CD7F41CD444235E235623224740ED534940324640CD5A442146403A554086CB77286621C5C35B432A4940ED5B5840A7ED52306622C5C35B432A4740225640CD4843CD6E43C39243CD5A442AC40225640CD4843CD6E43C39243C34E44DBFE64C3D94150E52A7B401FF03E18EDB11520FB4E60EBE192B4713231AB8C87718F82AC4011F8219237EFE028FAC92AC4011D7219E5CDE044E11130019C9237EFE1C30FA2B2B1100EBC9CD1E45110CD6C451A0CD6C451640CD6C451E83CD6C4511027CD6C45EBC9CD1E45110CD6C451100CD6C45101CD6C451010CD6C45EB97C91A1BD61DD83C93D20FCC96D3E02386520FBC92A4740ED5B49403E0861B23477AB378C818F6E1D1C1223C40ED533E40ED434040C5D5E5CDDD4065CD7F41CDDD4069CDD45CDC8456ACDD45CDC845CDDA45CD934618F52AC40EB1321210191F72EDB0CDDD40C9CDD1421EF214D40CDE042FEFD20F9CDE042FEFD20F2CDE04277231D20F8CDA746CD1D46CD5246CD304611D0193A544077FE29205CD39463E0FE27203CDBC46C9CD304667114C4023131AFE80C8775C818F32AC402311D6219C9CD3046111C0193A5540E63FC62077233A5540CB77C836DC9CD30461113019224D40111027CD7B4611E83CD7B4611640CD7B4611A0CD7B461110CD7B46C92A58403E1B3CA7ED5230FA192258402A4D407723224D40C9D92A3C40ED5B3E40ED4B4040D91F00CD35FC91ED214D403E086231D20FB215A40BEC8E1C3DA452A5640225840CD3046111B019C359462A4640E5ED5B4240A7ED52224840C31748CDCC467EFEC3CA947FECDCA947E6C7FEC2CA947FEC4CA9477E121323ED4B4440A7E5ED42E138DAC333477E1213234E234623E52A4240A73ED42B30E2A4440A7ED423862A484094D44E1EB71237023EB18C82A4640118211936C9233647C351471936C923362A1117019362B23362BED5B46402A1440A7ED52D01BED53440C9761892E33353A3902B2E312A03326322A18A2E33353A3902834323226332918A2E33353A390262929372A383818A2E33353A390312A332C392D18B383926373903926352A18C3839343503926352A18E2A373734371872E33353A390292E3203B26372E2627312A1812B2E312A03326322A00393E352A00312A332C392D003839263739018033333333333333333333333333333333180ED5BB5421922B54222F145D12A4240C9282631310311F1928263131D1C2B1E2719312902D311B101D221F252211192E332802D3119E312131290102D31113E01947218340865FB78B17B2320F7604FC90FF0CF8202100EF0BF8008200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035
 9000 SAVE "%Z"
 9001 IF USR 18520=8 THEN GOTO 9004
 9002 PRINT AT 10,11;"BAD LOAD"
 9003 STOP 
 9004 CLS 
 9005 PRINT AT 10,7;"INPUT TIMING VALUE"
 9006 INPUT N
 9008 POKE 16961,N
 9010 CLS 
 9012 PRINT AT 10,4;"INPUT CALIBRATION VALUE"
 9014 INPUT N
 9016 POKE 17107,N
 9018 CLS 
 9020 PRINT AT 10,2;"INPUT Z-XLR8 STARTING LOCATION"
 9022 INPUT L
 9023 IF L=0 THEN STOP 
 9024 LET TA=L+1760
 9030 POKE 16631,INT (TA/256)
 9032 POKE 16630,TA-256*INT (TA/256)
 9040 POKE 16450,131
 9042 POKE 16451,64
 9044 POKE 16452,23
 9046 POKE 16453,72
 9048 POKE 16455,INT (L/256)
 9050 POKE 16454,L-256*INT (L/256)
 9080 RAND USR 18141
 9082 NEW 

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

People

No people associated with this content.

Scroll to Top