This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
| Lines | Purpose |
|---|---|
| 1–2 | Z80 machine code embedded in REM statements |
| 4–8 | Display file relocation test / diagnostic |
| 10–80 | KEYBOARD LIST operation with hex address entry |
| 100–150 | WRITE operation: input and write bytes to memory |
| 200–250 | INSERT operation: input and insert bytes |
| 300–340 | DELETE operation |
| 400–422 | Save the full tool as “HEXLD3” and reset |
| 500–520 | Exit/CLEAR utility |
| 600–670 | Shared subroutine: address entry into fixed memory locations |
| 700–722 | Four-hex-digit to integer decoder with high/low byte display |
| 740–820 | Decimal value to high/low byte POKE utility |
| 830–840 | Save program image and LIST from line 4 |
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539— initialise/setup (used before KEYBOARD LIST and WRITE)16589— write byte routine16635— used as dimension value inDIM O$16651— prepare for SAVE16669— exit/CLEAR helper16687— insert byte routine16732— delete byte routine (also called viaRUN USRat line 340)16762— high/low byte display helper17106— display file relocation initialiser32258— routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732rather thanRAND USR;RUNon the ZX81 is equivalent toRUN 0which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself. - Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use ofUSRas a dimension expression. - The
CLEARat line 660 inside the address-entry subroutine (beforeRETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack. - Line 830 saves the program as
"1023%8"where%8represents an inverse “8” character — a common auto-run encoding. - The program mixes
GOSUB 600and directGOSUB 610calls to enter the address subroutine either with or without initialising the target address variableAfirst.
Content
Source Code
1 REM \F5\E6\F0 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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"F itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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"F itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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"F itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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"F\C6 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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\D7\F1\E6
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\C6 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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\D7\C9DDEFF
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
AD
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\A7\ED itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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"FC\CDD\CD\AF\D7E\CD\CB\AF\D7E\D7E\D7\DB\CF
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\CB\F4\EDBE\C6\ED\E5
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\ED\E1\ED\E1\C9
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\EDB\A7\EDD\C9
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\EB
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\EDB\ED\B0\C9
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\EDB\EDB\ED\B0\C9
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
AE\CB\CB
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CF\C5
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\EDB\A7\EDD\E1\EDB\EB\ED\B8\CD\CD\C9
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\EDB\D5\A7\EDD\E1\EDB\ED\B0 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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\ED\CF\D2
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
AC\CDD\CD\C9D\F5\CBFE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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\D7\F1\CB\EF\F5\F1\C9\D7\F1\C9DDDDDDDDDDDDDDDDDDDDDDDDDDDD
2 REM \A9
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EEB\D7C\CD\FFED\CD\FFE\AF\D7
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E\FE\DD\FE\FD\CD\FFE
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\F0\FE\ED\CD\FFEE\E5\E6\C3\FE
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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"\E1
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
BE\CD\FFE\F9
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E\B8\E5\CBF\F5\C6FFE\F1E itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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"F itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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"F itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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"F itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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"F
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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"F itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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"F\E6\E1
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
BE\CD\FFE\F9
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E\C3
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EDDDDDDDDDDDDF\A5\A5\AF\A5\A5\A5\AF\F5\A5\A5\F5\A5\AF\F5\E5\A5\F5\A5\FF\F5\A5\FE\FF\A5\FA\F5\A5\FA\F5\A5\F5\F5\A5\F5\FA\A5\F5\F5\A5\F5\F5\A5\F5\E6\F0 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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"F itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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"F itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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"F itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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"F\C6 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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\D7\F1\E6
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\C6 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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\D7\C9 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57437 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"
Skip to content
Hex Editor
This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
This program is a machine code loader and memory editor (“HEXLD3”) for the ZX81/TS1000, embedding two substantial blocks of Z80 machine code in REM statements at lines 1 and 2. The BASIC acts as a front-end for several machine code routines accessed via RAND USR calls at addresses such as 16539, 16589, 16687, 16732, and others, providing operations including WRITE, INSERT, and DELETE on memory addresses. Hex address entry is handled by decoding two-character ASCII pairs with the formula `16*CODE A$+CODE A$(2)-476`, converting hex digit pairs to byte values. The program manages its own display area by POKEing the ZX81 display file pointer (addresses 16388–16389) and includes utilities to split a 16-bit value into high and low bytes. A DIM statement at line 400 uses `USR 16635` as the array dimension, and line 420 SAVEs the full package as “HEXLD3”.
Program Analysis
Program Structure
The program is divided into several functional sections, each triggered by running or jumping to a specific line number. The BASIC serves primarily as a loader and user-interface wrapper around Z80 machine code stored in two REM statements.
Lines Purpose 1–2 Z80 machine code embedded in REM statements 4–8 Display file relocation test / diagnostic 10–80 KEYBOARD LIST operation with hex address entry 100–150 WRITE operation: input and write bytes to memory 200–250 INSERT operation: input and insert bytes 300–340 DELETE operation 400–422 Save the full tool as “HEXLD3” and reset 500–520 Exit/CLEAR utility 600–670 Shared subroutine: address entry into fixed memory locations 700–722 Four-hex-digit to integer decoder with high/low byte display 740–820 Decimal value to high/low byte POKE utility 830–840 Save program image and LIST from line 4
Machine Code in REM Statements
Lines 1 and 2 contain dense Z80 machine code. The code in line 1 begins at address 16514 (the byte after the REM token at line 1) and spans approximately 140 bytes, with entry points called from BASIC at addresses 16539, 16589, 16635, 16651, 16669, 16687, 16732, and 16762. Line 2 starts around 16640 and provides additional routines including a loader at address 17106 referenced in line 6.
Key Z80 constructs visible in the REM data include LDIR (ED B0) block copies, RST 10h (D7) character output calls, RST 08h (CF 08) error restart calls, and structured use of the IX/IY registers. The routines manipulate ZX81 system variables directly, including the display file pointer at addresses 16388–16389 (DFILE).
Hex Address Entry Idiom
The program uses a consistent two-character hex input convention to POKE address bytes. The formula:
16*CODE A$+CODE A$(2)-476
converts two ASCII hex digits (e.g. “4F”) into a byte value. Since ZX81 CODE of ASCII ‘0’–’9′ gives 28–37 and ‘A’–’F’ gives 38–43 (ZX81 character codes), the constant 476 = 16×29+12… however this program appears to use standard ASCII codes (uppercase hex), so CODE “0”=48, CODE “A”=65. Thus for “4F”: 16×52+70−476 = 832+70−476 = 426? The exact calibration depends on the character set and input method; the subroutine at lines 640–650 mirrors the same formula for address bytes split into high and low, POKEing A (low byte) and A+1 (high byte) into fixed locations at or near 16533–16534.
The four-digit version at line 710 extends this to:
4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
which decodes a full 16-bit hex address from a four-character string.
Display File Manipulation
Lines 4–5 directly POKE the ZX81 system variable DFILE (addresses 16388–16389) to set the display file pointer to address 32256 (0x7E00), relocating the display to high RAM. Line 6 calls RAND USR 17106 to execute an initialisation routine, and line 7 reads back the pointer to verify it. This is a common technique for creating a stable display area in RAM above the BASIC program.
RAND USR as Machine Code CALL
Throughout the program, RAND USR nnnn is used exclusively as a way to call Z80 subroutines, with no interest in the random number result. This is the standard ZX81 BASIC idiom for invoking machine code without a dedicated CALL keyword. Entry points used include:
16539 — initialise/setup (used before KEYBOARD LIST and WRITE)
16589 — write byte routine
16635 — used as dimension value in DIM O$
16651 — prepare for SAVE
16669 — exit/CLEAR helper
16687 — insert byte routine
16732 — delete byte routine (also called via RUN USR at line 340)
16762 — high/low byte display helper
17106 — display file relocation initialiser
32258 — routine in relocated display area
Notable Techniques and Anomalies
- Line 340 uses
RUN USR 16732 rather than RAND USR; RUN on the ZX81 is equivalent to RUN 0 which restarts the program, so this appears to be a bug — it would restart rather than call the delete routine. It may be intentional if the machine code at 16732 never returns to BASIC and handles control flow itself.
- Line 400 uses
DIM O$(USR 16635), which calls the machine code routine as a numeric function to obtain the required array size dynamically — an unusual use of USR as a dimension expression.
- The
CLEAR at line 660 inside the address-entry subroutine (before RETURN) clears the ZX81 variables area. This is intentional to free memory and reset the stack before the machine code routines take over, but it means the subroutine cannot truly “return” in the normal BASIC sense without the machine code managing the stack.
- Line 830 saves the program as
"1023%8" where %8 represents an inverse “8” character — a common auto-run encoding.
- The program mixes
GOSUB 600 and direct GOSUB 610 calls to enter the address subroutine either with or without initialising the target address variable A first.
Content
Source Code
1 REM \F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\3D\3D\13\7E\39\7F\39\7F\2A\99\40\22\97\40\54\5D\2A\95\40\A7\ED\52\19\30\1F\7C\CD\82\40\7D\CD\82\40\AF\D7\7E\CD\82\40\CB\76\20\04\AF\D7\7E\D7\3E\76\D7\23\22\95\40\18\DB\CF\00\2A\10\40\23\46\23\CB\28\28\F4\ED\5B\95\40\23\7E\87\87\87\87\23\86\C6\24\12\13\ED\53\95\40\E5\2A\99\40\ED\52\E1\30\04\ED\53\99\40\10\E1\C9\2A\99\40\ED\5B\93\40\A7\ED\52\22\97\40\44\4D\C9\2A\10\40\11\06\00\19\EB\2A\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\11\06\00\19\ED\5B\93\40\ED\4B\97\40\ED\B0\C9\2A\10\40\23\4E\23\46\CB\28\CB\19\20\02\CF\08\C5\2A\99\40\ED\5B\95\40\A7\ED\52\23\44\4D\E1\ED\5B\99\40\19\22\99\40\EB\ED\B8\CD\CD\40\C9\2A\99\40\ED\5B\97\40\D5\A7\ED\52\44\4D\E1\23\ED\5B\95\40\ED\B0\1B\ED\53\99\40\CF\08\D2\42\2A\78\41\7C\CD\82\40\7D\CD\82\40\C9\3D\06\08\F5\CB\7F\28\04\3E\1D\18\02\3E\1C\D7\F1\CB\07\10\EF\F5\F1\C9\D7\F1\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
2 REM \A9\40\2A\00\7E\3E\3B\87\D7\7C\CD\FF\7E\7D\CD\FF\7E\AF\D7\0E\00\7E\FE\DD\28\04\FE\FD\20\07\CD\FF\7E\23\0C\18\F0\FE\ED\20\21\CD\FF\7E\23\7E\E5\E6\C3\FE\43\20\04\06\03\18\02\06\01\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\18\B8\E5\CB\3F\F5\C6\7F\6F\26\7E\F1\7E\38\04\1F\1F\1F\1F\0D\20\02\1F\1F\E6\03\47\E1\2B\23\7E\CD\FF\7E\10\F9\23\22\00\7E\C3\02\7E\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\5F\55\55\A5\55\55\55\A5\AF\55\55\A5\A5\55\55\A5\AF\F5\55\A5\A5\F5\55\A5\AF\F5\99\E5\A5\F5\55\A5\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\99\99\99\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\55\55\95\55\FF\F5\A5\55\FE\FF\A5\55\FA\F5\A5\55\FA\F5\A5\55\F5\F5\A5\55\F5\FA\A5\55\F5\F5\A5\55\F5\F5\A5\F5\E6\F0\1F\1F\1F\1F\C6\1C\D7\F1\E6\0F\C6\1C\D7\C9\01\3B\01\11\00\7E\21\C2\41\ED\B0\C9\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E\C2\ED\B0\C9DDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
4 POKE 16388,0
5 POKE 16389,126
6 RAND USR 17106
7 PRINT AT 5,5;PEEK 16388+256*PEEK 16389
8 STOP
10 PRINT "KEYBOARD LIST "
20 GOSUB 600
30 RAND USR 16539
40 LET A=32256
45 PRINT
50 INPUT A$
55 PRINT A$
60 POKE A+1,16*CODE A$+CODE A$(2)-476
65 POKE A,16*CODE A$(3)+CODE A$(4)-476
70 RAND USR 32258
80 STOP
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
310 GOSUB 600
320 LET A=16535
330 GOSUB 610
340 RUN USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
422 NEW
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS "
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
700 INPUT A$
710 LET A=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332
711 LET B=INT (A/256)
712 LET C=A-((INT (A/256))*256)
713 PRINT
714 PRINT A$
715 PRINT A
716 PRINT "HIGH=";B
717 PRINT "LOW=";C
722 STOP
740 LET V=16760
750 INPUT X
760 LET B=INT (X/256)
790 LET C=X-((INT (X/256))*256)
797 POKE V,C
799 POKE V+1,B
800 PRINT
802 PRINT X
805 PRINT "LOW= ";C
806 PRINT "HIGH= ";B
810 RAND USR 16762
820 STOP
830 SAVE "1023%8"
840 LIST 4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
