Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 (

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
A\E5\CD

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
B

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
F
) decode as:

  • 2A 39 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

Source Code

   1 REM 



Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
A\E5\CD

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
B

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
AE\D7A\CB

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
A

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
E\E5\CD\E1\FE\E7\FD\CB

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
F\E6

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\C6

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
BE\FE

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\EB\E1E\FE\FEE\E5\D5\E1

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
B\CD\F8\EB\E1\D3\B9\C8\A7\ED\ED\EB\A7\C9\CB\BC\D1\C9

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
AB\F5\CD

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
B

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
F\CD\A7

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\CF\FF\FE\F4\F1\CB\C0\C3

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
FD\C3

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\C3

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
B\C5CD

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
E

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
E

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
C\AA\E6\D5\CD\ED\E3\CD\ED\EB\E1\A7\B1\E5\ED\ED\E5\C1\D1

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\C9\FF\FF\C9\A7\ED\C9\A7\EDC\B5

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\C0

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\C8A\B3\C8

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
B\A7\EB\E1\E3\EB\C9E\EB\C9\EB\CDB\EB\C9\D5B

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
B\C3C

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
F\FE\D7\F3\CD\EE

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
EB\D5\E5\CD\B2

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
B\E1\D1\C9\CD

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
BE

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\C9\DAF\D5\E5\C9\C5\E1\C9\EB\CDF\EB\C9\CDF\FB\CDF\FB\D5\CD\BB

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\E5\C1

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
CC\CD\BDE

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
D\D1\C9

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\CDB\CD\C7

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
A\C9\CD\CD\FD\C4

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
A

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\CDB\CD\C9

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\CD\E5

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\CB

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
F\CB

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\CB

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\CF\D1

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\D3

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\D7C\D9

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
A\C9\CD\CD

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
F\D3\CD\D2\CD

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
F\CB

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\CB

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
\CF\AC\D1\CD\D2\CD

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
F\CB\CDF\CD

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
C\CD\FD\C4\CDE\C3

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
A

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
A

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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"

Random Boxes

This file is part of and Timex Sinclair Public Domain Library Tape 1007. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Demo

This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.


Program Analysis

Program Structure

The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:

  1. Line 1 — A REM statement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes).
  2. Line 2RAND USR 17298 transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly.
  3. Line 10CLEAR with no argument resets the BASIC stack and clears variables.
  4. Line 20SAVE "1032%2" saves the program to tape.
  5. Line 30RUN 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 40LD HL,(0x4039)
  • E5PUSH HL
  • CD 2B 0FCALL 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:

AddressLikely 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 46BIT 0,(IY+33) — tests a system flag.
  • FD CB 21 4EBIT 1,(IY+33)
  • FD CB 01 4EBIT 1,(IY+1)
  • FD CB 01 C6SET 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Random Boxes

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.

Scroll to Top
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.

People

No people associated with this content.

Scroll to Top