--- title: "Hexload I & II" id: 71946 type: "computer_media" slug: "hexload-i-ii" url: "http://localhost/computer_media/hexload-i-ii/" markdown_url: "http://localhost/computer_media/hexload-i-ii.md" published_at: "2026-10-20T14:07:47+00:00" modified_at: "2026-10-20T14:12:24+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/10/HEXLOAD-scaled.jpg" excerpt: "Two BASIC hex loaders for entering machine code: a minimal eight-line poker and a three-stage tool that writes, lists and saves code with a text-entry mode." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Utility" slug: "utility" taxonomy: "genre" url: "http://localhost/type/utility/" media_type: "Cassette" download_url: "https://archive.org/download/timex-sinclair-software-archive/Hexload%20I%20and%20II%20%28198x%29%28-%29%28TS1000%29%28US%29%28Cassette%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/10/HEXLOAD-scaled.jpg" related_content: - id: 56687 title: "Hexload III" type: "computer_media" url: "http://localhost/computer_media/hexload-iii/" media_type_tags: "Utility" --- # Hexload I & II Two BASIC tools for typing machine code in as hexadecimal. HEXLOAD I is eight lines long: it `POKE`s pairs of hex digits into memory from address 30000 until you enter `S`. HEXLOAD II takes a four-digit hex start address, echoes each byte as it is entered, and adds a text mode in which characters typed between semicolons are stored as ZX81 character codes. It also has a routine that saves a block of code starting at 4C00 hex by copying it into a string array, so the block is saved with the program. The later stages of HEXLOAD II add a prompt for a hex address and a `RAND USR 16539` call meant to list memory through machine code held in REM lines. The handwritten label reads “HEXLOAD”. The tape holds HEXLOAD I and three successive saves of HEXLOAD II. Part 1 is the write-and-save version. Part 2 replaces the restore routine with an address prompt and a machine-code call. Part 3 is the same as part 2 with three REM lines added at the top to hold machine code. Hexload III, a later program, is also in the archive. ## Program Analysis ### Hex Conversion Both programs convert hex with a single expression that relies on the ZX81 character set, where the digits 0–9 (codes 28–37) are followed directly by A–F (38–43). A byte is `16*CODE A$+CODE A$(2)-476`, where 476 = 17 × 28. A four-digit address is `4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332`, where 122332 = 4369 × 28. Input can be a long string of pairs, which the loop works through two characters at a time with `A$=A$(3 TO )`. ### HEXLOAD II - **Write (lines 10–140)**: asks “WRITE TO” for a hex address, then accepts hex pairs, printing each as it is stored. `S` stops the program. - **Text mode (lines 300–380)**: an entry starting with `;` (ZX81 code 25) switches to storing each following character’s own code until the next `;`. The `**` token (216) is stored as 118, the ZX81 NEWLINE character. - **Save (lines 500–640)**: asks for the end address of a block starting at 4C00 hex (19456), copies the bytes into `O$` with `PEEK`, and runs `SAVE`. When the tape is loaded again, the program continues at line 600, `POKE`s the bytes back into place and runs `CLEAR` to discard the array. - **List (parts 2 and 3, lines 10–30 and 600–670)**: asks for a hex address, `POKE`s it high byte to 16534 and low byte to 16533, and calls `RAND USR 16539`. In part 3, those addresses fall inside the first of three REM lines (255 bytes reserved), which was meant to hold the listing routine. ### Notable Techniques - The save routine copies code into a dimensioned string, which is saved with the program’s variables, and copies it back after loading. This keeps code stored in unreserved memory above the BASIC area across a save. - Text mode lets ZX81 strings and messages for machine-code routines be typed as characters instead of hex. ### Potential Issues - In part 3, the reserved REM lines still hold the placeholder digits `1234567890…`, so the listing routine called by `RAND USR 16539` isn’t on this save. In part 2 there is no REM at all, and 16533–16539 fall inside the BASIC lines themselves. - In parts 2 and 3, line 660 runs `CLEAR` before returning, which erases `A$`. Line 40’s `GOSUB 200` then has no string to convert. - Parts 2 and 3 keep the `SAVE` at line 590 but replace the restore loop at 600 with the address prompt, so a block saved from those versions isn’t put back after loading. - Neither program lowers RAMTOP. Code at 30000 or 4C00 sits in free memory, and the `DIM O$` in the save routine is allocated in that same area, so a long program or a large block could overwrite the code before it is copied. - Neither program checks its input. An odd number of digits or a character outside 0–9 and A–F produces a wrong byte or an error. ## Source Code ``` 10 PRINT "WRITE TO "; 20 INPUT A$ 30 PRINT A$ 40 GOSUB 200 50 PRINT 60 LET A$="" 70 IF A$="" THEN INPUT A$ 80 IF A$="S" THEN STOP 90 IF CODE A$=25 THEN GOTO 300 100 PRINT A$( TO 2);" "; 110 POKE X,16*CODE A$+CODE A$(2)-476 120 LET X=X+1 130 LET A$=A$(3 TO ) 140 GOTO 70 200 LET X=4096*CODE A$+256*CODE A$(2)+16*CODE A$(3)+CODE A$(4)-122332 210 RETURN 300 LET A$=A$(2 TO ) 310 PRINT ".";A$(1);" "; 320 POKE X,CODE A$ 330 IF CODE A$=216 THEN POKE X,118 340 LET A$=A$(2 TO ) 350 LET X=X+1 360 IF CODE A$<>25 THEN GOTO 310 370 LET A$=A$(2 TO ) 380 GOTO 70 500 PRINT "4C00 TO "; 510 INPUT A$ 520 PRINT A$ 530 GOSUB 200 540 LET Y=X-19456 550 DIM O$(Y) 560 FOR X=1 TO Y 570 LET O$(X)=CHR$ PEEK (19456+X) 580 NEXT X 590 SAVE "█" 600 FOR X=1 TO Y 610 POKE 19456+X,CODE O$(X) 620 NEXT X 630 CLEAR 640 STOP ```