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:
- Line 1 — A
REMstatement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes). - Line 2 —
RAND USR 17298transfers 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. - Line 10 —
CLEARwith no argument resets the BASIC stack and clears variables. - Line 20 —
SAVE "1032%2"saves the program to tape. - Line 30 —
RUNre-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). 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. The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code: 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. On a standard 16K machine the REM data begins at address 16514 (0x4082). 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. Throughout the disassembly several well-known ROM entry points appear: A notable feature is the heavy use of absolute addresses in the 0x4400–0x44FF range as a structured data area. Addresses referenced include: 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 separate signed division or normalisation block appears at approximately offset 0x41ED, using Several code sections use Several 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. Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters. No people associated with this content. 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. The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code: 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. On a standard 16K machine the REM data begins at address 16514 (0x4082). 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. Throughout the disassembly several well-known ROM entry points appear: A notable feature is the heavy use of absolute addresses in the 0x4400–0x44FF range as a structured data area. Addresses referenced include: 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 separate signed division or normalisation block appears at approximately offset 0x41ED, using Several code sections use Several 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. Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters. No people associated with this content. 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. The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code: 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. On a standard 16K machine the REM data begins at address 16514 (0x4082). 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. Throughout the disassembly several well-known ROM entry points appear: A notable feature is the heavy use of absolute addresses in the 0x4400–0x44FF range as a structured data area. Addresses referenced include: 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 separate signed division or normalisation block appears at approximately offset 0x41ED, using Several code sections use Several 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. Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters. No people associated with this content.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 (
Skip to content
) decode as:Random Boxes
Program Analysis
Program Structure
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).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.CLEAR with no argument resets the BASIC stack and clears variables.SAVE "1032%2" saves the program to tape.RUN re-executes from line 1 after saving.Machine Code Entry Point
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 HLCD 2B 0F — CALL 0x0F2B (a ROM routine)ROM Calls and RST Usage
Address Likely ROM routine 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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
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
06 10) iterates once per bit.ADD HL,HL and RL C / RL A.ADD HL,DE accumulates partial products.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
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
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)Notable Techniques
RAND USR jumps directly into it, bypassing any BASIC interpreter overhead.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.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.2A 00 07 00 1E 00 ...) are clearly a data table rather than code, used as parameters for the routines above.Anomalies and Observations
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.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.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.Content
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 People
Random Boxes
Program Analysis
Program Structure
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).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.CLEAR with no argument resets the BASIC stack and clears variables.SAVE "1032%2" saves the program to tape.RUN re-executes from line 1 after saving.Machine Code Entry Point
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 HLCD 2B 0F — CALL 0x0F2B (a ROM routine)ROM Calls and RST Usage
Address Likely ROM routine 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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
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
06 10) iterates once per bit.ADD HL,HL and RL C / RL A.ADD HL,DE accumulates partial products.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
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
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)Notable Techniques
RAND USR jumps directly into it, bypassing any BASIC interpreter overhead.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.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.2A 00 07 00 1E 00 ...) are clearly a data table rather than code, used as parameters for the routines above.Anomalies and Observations
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.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.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.Content
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 People
Random Boxes
Program Analysis
Program Structure
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).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.CLEAR with no argument resets the BASIC stack and clears variables.SAVE "1032%2" saves the program to tape.RUN re-executes from line 1 after saving.Machine Code Entry Point
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 HLCD 2B 0F — CALL 0x0F2B (a ROM routine)ROM Calls and RST Usage
Address Likely ROM routine 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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
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
06 10) iterates once per bit.ADD HL,HL and RL C / RL A.ADD HL,DE accumulates partial products.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
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
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)Notable Techniques
RAND USR jumps directly into it, bypassing any BASIC interpreter overhead.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.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.2A 00 07 00 1E 00 ...) are clearly a data table rather than code, used as parameters for the routines above.Anomalies and Observations
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.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.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.Content
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 People
2A 39 40—LD HL,(0x4039)E5—PUSH HLCD 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 by32 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 withLD HL,(...)/LD (...),HLpairs, 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,HLandRL C/RL A. - Conditional
ADD HL,DEaccumulates 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 USRjumps 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)/E9instructions 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
CLEARat 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
SAVEfilename"1032%2"uses the%2escape for inverse video of ‘2’, which on tape gives a distinctive visual name but does not affect the saved bytes. - The
RUNat 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.
Content
Source Code
1 REM
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\E5\CD
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\CD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"F
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
AE\D7A\CB
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
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
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E\E5\CD\E1\FE\E7\FD\CB
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\FE\FE\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"C\E4\FE\E0\D7\DD
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\E6
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\C6
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
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-56854 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.6 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.4"E
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E\D7\CBE\D7\CD\B3\E1\D5\E5\CD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"F
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C1\CD\E1\A7\C9\FE\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"C\AE\FE
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\AA\D7\D6 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"CF
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\EB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"E\D9\EB\FD\CBE\C0\CBC\C8\E1\E1\C9
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
BE\FE
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\F7\E5\D6 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"CF
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\EB\E1E\FE\FEE\E5\D5\E1
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\CD\F8\EB\E1\D3\B9\C8\A7\ED\ED\EB\A7\C9\CB\BC\D1\C9
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
AB\F5\CD
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\CD\A7
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CF\FF\FE\F4\F1\CB\C0\C3
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
FD\C3
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
FD\C3\F5D itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\C3
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\C5CD
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"\F7\C1\C9
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
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-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
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
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
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
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\AA\E6\D5\CD\ED\E3\CD\ED\EB\E1\A7\B1\E5\ED\ED\E5\C1\D1
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\F5A itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"EF\EDA\EDA\EDDC itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"D\ECF\F1\E2\CBF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"\EB\CBF\C8
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\CDF\CB\D0C\D0\EB\A7\ED\ED\C9C\B5\C8 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\C9\FF\FF\C9\A7\ED\C9\A7\EDC\B5
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\C0
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\C9\A7\ED\C8\E3\EB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\EB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"C\A8A\A8\ED
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\D8\EE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"F\C9C\B5
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\C8A\B3\C8
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\C9C\B5\B2\ED\F5E itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"\AF\E3E\E3
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\A7\EB\E1\E3\EB\C9E\EB\C9\EB\CDB\EB\C9\D5B
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\EDB\CD\E5\CD\C1C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"D itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"F
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\C3C
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\CB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"A\CBF
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\CBCE\D7\CD\F0 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"\F0\D8 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"E\FF\C5\CD\E1\CD\AD
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\E5\C1D itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"E itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"C\CBA itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"\EDF\D7\EDF\D7\CBA\CB\FA\EF\C9\E1E\FE
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\FE\D7\F3\CD\EE
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EB\D5\E5\CD\B2
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\E1\D1\C9\CD
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
CC\B5\E3E\E3\C0\E1\EB\E9D\E6 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"FF\FD\CB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"E
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\FD\CB\FF\C6C\D4\FD\FEAA\DE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"\CD\FA\FD\CB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"\C6\C9\E1E\E5\D5
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
BE
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\D5\F9\E1\C1\D1A\EB\E1\E3\C5\E1 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"\EB\CD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"B\E1\D8\C1\E9\EB\C9\C1\E5\C1\C9E
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\C9\DAF\D5\E5\C9\C5\E1\C9\EB\CDF\EB\C9\CDF\FB\CDF\FB\D5\CD\BB
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\E5\C1
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
CC\CD\BDE
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\D1\C9
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CDB\CD\C7
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CDB\CDA\C9 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C9\CD\CD\FD\C4
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
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
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CDB\CD\C9
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C9\CD\EB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CD\E5
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C7\CD\EB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CD\D1\CD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CB
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C7\CD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"\D1\CD\D2\CD
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\CB
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C7\CD\EB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CD\CD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CB
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C9\CD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CF\D1
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C7\CD\EB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CD\CD\CD\D2 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\D3
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C7\CD\D5 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\D7C\D9
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C9\CD\CD
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\D3\CD\D2\CD
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\CB
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C7\CD\EB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CD\CD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CB
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C7\CD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CF\AC\D1\CD\D2\CD
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\CB\CDF\CD
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\CD\FD\C4\CDE\C3
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
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
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
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-56854 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.6 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.4"E
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
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
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
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-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
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-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
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-56854 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.6 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.4"
Skip to content
Random Boxes
This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
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:
- Line 1 — A
REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
- 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.
- Line 10 —
CLEAR with no argument resets the BASIC stack and clears variables.
- Line 20 —
SAVE "1032%2" saves the program to tape.
- 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 0x0F2BEvaluate expression / FP stack 0x0F23Related arithmetic entry 0x0A1FPrint character / output 0x0918Display / print routine 0x0BBDCassette 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C
2 RAND USR 17298
10 CLEAR
20 SAVE "1032%2"
30 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

