Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with (two LD (HL),H NOPs effectively) followed by \CD\E7

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • Program Merge

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

    This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


    Program Analysis

    Program Structure

    The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

    1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
    2. Line 10 — SAVE command to persist the program to tape
    3. Line 11 — Full-screen instructions printed at row 10
    4. Line 12 — Prompt printed at row 20
    5. Line 13 — Busy-wait keypress loop using INKEY$
    6. Line 20RAND USR 16516 launches the machine code

    Machine Code Entry Point

    RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

    Relocation via PEEK 16388/16389

    The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

    Machine Code Highlights

    Disassembling the REM payload reveals several notable operations:

    • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
    • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
    • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
    • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
    • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
    • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

    Key BASIC Idioms

    IdiomLocationPurpose
    IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
    RAND USR 16516Line 20Jump into REM machine code at fixed address
    PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
    AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

    Notable Techniques

    Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

    Bugs and Anomalies

    Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

    Content

    Appears On

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

    Related Products

    Related Articles

    Related Content

    Image Gallery

    Source Code

       1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
      10 SAVE "1008%5"
      11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
      12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
      13 IF INKEY$="" THEN GOTO 13
      20 RAND USR 16516

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

    People

    No people associated with this content.

    Scroll to Top
    A
    LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \EDSBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \CD\E7



Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

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

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

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

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
C

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
\C7\E6\F6

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
\E1D

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
BE

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
B\F9

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
B

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
B

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

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

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
\ED\B0\C3\C3\CD\E7

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
\FD\CB\CD\CB\FB

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

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

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
EF\DB\FE\D3\FF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"FA\F1\C1\FD\CBA\CD\CB\FD\CB\C6\F5 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"EC\CD\CB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"D\F8 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"EF\CD\CB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"D\FA

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
AFD\B7\ED\C8\EB

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

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

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
\E5\CD\CB\EDB

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

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

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
EE\FF\FD\CBB\CF

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
CE\CF

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
D\CF\D5 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"E itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"A itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"D\DB\FE\CBBB\F5\F5\D1\FE\E3F\CB\DE\C9DE\E6\C0 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"A\BE

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

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

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
B\E5\EB\CD\F2\E1\EC\D5\CD\F2\E3\C5

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
B\CDE\C1\D1\EB\ED\B0\D2\D5\CD\F2\EB\D1\CA

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top

Program Merge

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

This program implements a BASIC program merger utility for the ZX81/TS1000, allowing two or more BASIC programs to be combined in memory. The machine code routine, stored as a REM statement at line 1, is invoked via RAND USR using the classic PEEK 16388+256*PEEK 16389 idiom to locate the start of BASIC regardless of RAM pack size. The REM data begins with the standard two-byte JP (0xC3) preamble at offset 2, making the machine code self-relocating and compatible with any memory configuration. Line 20 launches the routine directly at address 16516, which corresponds to the start of the REM statement’s data area in the default 1K RAM layout.


Program Analysis

Program Structure

The program is brief by design — its real payload is the machine code embedded in the REM statement at line 1. The remaining lines handle display and invocation:

  1. Line 1 — REM statement containing the binary machine code routine (approximately 230 bytes)
  2. Line 10 — SAVE command to persist the program to tape
  3. Line 11 — Full-screen instructions printed at row 10
  4. Line 12 — Prompt printed at row 20
  5. Line 13 — Busy-wait keypress loop using INKEY$
  6. Line 20RAND USR 16516 launches the machine code

Machine Code Entry Point

RAND USR 16516 at line 20 jumps directly into the REM data area. Address 16514 is the start of the BASIC program area (RAMTOP on a stock 1K/16K machine), and 16516 is two bytes in — past the line number and length fields — placing execution exactly at the first byte of the REM’s content. The REM data begins with \76\76 (two LD (HL),H NOPs effectively) followed by \CD\E7\02, a CALL 0x02E7, consistent with calling a ZX81 ROM routine.

Relocation via PEEK 16388/16389

The user instructions at line 11 direct the operator to invoke the merger after loading a target program using RAND USR(PEEK 16388+256*PEEK 16389). System variables at addresses 16388–16389 hold the PROG pointer — the address of the start of the BASIC program area. This idiom correctly locates the REM’s machine code regardless of which RAM configuration is in use, making the utility memory-size agnostic.

Machine Code Highlights

