--- title: "Random Boxes" id: 56854 type: "computer_media" slug: "random-boxes" url: "http://localhost/computer_media/random-boxes/" markdown_url: "http://localhost/computer_media/random-boxes.md" published_at: "2024-09-29T07:47:59+00:00" modified_at: "2026-03-30T21:20:44+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/09/322_Unk.png" excerpt: "Machine language program that prints random sized boxes with random character fills." 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: "Demo" slug: "demo" taxonomy: "genre" url: "http://localhost/type/demo/" media_contents: - id: 56738 title: "Timex Sinclair Public Domain Library Tape 1007" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1007/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/09/322_Unk.png" media_type_tags: "Demo" --- This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN. *** ## Program Analysis ### Program Structure The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code: 1. **Line 1** — A `REM` statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes). 2. **Line 2** — `RAND USR 17298` transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly. 3. **Line 10** — `CLEAR` with no argument resets the BASIC stack and clears variables. 4. **Line 20** — `SAVE "1032%2"` saves the program to tape. 5. **Line 30** — `RUN` re-executes from line 1 after saving. The flow implies the program is intended to be loaded, auto-saved under the given name, and then run. Lines 10–30 act as a distribution/duplication wrapper rather than core program logic. ### Machine Code Entry Point On a standard 16K machine the REM data begins at address 16514 (0x4082). `RAND USR 17298` (0x4392) therefore enters the code at a byte offset of 784 into the REM block, past the initial setup routines. The first bytes of the REM (`\2A\39\40\E5\CD\2B\0F`) decode as: - `2A 39 40` — `LD HL,(0x4039)` - `E5` — `PUSH HL` - `CD 2B 0F` — `CALL 0x0F2B` (a ROM routine) This suggests the very start of the REM block (reachable via a different entry or self-modifying jump) begins by reading a word from address 0x4039 and calling into the ROM, consistent with floating-point or channel setup. ### ROM Calls and RST Usage Throughout the disassembly several well-known ROM entry points appear: | Address | Likely ROM routine | | --- | --- | | `0x0F2B` | Evaluate expression / FP stack | | `0x0F23` | Related arithmetic entry | | `0x0A1F` | Print character / output | | `0x0918` | Display / print routine | | `0x0BBD` | Cassette or I/O routine | `RST` instructions appear as `D7` (RST 0x10 — print character to current channel) and `CF` (RST 0x08 — error handler), which are standard Spectrum/TS2068 ROM fast-call idioms used to minimise code size. ### Fixed Memory Map at 0x4400 A notable feature is the heavy use of absolute addresses in the 0x4400–0x44FF range as a structured data area. Addresses referenced include: - `0x4421` / `0x4439` / `0x443A` / `0x443B` — flag bytes and counters read and written throughout the code. - `0x441E` — a single byte used as a direction or mode flag (modified by `32 1E 40` = `LD (0x401E),A`). - `0x44C7`, `0x44C9`, `0x44CB`, `0x44CD`, `0x44CF`, `0x44D1`, `0x44D3`, `0x44D5`, `0x44D7`, `0x44D9` — a tightly packed array of 16-bit words, each loaded/stored with `LD HL,(...)` / `LD (...),HL` pairs, suggesting a table of coordinates or vector components. - `0x445D` — used as a base pointer in one display loop. ### Arithmetic and Multiply Routines The REM block contains what appears to be a custom 16-bit multiply routine starting near offset 0x41C5. It uses the classic shift-and-add pattern: - A loop counter of 16 (`06 10`) iterates once per bit. - Double-length left shifts are performed with `ADD HL,HL` and `RL C` / `RL A`. - Conditional `ADD HL,DE` accumulates partial products. A separate signed division or normalisation block appears at approximately offset 0x41ED, using `ED 52` (`SBC HL,DE`) and `ED 62` (`NEG` equivalent on HL) with carry checks, typical of fixed-point scaling code used in line-drawing or 3D projection. ### Display and Graphics Handling Several code sections use `D7` (RST 16) to stream character codes to the display, including control codes 0x12 (AT), 0x16 (INK/PAPER attribute tokens), and 0x13 (TAB). The sequence `3E 12 D7` (`LD A,18 / RST 16`) appears more than once, consistent with positioning the print cursor via AT row/column pairs. A loop at one location outputs a sequence of block graphic characters from a table, building a sprite or border directly through the channel output system rather than direct screen memory writes. ### FD CB (IY-bit) Instructions Several `FD CB` prefix instructions appear, operating on bits of `(IY+offset)`. For example: - `FD CB 21 46` — `BIT 0,(IY+33)` — tests a system flag. - `FD CB 21 4E` — `BIT 1,(IY+33)` - `FD CB 01 4E` — `BIT 1,(IY+1)` - `FD CB 01 C6` — `SET 0,(IY+1)` These are accessing the system variables area via the IY register (which the ROM keeps pointing to 0x5C3A on the Spectrum/TS2068), specifically flags related to input mode and key state. ### Notable Techniques - **REM as code store:** The entire executable lives in the REM at line 1; `RAND USR` jumps directly into it, bypassing any BASIC interpreter overhead. - **EX (SP),HL tricks:**`E3` (`EX (SP),HL`) appears multiple times to swap HL with the top of stack, a compact way to pass or return values without dedicated registers. - **Self-modifying or table-driven dispatch:** Several `JP (HL)` / `E9` instructions at the ends of routines use a pointer loaded from the data table at 0x4400, providing an indirect jump dispatch mechanism. - **Inline data tables:** The final bytes of the REM (`2A 00 07 00 1E 00 ...`) are clearly a data table rather than code, used as parameters for the routines above. ### Anomalies and Observations - The `CLEAR` at line 10 has no address argument; this clears variables but does not set a new RAMTOP, which means it does not protect the machine code sitting in the REM from being overwritten by BASIC — the machine code must have already finished and returned to BASIC by this point. - The `SAVE` filename `"1032%2"` uses the `%2` escape for inverse video of ‘2’, which on tape gives a distinctive visual name but does not affect the saved bytes. - The `RUN` at line 30 after saving will re-enter line 1 and immediately jump back into machine code via line 2, causing any post-save logic to loop. ## Source Code ``` 1 REM \2A\39\40\E5\CD\2B\0F\CD\1F\0A\3E\12\D7\3A\21\40\CB\47\20\26\2A\0E\40\E5\CD\75\43\E1\FE\77\28\E7\FD\CB\21\46\00\20\3A\FE\76\28\21\FE\16\28\08\FE\1C\38\E4\FE\26\30\E0\D7\18\DD\07\07\2F\E6\02\C6\02\32\1E\40\21\00\00\3E\12\D7\18\CB\3E\13\D7\CD\10\41\38\B3\E1\D5\E5\CD\1F\0A\C1\CD\18\09\E1\A7\C9\FE\76\28\26\FE\1C\38\AE\FE\2C\30\AA\D7\D6\1C\5F\16\00\19\EB\21\1E\40\35\28\D9\EB\29\29\29\29\18\95\FD\CB\21\4E\C0\CB\7C\C8\E1\E1\37\C9\11\00\00\4B\7E\FE\16\20\04\23\0C\18\F7\E5\D6\1C\6F\26\00\19\EB\E1\23\7E\FE\13\28\15\FE\7E\28\11\E5\D5\E1\06\09\19\2B\CD\04\41\23\10\F8\EB\E1\18\D3\97\B9\C8\A7\ED\62\ED\52\EB\A7\C9\22\32\40\CB\BC\D1\C9\00\3A\3B\40\F5\CD\2B\0F\CD\75\43\A7\20\02\CF\FF\FE\28\20\F4\F1\CB\77\C0\C3\23\0F\44\4D\C3\35\0F\43\4D\C3\F5\08\7D\01\00\00\C3\75\0B\C5\06\10\7C\4D\21\00\00\29\CB\11\17\30\01\19\10\F7\C1\C9\00\01\18\06\0E\02\18\02\0E\00\7C\AA\E6\80\47\D5\CD\ED\41\E3\CD\ED\41\EB\E1\79\A7\28\36\78\B1\E5\ED\62\ED\52\E5\C1\D1\21\00\00\37\3F\F5\7A\53\1E\08\29\30\05\8F\ED\4A\18\09\87\ED\4A\38\03\ED\42\3D\3C\1D\20\EC\5F\F1\30\E2\CB\4F\20\01\EB\CB\7F\C8\18\0B\CD\7F\41\CB\10\D0\18\03\7C\07\D0\EB\A7\ED\62\ED\52\C9\7C\07\38\06\B5\C8\21\01\00\C9\21\FF\FF\C9\A7\ED\52\C9\A7\ED\52\7C\B5\21\00\00\C0\2C\C9\A7\ED\52\C8\18\E3\EB\01\00\80\18\04\EB\01\01\80\7C\A8\67\7A\A8\57\ED\52\26\00\79\6F\D8\EE\01\6F\C9\7C\B5\21\00\00\C8\7A\B3\C8\2C\C9\7C\B5\B2\ED\62\18\F5\3E\01\18\01\AF\E3\5E\23\56\23\E3\2B\29\19\A7\28\08\EB\E1\E3\EB\73\23\72\C9\5E\23\56\EB\C9\EB\CD\6B\42\EB\C9\D5\11\4B\00\ED\4B\32\40\03\62\68\CD\09\13\E5\62\69\CD\09\13\C1\7C\81\30\01\04\67\7D\90\30\01\25\6F\2B\C3\4C\41\00\00\3A\21\40\CB\47\20\1A\CB\4F\20\0A\CB\7C\28\06\3E\16\D7\CD\F0\41\01\F0\D8\1E\FF\C5\CD\E1\07\CD\AD\0A\E5\C1\21\5D\40\57\1E\1C\70\CB\7A\28\01\71\97\ED\6F\83\D7\97\ED\6F\83\D7\CB\7A\CB\FA\28\EF\C9\E1\7E\23\FE\70\28\2F\FE\76\20\03\D7\18\F3\CD\79\41\18\EE\97\18\02\3E\90\4B\45\21\30\40\56\77\D5\E5\CD\B2\0B\E1\D1\72\C9\CD\0C\42\7C\B5\E3\5E\23\56\23\E3\C0\E1\EB\E9\7D\E6\1F\4F\FD\CB\01\4E\28\0A\FD\96\38\CB\FF\C6\3C\D4\71\08\FD\86\39\FE\21\3A\3A\40\DE\01\CD\FA\08\FD\CB\01\C6\C9\E1\5E\23\56\23\E5\D5\21\07\00\19\06\04\56\2B\5E\2B\D5\10\F9\E1\C1\D1\7A\19\EB\E1\E3\73\23\72\C5\E1\07\30\01\EB\CD\1B\42\E1\D8\C1\E9\EB\73\C9\C1\E5\C1\C9\6E\26\00\C9\11\DA\7F\D5\E5\C9\C5\E1\C9\EB\CD\7F\43\EB\C9\CD\7F\43\38\FB\CD\7F\43\30\FB\D5\CD\BB\02\E5\C1\2C\6C\28\04\CD\BD\07\6E\26\00\7D\D1\C9\11\36\00\CD\6B\42\CD\96\41\22\C7\44\11\16\00\CD\6B\42\CD\9A\41\22\C9\44\11\01\00\2A\C9\44\CD\20\42\CD\FD\42\C4\43\11\0A\00\CD\6B\42\CD\96\41\22\C9\44\11\02\00\2A\C9\44\CD\92\41\EB\21\01\00\CD\05\42\E5\11\02\00\2A\C7\44\CD\92\41\EB\21\01\00\CD\05\42\D1\CD\73\41\21\01\00\22\CB\44\2A\C7\44\22\CD\44\21\01\00\22\CF\44\21\01\44\22\D1\44\CD\D2\42\80\70\CD\2F\43\CB\44\11\02\00\2A\C7\44\CD\92\41\EB\21\01\00\CD\05\42\CD\09\43\21\01\00\22\CB\44\2A\C9\44\22\CD\44\21\01\00\22\CF\44\21\36\44\22\D1\44\11\02\00\2A\C7\44\CD\92\41\EB\21\01\00\CD\05\42\CD\09\43\CD\D2\42\80\70\21\01\00\22\D3\44\11\02\00\2A\C7\44\CD\05\42\22\D5\44\21\01\00\22\D7\44\21\6C\44\22\D9\44\2A\C9\44\CD\78\41\CD\2F\43\D3\44\CD\D2\42\80\70\CD\2F\43\CB\44\11\02\00\2A\C7\44\CD\92\41\EB\21\01\00\CD\05\42\CD\09\43\21\01\00\22\CB\44\2A\C7\44\22\CD\44\21\01\00\22\CF\44\21\AC\44\22\D1\44\CD\D2\42\80\70\CD\2F\43\CB\44\CD\7F\43\CD\0C\42\CD\FD\42\C4\44\CD\5E\43\C3\92\43\2A\00\07\00\1E\00\2A\00\01\00\01\44\06\00\05\00\01\00\6C\44 2 RAND USR 17298 10 CLEAR 20 SAVE "1032%2" 30 RUN ```