--- title: "Scroll" id: 69499 type: "computer_media" slug: "scroll-2" url: "http://localhost/computer_media/scroll-2/" markdown_url: "http://localhost/computer_media/scroll-2.md" published_at: "2026-04-13T21:19:18+00:00" modified_at: "2026-04-13T21:20:43+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/04/SCR-20260413-fuau.png" excerpt: "A 98-byte Z80 machine code routine POKEd into high memory delivers smooth upward screen scrolling — and the REM block hints at adapting it for all four directions." 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: "Programming" slug: "programming" taxonomy: "genre" url: "http://localhost/type/programming/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Scroll%20%28198x%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/04/SCR-20260413-fuau.png" media_type_tags: "Programming" --- This program implements an upward screen-scroll routine using Z80 machine code stored via DATA statements and POKEd into memory starting at address 62000. The routine shifts the display file upward by one character row at a time using the Z-80 block move instruction (LDIR, opcode ED B0) and related register operations. Line 70 demonstrates the scroll by calling RANDOMIZE USR 62000 a total of 175 times in a loop, scrolling the LIST output off the top of the screen. The 98-byte machine code payload is loaded through a straightforward FOR/READ/POKE loop before execution. *** ## Program Analysis ### Program Structure The program is organized into four functional phases: 1. **Documentation** — Line `10` is a REM statement describing the routine’s purpose and usage. 2. **Data** — Lines `20` and `30` hold the 98 decimal bytes of Z-80 machine code across two DATA statements. 3. **Loader** — Lines `40`–`60` set the load address (`s=62000`), then READ and POKE each byte into RAM. 4. **Demo** — Line `70` runs LIST to populate the screen, then calls `RANDOMIZE USR 62000` 175 times to scroll the content off the top. ### Machine Code Payload The 98 bytes constitute a Z-80 routine loaded at address 62000 (decimal). Key opcodes visible in the DATA include: - `ED B0` — LDIR (block copy with auto-increment and decrement of BC), the core instruction for moving display memory rows upward. - `ED 42` — SBC HL,BC, used for pointer arithmetic between source and destination addresses. - `21, 00, 41` — LD HL,16640 (0x4100), pointing into the display file one row down from the top. - `11, 00, 40` — LD DE,16384 (0x4000), the start of the display file. - `C9` — RET, terminating the routine and returning control to BASIC. The routine iterates through the display file’s character rows, copying each row’s pixel data one row up, effectively scrolling the entire screen upward by one character row per call. The final row is cleared or left as residual data after the last LDIR. ### Memory Layout | Address | Contents | | --- | --- | | 16384 (0x4000) | Start of display file | | 16640 (0x4100) | Second character row (one row = 256 bytes × pixel lines) | | 62000 | Machine code load address (s) | | 62000–62097 | 98 bytes of Z-80 scroll routine | ### Key BASIC Idioms - `LET s=62000` on line `40` stores the base address in a variable, making the POKE loop on line `60` cleaner and the target address easy to change for experimentation. - `FOR f=0 TO 97 … READ a: POKE s+f,a: NEXT f` is the standard single-line loader idiom, reading all 98 data bytes in sequence. - `RANDOMIZE USR 62000` is the conventional way to call a machine code subroutine from BASIC; RANDOMIZE discards the integer return value in HL without error. - The demo loop `FOR z=1 TO 175: RANDOMIZE USR 62000: NEXT z` calls the scroll 175 times — enough to push a full screen’s worth of LIST output off the display. ### Notable Techniques Using address 62000 places the machine code well above the typical BASIC program area and below the 65535 ceiling, avoiding conflicts with system variables and the display file. The two-DATA-statement split across lines `20` and `30` keeps individual line lengths manageable. The REM comment on line `10` explicitly invites modification of the routine to scroll in other directions, suggesting the LDIR source/destination addressing could be reversed or reoriented for downward, left, or right scrolling. ### Bugs and Anomalies No significant bugs are present. The loop count of 175 in the demo is slightly over the 24 visible character rows (each requiring one USR call), so the scroll will continue past a cleared screen — this is cosmetic and intentional for demonstration purposes. The DATA byte count of 98 (indices 0 to 97) matches the FOR loop range exactly, so no bytes are missed or over-read. ## Source Code ``` 10 REM Up-Scroll / Can be Modified to scroll in all directions. DATA statements are Z-80 machinecode. To scroll, type - : RANDOMIZE USR 62000 Unfortunately, Author & publica-tion remain unknown. 20 DATA 33,0,65,17,0,64,6,3,197,6,8,197,6,7,197,1,32,0,237,176,1,224,0,9,229,213,225,9,229,209,225,193,16,236,1,224,7,237,66,1,32,0,237,176,1,32,0,237,66,229 30 DATA 209,1,0,1,9,193,16,209,1,0,7,213,225,9,1,32,0,229,237,66,229,209,225,1,32,0,237,176,1,0,1,213,225,9,193,16,177,33,224,87,1,0,32,113,35,16,252,201 40 LET s=62000 50 FOR f=0 TO 97 60 READ a: POKE s+f,a: NEXT f 70 LIST : FOR z=1 TO 175: RANDOMIZE USR 62000: NEXT z ```