--- title: "Super Marbles" id: 63197 type: "computer_media" slug: "super-marbles" url: "http://localhost/computer_media/super-marbles/" markdown_url: "http://localhost/computer_media/super-marbles.md" published_at: "2026-01-30T21:13:39+00:00" modified_at: "2026-04-03T07:57:56+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "A BASIC loader for a machine code marble game, with built-in screen save/load utilities and a clever self-locating bootstrap sequence." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "Eric Boisvert" slug: "boisvert-eric" taxonomy: "indiv" url: "http://localhost/indiv/boisvert-eric/" - name: "Kristian Boisvert" slug: "boisvert-kristian" taxonomy: "indiv" url: "http://localhost/indiv/boisvert-kristian/" - name: "Michael Kemper" slug: "michael-kemper" taxonomy: "indiv" url: "http://localhost/indiv/michael-kemper/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 63048 title: "Byte Power February 1987" type: "computer_media" url: "http://localhost/computer_media/byte-power-february-1987/" media_type: "Program" programmers: - name: "Eric Boisvert" slug: "boisvert-eric" taxonomy: "indiv" url: "http://localhost/indiv/boisvert-eric/" - name: "Kristian Boisvert" slug: "boisvert-kristian" taxonomy: "indiv" url: "http://localhost/indiv/boisvert-kristian/" - name: "Michael Kemper" slug: "michael-kemper" taxonomy: "indiv" url: "http://localhost/indiv/michael-kemper/" mediadate: "1987" producer_company: - id: 25181 title: "Byte Power" type: "company" url: "http://localhost/company/byte-power/" images: - url: "http://localhost/wp-content/uploads/2026/01/super-marbles.png" media_type_tags: "Game" --- Super Marbles is a game loader and screen-save/load utility that uses machine code routines stored at address 37900 and above. The BASIC stub at line 30 jumps to a machine code entry point via RANDOMIZE USR 37900, while line 9010 locates and executes a second routine by reading the BASIC program’s own start address from system variables at 23627–23628, adding 6 bytes for the line header. Screen data (14080 bytes from address 50400, covering the Spectrum’s display file and attributes) can be saved and loaded by name using the SUBroutine at line 2000. The bootstrap at line 9999 saves both the BASIC loader (autostarting at line 9000) and the machine code block in a single sequence, followed by two VERIFY passes to confirm integrity. *** ## Program Structure The program is divided into several functional regions: 1. **Lines 10–40:** Main entry point and dispatcher. Reads `PEEK 23681` to decide which routine to jump to, or falls through to machine code via `RANDOMIZE USR 37900`. 2. **Lines 100–145:** Screen save routine — prompts for a filename, saves 14080 bytes from address 50400, verifies, then re-enters machine code. 3. **Lines 150–160:** Screen load routine — prompts for a filename and loads the screen data back to address 50400. 4. **Line 255–260:** Quit handler — issues `CLEAR 65535` and `NEW`. 5. **Lines 2000–2020:** Shared filename input subroutine with a length guard (max 10 characters). 6. **Lines 9000–9020:** Tape loader — sets black border/paper/ink, self-locates, executes a machine code initialiser, then loads the main code block and restarts. 7. **Line 9999:** Bootstrap saver — writes both the BASIC file (autostart line 9000) and the machine code block, then verifies both. ## Machine Code Integration Three distinct `RANDOMIZE USR` calls are used to invoke machine code: | Address | Context | Purpose | | --- | --- | --- | | 37900 | Line 30 | Main game entry point after normal boot | | 45181 | Line 140 | Called after screen save/load to return to game | | Computed | Line 9010 | Self-located initialiser within the BASIC program area | The self-locating technique at line 9010 is notable: `LET a=6+PEEK 23627+256*PEEK 23628` reads system variables `PROG` (23627–23628), which holds the start address of the BASIC program, then adds 6 to skip past the line number (2 bytes), line length (2 bytes), and REM token plus space (2 bytes) to reach embedded machine code stored inside a `REM` statement at the very first line of the program when loaded from tape. ## System Variable Usage `PEEK 23681` is used twice (lines 40 and 145) as a dispatch value. Address 23681 is `RASP`/the printer buffer area — its use here as a state variable to control program flow is an unconventional but functional technique, avoiding the need to maintain a separate BASIC variable across `CLS` or machine code calls that might corrupt memory. ## Screen Data Handling The save/load routines target address 50400 for 14080 bytes. The standard Spectrum display file starts at 16384 and is 6912 bytes; 50400 is well above the normal screen area, suggesting the machine code copies or manages an off-screen display buffer at this address. 14080 bytes is slightly larger than two full Spectrum screens (2 × 6912 = 13824), indicating possibly compressed or extended screen data including additional game state. ## Bootstrap and Distribution (Line 9999) Line 9999 packages the game for tape distribution in one command sequence: - `SAVE "MARBLES" LINE 9000` — saves the BASIC program with autostart at the loader (line 9000) - `SAVE "MARBLES"CODE 37900,27635` — saves 27635 bytes of machine code starting at 37900 - `VERIFY ""` and `VERIFY ""CODE` — verifies both blocks immediately The machine code block of 27635 bytes is substantial, running from 37900 to approximately 65535, filling almost the entire upper half of the 64 KB address space. ## Protection and Integrity Check Lines 20–30 implement a simple integrity guard: if `PEEK 23681` is zero (i.e., the program has been `RUN` directly rather than loaded via the tape loader), it resets the font pointer system variables (23606–23607 to 0 and 60, giving address 15360), sets a neutral display state, and prints a warning not to use `CLEAR`, directing the user to `GO TO 9999` instead. This protects the machine code which would be destroyed by an inadvertent `CLEAR` below 37900. ## Notable BASIC Idioms - `INPUT "FILE NAME:"; LINE a$` — uses `LINE` to accept the full input as a string without quote-stripping. - `PRINT #1;AT 0,0;` — writes to the lower screen (stream 1) to display the rewind tape prompt without disturbing the main screen. - `CLEAR 65535` in the quit handler sets RAMTOP to the top of RAM, which effectively reclaims all memory before `NEW` resets the interpreter. ## Source Code ``` 10 REM SUPER MARBLES 20 IF PEEK 23681=0 THEN POKE 23606,0: POKE 23607,60: BORDER 7: INK 0: PAPER 7: CLS : LIST 9999: PRINT ''"DO NOT USE CLEAR..."''"JUST GOTO 9999": STOP 30 PRINT AT 0,0;: RANDOMIZE USR 37900 40 CLS : GO TO PEEK 23681 100 REM SAVE SCREENS 110 GO SUB 2000 120 IF a$="" THEN GO TO 110 130 SAVE a$CODE 50400,14080 135 PRINT #1;AT 0,0;"REWIND TAPE TO VERIFY": PRINT AT 20,0;: VERIFY A$CODE 50400 140 CLS : PRINT AT 0,0;: RANDOMIZE USR 45181 145 CLS : GO TO PEEK 23681 150 REM LOAD SCREENS 160 GO SUB 2000: LOAD A$CODE 50400: GO TO 140 255 REM QUIT 260 CLEAR 65535: NEW 2000 REM get string 2010 INPUT "FILE NAME:"; LINE a$: IF LEN a$>10 THEN GO TO 2010 2020 RETURN 9000 REM LOADER 9010 BORDER 0: PAPER 0: INK 0: CLS : LET a=6+PEEK 23627+256*PEEK 23628: RANDOMIZE USR a 9020 LOAD "MARBLES"CODE : OVER 0: GO TO 10 9999 SAVE "MARBLES" LINE 9000: SAVE "MARBLES"CODE 37900,27635: VERIFY "": VERIFY ""CODE ```