Scroll demonstrates a horizontal bit-shifting scroll technique for screen text using two short machine code routines loaded into RAM starting at address 32000. The first routine (loaded via POKEs from DATA statements) performs a right-to-left pixel scroll across the display, while the second performs the reverse direction. Each routine uses Z80 instructions including RLC/RRC operations on 16-bit register pairs to shift pixel data across the 32-column, 22-row display area. The BASIC driver fills the screen with a repeating text string, then calls each machine code routine 128 times (8×16 iterations) to animate a full character-width scroll in each direction. The program saves both the BASIC loader and the machine code block as separate files.
Program Analysis
Program Structure
The program is organized into four logical phases:
- Initialization (lines 5–10): Clears the screen and reserves memory below address 32000 with
CLEAR 31999, protecting the machine code area from BASIC. - Machine code loader (lines 20–60): Reads bytes from
DATAstatements and POKEs them into memory starting at address 32000, using a sentinel value of 9999 to terminate the loop. - Screen setup (line 100): Fills all 22 lines with the string
LIST SINCLAIR TIMEX GROUP L.I.NY(truncated to 32 characters per line). - Scroll animation (lines 105–130): Calls each machine code routine 128 times (8 pixels × 16 characters) to scroll right then left across the full display before halting.
Machine Code Routines
Two routines are packed into 38 bytes starting at address 32000. Their Z80 disassembly can be reconstructed from the DATA values:
| Address | Bytes | Mnemonic | Purpose |
|---|---|---|---|
| 32000 | 21 FF 57 | LD HL, 57FFh | Point HL to end of display file area |
| 32003 | 0E 20 | LD C, 32 | Load column counter (32 columns) |
| 32005 | A7 | AND A | Clear carry flag |
| 32006 | CB 16 | RL (HL) | Rotate left through carry |
| 32008 | 2B | DEC HL | Move to previous byte |
| 32009 | 0D | DEC C | Decrement column counter |
| 32010 | 20 FA | JR NZ, -6 | Loop over 32 columns |
| 32012 | 3E 3F | LD A, 63 | Load row-end comparison value |
| 32014 | BC | CP H | Check if H has reached top of display |
| 32015 | 20 F2 | JR NZ, -14 | Loop over all rows |
| 32017 | C9 | RET | Return to BASIC |
| 32018 | 00 00 | NOP / padding | Alignment padding |
| 32020 | 21 00 40 | LD HL, 4000h | Point HL to start of display file |
| 32023 | 0E 20 | LD C, 32 | Load column counter |
| 32025 | A7 | AND A | Clear carry flag |
| 32026 | CB 1E | RR (HL) | Rotate right through carry |
| 32028 | 23 | INC HL | Move to next byte |
| 32029 | 0D | DEC C | Decrement column counter |
| 32030 | 20 FA | JR NZ, -6 | Loop over 32 columns |
| 32032 | 3E 58 | LD A, 88 | Load row-end comparison value |
| 32034 | BC | CP H | Check if H has reached bottom of display |
| 32035 | 20 F2 | JR NZ, -14 | Loop over all rows |
| 32037 | C9 | RET | Return to BASIC |
The first routine (called at line 125) starts at 32000 and scrolls left by rotating each byte left (RL (HL)) traversing the display from bottom to top. The second routine (called at line 110) starts at 32020 and scrolls right using RR (HL), traversing top to bottom. Both use the high byte of HL (register H) compared against a boundary value (63 = 3Fh for the top, 88 = 58h for the bottom) to detect when the full 22-row display has been processed.
Scroll Animation Logic
The loop bounds 8*16 (evaluated as 128 at runtime) represent 8 pixel columns per character times 16 characters, producing a scroll distance of exactly 16 characters across the 32-column display. Each call to the machine code routine shifts the entire screen image by exactly one pixel column. The BASIC performs no pixel manipulation itself — all work is delegated to the Z80 routines via RANDOMIZE USR.
Key BASIC Idioms
CLEAR 31999reserves addresses 32000 and above for machine code, preventing BASIC’s memory manager from overwriting it.- The sentinel-terminated
READ/POKEloop (lines 30–40) is a standard technique for loading machine code fromDATAlines without needing a separate byte count. RANDOMIZE USRis used instead ofPRINT USRto call machine code and discard the return value cleanly.8*16as a loop limit is left as an expression rather than the literal 128, making the intent (8 pixels × 16 characters) self-documenting.
Notable Techniques
The carry flag is explicitly cleared with AND A before each row’s rotation sequence. This ensures that no carry bleeds between rows, so each row of pixels scrolls independently rather than wrapping bits from adjacent rows. The inner loop rotates exactly 32 bytes (one pixel row) and then the outer loop advances HL to the next row by natural pointer progression.
The two routines share an almost identical structure but differ in direction (RL vs RR), traversal order (decrement vs increment HL), and the boundary value compared against H. This symmetry makes the code compact while providing bidirectional scrolling.
Anomalies and Notes
- The scroll is called right-then-left in the animation: line 105–115 calls the routine at 32020 (right scroll) first, then lines 120–130 call 32000 (left scroll). The comments in the program imply the directions are labeled from the routine addresses rather than descriptive names.
- Line 9998 saves two files: the BASIC program with auto-run and the raw machine code block (38 bytes from address 32000), allowing the machine code to be reloaded independently.
- The two
NOPpadding bytes at addresses 32018–32019 appear to be alignment filler rather than functional code, ensuring the second routine begins at a round address (32020) for ease of reference.
Content
Source Code
5 CLS
10 CLEAR 31999
20 LET j=32000
30 READ a: IF a=9999 THEN GO TO 100
40 POKE j,a: LET j=j+1: GO TO 30
50 DATA 33,255,87,14,32,167,203,22,43,13,32,250,62,63,188,32,242,201,0,0
60 DATA 33,0,64,14,32,167,203,30,35,13,32,250,62,88,188,32,242,201
100 FOR j=1 TO 22: PRINT "LIST SINCLAIR TIMEX GROUP L.I.NY" : NEXT J
105 FOR J=1 TO 8*16
110 RANDOMIZE USR 32020
115 NEXT J
120 FOR J=1 TO 8*16
125 RANDOMIZE USR 32000
130 NEXT J: STOP
9998 SAVE "SCROLL" LINE 0: SAVE "SCROLL"CODE 32000,38
9999 DATA 9999
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