Disassembling the REM payload reveals several notable operations:

  • \2A\04\40LD HL,(0x4004): loads the PROG system variable, confirming the code operates on BASIC program memory directly.
  • \ED\42SBC HL,BC: used for address arithmetic, likely computing program lengths.
  • \ED\B0LDIR: block memory copy instruction, the core mechanism for merging program bytes.
  • \DB\FE / \D3\FFIN A,(0xFE) / OUT (0xFF),A: keyboard read and display port access, used during the merge operation for user interaction or synchronisation.
  • \CFRST 8 (ZX81 error handler): called at several points, likely for controlled exits or triggering specific ROM behaviours.
  • Multiple \1C bytes at the end of the REM — INC E instructions — appear to be padding or a data table used by the routine.

Key BASIC Idioms

IdiomLocationPurpose
IF INKEY$="" THEN GOTO 13Line 13Busy-wait loop until any key is pressed
RAND USR 16516Line 20Jump into REM machine code at fixed address
PEEK 16388+256*PEEK 16389Line 11 (instructions)Read PROG pointer to find machine code after reload
AT 10,0 / AT 20,0Lines 11–12Positional text layout using PRINT AT

Notable Techniques

Storing executable machine code inside a REM statement is a classic ZX81 technique: the BASIC interpreter skips REM content entirely, but the bytes remain in memory and are addressable. The fixed entry via RAND USR 16516 assumes the program loads at the default BASIC start address (0x4045 / 17477 in decimal, with line 1 starting at 16514 and data at 16516). The additional invocation method documented in the instructions (PEEK 16388+256*PEEK 16389) adds two to the PROG pointer to skip the REM line’s header and reach the code, providing a portable entry point suitable for use after merging programs when the absolute address may shift.

Bugs and Anomalies

Line 10 saves before the program has been run or tested by the user; a user loading this from tape would need to be aware that running line 10 immediately on load would simply re-save the loader. This is a common pattern for self-distributing utilities and is not a functional bug. No other anomalies are present in the BASIC wrapper.

Content

Appears On

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

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM \76\76\CD\E7\02\2A\04\40\01\E2\00\B7\ED\42\22\04\40\E5\01\0C\00\09\22\C7\40\22\E6\40\22\F6\40\22\00\41\22\19\41\E1\54\5D\2B\36\3E\2B\F9\2B\2B\22\02\40\21\BF\40\01\E2\00\ED\B0\C3\C3\03\CD\E7\02\FD\CB\21\86\CD\CB\40\18\FB\0E\01\06\00\3E\7F\DB\FE\D3\FF\1F\30\5A\17\17\38\67\10\F1\C1\FD\CB\21\46\20\5A\CD\CB\40\FD\CB\21\C6\79\17\30\F5\1E\05\21\3C\40\CD\CB\40\71\23\1D\20\F8\1E\6F\CD\CB\40\1D\20\FA\2A\3F\40\11\7D\40\B7\ED\52\C8\EB\2A\1C\40\01\80\00\09\E5\CD\CB\40\71\23\ED\4B\02\40\05\E5\ED\42\E1\30\19\1B\7A\B3\20\EB\36\80\E1\18\2E\3E\FF\32\27\40\FD\CB\3B\86\CF\0C\18\8E\CF\0D\CF\03\D5\1E\94\06\1A\1D\DB\FE\17\CB\7B\7B\38\F5\10\F5\D1\20\04\FE\56\30\E3\3F\CB\11\30\DE\C9\11\7D\40\7E\E6\C0\20\31\1A\13\BE\23\20\02\1A\BE\1B\2B\30\08\E5\EB\CD\F2\09\E1\18\EC\28\13\D5\CD\F2\09\E3\C5\2B\CD\9E\09\23\23\C1\D1\EB\ED\B0\18\D2\D5\CD\F2\09\EB\D1\18\CA\21\00\00\22\29\40\CF\FF\25\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C\1C
  10 SAVE "1008%5"
  11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK  WITH ANY SIZE MEMORY. TO USE    ENTER RAND USR(PEEK 16388+256*PEEK 16389)"
  12 PRINT AT 20,0;"PRESS ANY KEY TO RUN"
  13 IF INKEY$="" THEN GOTO 13
  20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top
\CF\FF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57136 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.7 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.5"C 10 SAVE "1008%5" 11 PRINT AT 10,0;"THIS PROGRAM WILL MERGE ANY TWO OR MORE PROGRAMS. IT WILL WORK WITH ANY SIZE MEMORY. TO USE ENTER RAND USR(PEEK 16388+256*PEEK 16389)" 12 PRINT AT 20,0;"PRESS ANY KEY TO RUN" 13 IF INKEY$="" THEN GOTO 13 20 RAND USR 16516

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

People

No people associated with this content.

Scroll to Top