Slow Message

Developer(s): D. J. Currie
Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Banner

This program displays a user-entered text message as a continuously repeating scrolling marquee, rendering each character at double size on screen. The user inputs a message via INPUT, and each character is individually printed in INK 5 at the bottom of the screen (line 21), then examined pixel-by-pixel using the POINT command to reconstruct it scaled 2× in both dimensions using PLOT. Between each character display, a machine code routine at address 60000 is called 16 times to perform a smooth horizontal scroll of the double-size rendering area. The 17-byte machine code routine (loaded via READ/DATA and POKE) implements a left-shift scroll using Z80 instructions operating on the display memory starting at address 0x57FF. The message loops indefinitely by jumping back to line 80 after all characters have been processed.


Program Analysis

Program Structure

The program is organized into three logical phases: initialization (lines 10–40), user input (lines 50–70), and the main display loop (lines 80–220), with machine code data at line 230.

  1. Lines 10–40: Reserve memory with CLEAR 59999, then load 17 bytes of machine code into address 60000 via READ/POKE.
  2. Lines 50–70: Prompt for a message string, reject empty input, and store the message length in n.
  3. Lines 80–100: Outer loop iterates over each character in the message using index q, calling the double-size print subroutine at line 110, then repeating indefinitely.
  4. Lines 110–220: Subroutine that prints a character at screen row 21, samples its pixels with POINT, and plots a 2× scaled version, then scrolls via machine code.
  5. Line 230: DATA block containing the 17-byte Z80 machine code routine.

Double-Size Character Rendering

The subroutine at line 110 uses a clever technique to scale characters. Each character y$(q) is printed with INK 5 at position AT 21,0 — the bottom row of the screen. The nested loops over a (rows 7 down to 0) and b (columns 0 to 7) use POINT (b,a) to test each pixel of the rendered character at the bottom of the display. For each lit pixel, an additional 2×2 block is plotted at PLOT x-16+2*b+c, y+2*a-d using inner loops c and d (both 0 to 1), effectively doubling the character in both axes. The row loop runs from 7 to 0 (descending) because BASIC graphics coordinates place row 0 at the bottom.

The target position is anchored by x=255 and y=100, placing the scaled output in the upper-right region of the display. Note that x-16+2*b can reach a maximum of 255-16+14 = 253, staying within the 256-pixel-wide screen.

Machine Code Scroll Routine

The 17-byte routine stored at address 60000 performs a hardware-level left scroll of the relevant screen area. The DATA values decode as the following Z80 instructions:

OffsetBytesMnemonicNotes
033 FF 57LD HL, 0x57FFPoints near display file
30E C0LD C, 0xC0Row count / mask
506 20LD B, 3232 bytes per row
77BLD A, ELoad accumulator
8CB 16RL (HL)Rotate left through carry
102BDEC HLMove to next byte
1110 FBDJNZ -5Loop 32 times
130DDEC CDecrement row counter
1420 F5JR NZ, -11Loop over rows
16C9RETReturn to BASIC

This routine is called 16 times per character (line 210: FOR r=1 TO 16: RANDOMIZE USR 60000: NEXT r), producing a smooth 16-pixel leftward scroll for each character-width cycle, matching the 2× scaled 8-pixel character (16 pixels wide). RANDOMIZE USR is the standard idiom for calling machine code from BASIC, discarding the return value.

Key BASIC Idioms

  • CLEAR 59999 reserves RAM above address 59999, protecting the machine code from being overwritten by BASIC string/variable storage.
  • IF t$="" THEN GO TO 50 at line 50 provides simple input validation, ensuring the message is non-empty before proceeding.
  • The variable y$ is assigned from t$ at line 60 but is never modified — it appears redundant; t$ could be used directly throughout.
  • PRINT AT 21,0;" " at line 220 clears the character used as a pixel source before returning, preventing leftover ink from affecting the next character’s POINT sampling.

Notable Techniques and Observations

The use of POINT to read back pixel data from a character rendered on-screen is an elegant way to access the font bitmap without needing to know font memory addresses. By printing to a known screen location and sampling with POINT, the program is font-agnostic and will correctly scale any character the system can display, including user-defined graphics.

One minor anomaly: the variable y$ (line 60) is a direct copy of t$ and serves no functional purpose — the loop at line 90 references y$(q), which is equivalent to t$(q). This may be a leftover from an earlier version where the strings diverged.

The scroll loop calls the machine code 16 times rather than passing a loop count as a parameter, which is less efficient but simpler to implement in BASIC. Each call scrolls the display one pixel left, for a total of 16 pixels — exactly one double-width character column.

Content

Appears On

Library tape of the Indiana Sinclair Timex User’s Group.

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   10 REM     SLOW MESSAGE         Enter a message of any length   and leave spaces at the end     as the message will repeat.                                             by D.J. Currie         
   20 CLEAR 59999
   30 FOR f=0 TO 16: READ a: POKE 60000+f,a: NEXT f
   40 LET x=255: LET y=100
   50 INPUT "Enter message - ";t$: IF t$="" THEN GO TO 50
   60 LET y$=t$
   70 LET n=LEN y$
   80 FOR q=1 TO n
   90 GO SUB 110: NEXT q
  100 GO TO 80
  110 REM Print double size
  120 PRINT INK 5;AT 21,0;y$(q)
  130 FOR a=7 TO 0 STEP -1
  140 FOR b=0 TO 7
  150 IF POINT (b,a)=0 THEN GO TO 200
  160 FOR c=0 TO 1
  170 FOR d=0 TO 1
  180 PLOT x-16+2*b+c,y+2*a-d
  190 NEXT d: NEXT c
  200 NEXT b: NEXT a
  210 FOR r=1 TO 16: RANDOMIZE USR 60000: NEXT r
  220 PRINT AT 21,0;" ": RETURN 
  230 DATA 33,255,87,14,192,6,32,183,203,22,43,16,251,13,32,245,201
  240 SAVE "Message" LINE 10

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top