--- title: "ROLL OVER" id: 70826 type: "computer_media" slug: "roll-over" url: "http://localhost/computer_media/roll-over/" markdown_url: "http://localhost/computer_media/roll-over.md" published_at: "2026-08-23T15:08:05+00:00" modified_at: "2026-08-23T20:50:56+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/08/roll-over.png" alt: "ROLL OVER screen" excerpt: "A subroutine that copies font bitmaps and cycles color attributes to make text appear to \"roll\" with animated, shifting colors across each character." 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/" genre: - name: "Demo" slug: "demo" taxonomy: "genre" url: "http://localhost/type/demo/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/ROLL%20OVER%20%28198x%29%28-%29%28TS2068%29%28US%29%28Program%29.zip" tsrun_member: "ROLL OVER (198x)(-)(TS2068)(US)(Program).tap" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/08/roll-over.png" alt: "ROLL OVER screen" media_type_tags: "Demo" --- # ROLL OVER ROLL OVER is a text animation routine that creates a “rolling” color-cycling effect on a string of characters printed to the screen. The subroutine at line 9000 first copies character bitmap data from the system font (via the `ch` pointer at address 23606/23607) into the display file area (via the `gr` pointer at address 23675/23676), doubling each row of pixels by writing it twice to consecutive byte pairs. It then animates the string by cycling through PAPER/INK attribute combinations using `CHR$ (142+2*z)` and scrolling the attribute value downward through positions 0–7 in a loop of 10 repetitions. System variables at 23675/23676 (D_FILE) and 23606/23607 (CHARS) are accessed directly via PEEK to locate the display file and character set in memory. *** ### Program Structure The program is short, consisting of a main section (lines 5–30) and a reusable subroutine (lines 9000–9120). The main section sets screen colors, calls the subroutine twice with different strings (`"ROLL OVER"` and `"Try Again"`), then halts. The subroutine is self-contained and driven entirely by the string passed in `x$`. | Lines | Role | | --- | --- | | 5 | Set PAPER 6, BORDER 4 | | 10–20 | Set `x$` and call subroutine | | 30 | STOP | | 9000–9010 | Read system variable pointers for display file and character set | | 9020–9060 | Copy font bitmaps into display file, doubled vertically | | 9070–9110 | Animate by cycling attribute bytes and reprinting string | | 9120 | Restore D_FILE low byte, return | ### System Variable Access The subroutine makes direct use of two Spectrum system variables: - `23675`/`23676` — D_FILE (display file address), read at line 9000 to locate where character cell bitmaps live in memory. - `23606`/`23607` — CHARS (character set base address), read at line 9010 to find the ROM font. Both 16-bit values are assembled from their low and high bytes using the standard `PEEK low + 256 * PEEK high` idiom, storing results in `gr` and `ch` respectively. ### Bitmap Copying with Vertical Doubling Lines 9020–9060 iterate over every character in `x$`. For each character, its ASCII code is obtained with `CODE x$(z+1)`. The eight pixel rows of that character’s font data are read from `ch + (a*8) + n`. Each row byte `v` is written to two consecutive positions in the display file: once at `gr + (16*z) + n` and again at `gr + (16*z) + 8 + n`. This doubles each character row, effectively stretching each glyph to occupy 16 bytes instead of the usual 8 — a simple vertical scaling technique using only PEEK and POKE. ### Color Animation The animation loop (lines 9070–9110) runs 10 repetitions (`r`). Within each repetition, the low byte of D_FILE is temporarily modified via `POKE 23675, n+88` as `n` counts down from 7 to 0, shifting which part of the display file is addressed. Simultaneously, line 9100 rebuilds `x$` by replacing each character with `CHR$ (142 + 2*z)`, generating color attribute control characters that vary per character position. The string is then printed at a fixed screen position with `PRINT AT 10,10;x$`, causing each character to display with a different, cycling PAPER/INK combination. ### Notable Techniques - **D_FILE manipulation:** Temporarily altering the low byte of the display file pointer (`POKE 23675, n+88`) redirects where the system reads display data, creating a scrolling or rolling visual without moving any pixel data. - **Attribute color cycling:** Using `CHR$ (142 + 2*z)` produces embedded color-change escape sequences within a string, allowing per-character attribute control inside a single `PRINT` statement. - **Subroutine reuse:** The same subroutine handles strings of any length because all loops are bounded by `LEN x$`. ### Potential Anomalies Line 9080 sets `POKE 23675, 88+8` (= 96) immediately before the inner loop resets it in steps from 95 down to 88. This initial POKE may be a preparatory state or a minor redundancy, since the inner loop at line 9090 immediately overwrites it. Additionally, line 9100 permanently overwrites the contents of `x$` with control characters on each pass through the outer loop, meaning the original string text is destroyed after the first animation frame. For the demo’s purposes this is harmless since the subroutine returns after the animation, but callers should be aware that `x$` is not preserved. ## Source Code ``` 5 PAPER 6: BORDER 4 10 LET x$="ROLL OVER": GO SUB 9000 20 LET x$="Try Again": GO SUB 9000 30 STOP 9000 LET gr=PEEK 23675+256*PEEK 23676 9010 LET ch=PEEK 23606+256*PEEK 23607 9020 FOR z=0 TO (LEN x$-1): LET a=CODE x$(z+1) 9030 FOR n=0 TO 7: LET v=PEEK (ch+(a*8)+n) 9040 POKE (gr+(16*z)+n),v 9050 POKE (gr+(16*z)+8+n),v 9060 NEXT n: NEXT z 9070 FOR r=1 TO 10 9080 POKE 23675,88+8 9090 FOR n=7 TO 0 STEP -1: POKE 23675,(n+88) 9100 FOR z=1 TO LEN x$: LET x$(z)=CHR$ (142+2*z): NEXT z 9110 PRINT AT 10,10;x$: NEXT n: NEXT r 9120 POKE 23675,88: RETURN ```