--- title: "Fast Tape Loading" id: 57135 type: "computer_media" slug: "unknown-machine-code-routine" url: "http://localhost/computer_media/unknown-machine-code-routine/" markdown_url: "http://localhost/computer_media/unknown-machine-code-routine.md" published_at: "2024-10-04T00:06:12+00:00" modified_at: "2026-03-30T21:19:37+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/84_Unk.png" excerpt: "A self-installing machine code loader hides inside a REM statement, rewrites RAM, then wipes itself — leaving only the code it delivered behind." 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_contents: - id: 56733 title: "Timex Sinclair Public Domain Library Tape 1002" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1002/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/84_Unk.png" media_type_tags: "Utility" --- # Fast Tape Loading This program is a ZX81/TS1000 machine code routine embedded in a REM statement at line 10, invoked via RAND USR 16514 at line 20. The machine code implements what appears to be a fast tape loading system, manipulating memory around address 0x4000 (the display file region) and performing LDIR block moves, suggesting it relocates or patches data in RAM. The routine uses the HL register pair as a pointer saved at address 0x407B and includes calls to ROM routines (e.g., CD A7 0E and CD 20 15), indicating interaction with the ZX81 ROM’s character/token handling. Line 30 executes NEW after the routine completes, wiping BASIC memory, and line 60 notes that RAND USR 32500 can be used as an alternative entry point for the loaded code. *** ## Program Analysis ### Program Structure The listing has five active lines and one comment line: 1. `10 REM` — contains the raw machine code payload (approximately 190 bytes of Z80 opcodes) 2. `20 RAND USR 16514` — transfers execution to the machine code inside the REM body (16514 = 0x4082, two bytes past the REM token and length field at line 10) 3. `30 NEW` — wipes BASIC memory after the machine code returns 4. `40 SAVE "1008%4"` — saves the program to tape 5. `50 LIST` — lists the program 6. `60 REM RAND USR 32500 TO USE` — documents the entry point for the installed code ### Machine Code Entry and Memory Map `RAND USR 16514` jumps to offset +2 inside the REM data at line 10, which is the standard ZX81 technique for embedding executable machine code in a REM statement. The base of the program in RAM is 0x4080, so 16514 (0x4082) lands directly on the first opcode. | Address | Role | | --- | --- | | 0x4082 | Machine code entry point (start of REM data) | | 0x400C | Pointer/counter used during copy loop | | 0x401C | Secondary pointer saved and restored during operation | | 0x407B–0x407C | HL save location used as running pointer | | 0x7FEE | Target area for installed code (near top of RAM) | | 32500 (0x7F04) | Documented entry point for the delivered routine | ### Key Z80 Techniques - **LDIR block copy (`ED B0`)** — used at least twice to relocate blocks of data, likely copying the payload from the REM area to high RAM around 0x7FEE. - **HL save/restore via RAM (`22 7B 40` / `2A 7B 40`)** — the HL register is repeatedly saved to 0x407B and reloaded, acting as a persistent pointer across subroutine calls. - **LDDR block copy (`ED B8`)** — a reverse block move is used in addition to LDIR, suggesting overlapping source and destination regions. - **ROM calls** — `CD A7 0E` (0x0EA7) and `CD 20 15` (0x1520) call into the ZX81 ROM; 0x0EA7 is related to expression evaluation/token scanning and 0x1520 is near the SAVE/LOAD routines. - **Token scanning loop** — the code walks through the REM body byte by byte, comparing against `0xEC`, `0xED`, `0x76` (NEWLINE), and `0x10`, indicating it is parsing the tokenised BASIC line to locate data boundaries. - **Arithmetic via 16-bit subtraction (`ED 52` = SBC HL,DE)** — used to compute lengths or offsets dynamically. ### Loader Behaviour The overall behaviour is consistent with a *relocating self-installer*: the machine code inside the REM statement scans its own containing line to determine the extent of the payload data, copies that data to high RAM (around 0x7FEE and below), patches any necessary addresses, then returns to BASIC. Line 30 (`NEW`) then destroys the BASIC program, leaving only the freshly installed high-RAM routine accessible via `RAND USR 32500` as documented in line 60. The trailing bytes `3D 3D 3D 3D 3D` (DEC A repeated) followed by a run of `24` bytes at the end of the REM data are likely padding or a data table rather than executable code, since the main routine branches away before reaching them. ### SAVE Line Line 40 saves the program under a filename containing an inverse-video digit, which is the standard mechanism on this platform for marking a program to auto-run on load. The program is distributed ready to self-install on loading. ### Anomalies and Notes - Lines 30 (`NEW`) and 50 (`LIST`) will never be reached during normal execution, since the machine code at line 20 either halts or jumps elsewhere. They exist solely so the SAVE at line 40 preserves a tidy, self-documenting listing on tape. - The reference to address 0x4000 in the machine code (`11 D4 00` loads DE with 0x00D4; `ED 53 04 40` stores DE to 0x4004) touches the very start of the display file, suggesting the loader temporarily uses display RAM as workspace. - No stack imbalance or obvious bugs are present; all `E5`/`D5` pushes are matched by corresponding `E1`/`D1` pops. ## Source Code ``` 10 REM \21\92\40\11\F4\7E\01\D4\00\ED\53\04\40\ED\B0\C9\21\80\40\22\7B\40\2A\7B\40\23\7E\FE\EC\28\2D\FE\ED\28\29\FE\76\20\F2\23\7E\FE\76\20\EC\21\7C\40\11\DE\03\23\ED\4B\0C\40\A7\ED\42\C8\09\06\0A\13\10\FD\72\23\73\23\4E\23\46\09\18\E7\23\7E\FE\10\28\C7\23\23\23\23\7E\FE\7E\28\06\2B\2B\2B\2B\18\B9\22\7B\40\2A\1C\40\E5\01\05\00\09\22\1C\40\D1\2A\7B\40\23\ED\B0\CD\A7\0E\21\E8\03\22\EE\7F\11\7D\40\1A\67\13\1A\6F\A7\ED\42\28\21\30\1F\E5\D5\2A\EE\7F\11\0A\00\19\22\EE\7F\D1\E1\13\1A\6F\13\1A\67\19\54\5D\13\2A\0C\40\ED\52\30\D5\ED\4B\EE\7F\CD\20\15\2A\7B\40\23\23\23\EB\2A\1C\40\2B\2B\2B\01\03\00\ED\B8\EF\2A\34\2A\1C\40\01\0A\00\A7\ED\42\ED\5B\7B\40\1B\1B\1B\1B\0E\04\ED\B0\CD\9A\14\C3\FA\7E\3D\3D\3D\3D\3D\24\24\24\24\24\24\24\24\24\24\24\24\24\24 20 RAND USR 16514 30 NEW 40 SAVE "1008%4" 50 LIST 60 REM RAND USR 32500 TO USE ```