This program is a machine code loader and launcher that prints random sized boxes with random character fills.. The BASIC program uses a single `RAND USR 17298` call at line 2 to transfer execution into the machine code embedded in the REM, which begins at address 16514 (the first byte after the REM token and length bytes on a 16K machine). The REM data is substantial — several hundred bytes of Z80 opcodes — and handles all primary logic including what appear to be floating-point arithmetic routines, display output via RST instructions, and structured data tables stored at fixed addresses in the 0x4400 region. Lines 10–30 provide a simple BASIC wrapper: clearing memory, saving the program under the name “1032%2”, then restarting with RUN.
Program Analysis
Program Structure
The BASIC listing is intentionally minimal, serving only as a vehicle to store and launch Z80 machine code:
- Line 1 — A
REMstatement containing the entire machine code payload (several hundred bytes of raw Z80 opcodes). - Line 2 —
RAND USR 17298transfers execution to the machine code. Address 17298 decimal is 0x4392, which falls well into the REM body, suggesting the code self-relocates or that the REM begins at the standard address 0x4009 and the entry point is offset accordingly. - Line 10 —
CLEARwith no argument resets the BASIC stack and clears variables. - Line 20 —
SAVE "1032%2"saves the program to tape. - Line 30 —
RUNre-executes from line 1 after saving.
The flow implies the program is intended to be loaded, auto-saved under the given name, and then run. Lines 10–30 act as a distribution/duplication wrapper rather than core program logic.
Machine Code Entry Point
On a standard 16K machine the REM data begins at address 16514 (0x4082). RAND USR 17298 (0x4392) therefore enters the code at a byte offset of 784 into the REM block, past the initial setup routines. The first bytes of the REM (\2A\39\40\E5\CD\2B\0F) decode as:
2A 39 40—LD HL,(0x4039)E5—PUSH HLCD 2B 0F—CALL 0x0F2B(a ROM routine)
This suggests the very start of the REM block (reachable via a different entry or self-modifying jump) begins by reading a word from address 0x4039 and calling into the ROM, consistent with floating-point or channel setup.
ROM Calls and RST Usage
Throughout the disassembly several well-known ROM entry points appear:
| Address | Likely ROM routine |
|---|---|
0x0F2B | Evaluate expression / FP stack |
0x0F23 | Related arithmetic entry |
0x0A1F | Print character / output |
0x0918 | Display / print routine |
0x0BBD | Cassette or I/O routine |
RST instructions appear as D7 (RST 0x10 — print character to current channel) and CF (RST 0x08 — error handler), which are standard Spectrum/TS2068 ROM fast-call idioms used to minimise code size.
Fixed Memory Map at 0x4400
A notable feature is the heavy use of absolute addresses in the 0x4400–0x44FF range as a structured data area. Addresses referenced include:
0x4421/0x4439/0x443A/0x443B— flag bytes and counters read and written throughout the code.0x441E— a single byte used as a direction or mode flag (modified by32 1E 40=LD (0x401E),A).0x44C7,0x44C9,0x44CB,0x44CD,0x44CF,0x44D1,0x44D3,0x44D5,0x44D7,0x44D9— a tightly packed array of 16-bit words, each loaded/stored withLD HL,(...)/LD (...),HLpairs, suggesting a table of coordinates or vector components.0x445D— used as a base pointer in one display loop.
Arithmetic and Multiply Routines
The REM block contains what appears to be a custom 16-bit multiply routine starting near offset 0x41C5. It uses the classic shift-and-add pattern:
- A loop counter of 16 (
06 10) iterates once per bit. - Double-length left shifts are performed with
ADD HL,HLandRL C/RL A. - Conditional
ADD HL,DEaccumulates partial products.
A separate signed division or normalisation block appears at approximately offset 0x41ED, using ED 52 (SBC HL,DE) and ED 62 (NEG equivalent on HL) with carry checks, typical of fixed-point scaling code used in line-drawing or 3D projection.
Display and Graphics Handling
Several code sections use D7 (RST 16) to stream character codes to the display, including control codes 0x12 (AT), 0x16 (INK/PAPER attribute tokens), and 0x13 (TAB). The sequence 3E 12 D7 (LD A,18 / RST 16) appears more than once, consistent with positioning the print cursor via AT row/column pairs. A loop at one location outputs a sequence of block graphic characters from a table, building a sprite or border directly through the channel output system rather than direct screen memory writes.
FD CB (IY-bit) Instructions
Several FD CB prefix instructions appear, operating on bits of (IY+offset). For example:
FD CB 21 46—BIT 0,(IY+33)— tests a system flag.FD CB 21 4E—BIT 1,(IY+33)FD CB 01 4E—BIT 1,(IY+1)FD CB 01 C6—SET 0,(IY+1)
These are accessing the system variables area via the IY register (which the ROM keeps pointing to 0x5C3A on the Spectrum/TS2068), specifically flags related to input mode and key state.
Notable Techniques
- REM as code store: The entire executable lives in the REM at line 1;
RAND USRjumps directly into it, bypassing any BASIC interpreter overhead. - EX (SP),HL tricks:
E3(EX (SP),HL) appears multiple times to swap HL with the top of stack, a compact way to pass or return values without dedicated registers. - Self-modifying or table-driven dispatch: Several
JP (HL)/E9instructions at the ends of routines use a pointer loaded from the data table at 0x4400, providing an indirect jump dispatch mechanism. - Inline data tables: The final bytes of the REM (
2A 00 07 00 1E 00 ...) are clearly a data table rather than code, used as parameters for the routines above.
Anomalies and Observations
- The
CLEARat line 10 has no address argument; this clears variables but does not set a new RAMTOP, which means it does not protect the machine code sitting in the REM from being overwritten by BASIC — the machine code must have already finished and returned to BASIC by this point. - The
SAVEfilename"1032%2"uses the%2escape for inverse video of ‘2’, which on tape gives a distinctive visual name but does not affect the saved bytes. - The
RUNat line 30 after saving will re-enter line 1 and immediately jump back into machine code via line 2, causing any post-save logic to loop.
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.
