This program is an animated bulletin board display created by Synchro-Sette for the November 1983 issue. It opens with a scrolling checkerboard background built from alternating block-graphic pairs, then slides the “SYNCHRO-SETTE PRESENTS” title onto the screen from the right using substring slicing, and flashes it in inverse video. After the intro, it draws a framed bulletin board using block-graphic characters for borders (▌, ▐, ▀, ▄ variants), and scrolls two independently controlled text strings — stored in A$ and B$ — through separate windows within the frame. Keyboard controls allow the user to pause (P), scroll backwards (B), and resume forwards (F) through each text band, with the two subroutines at lines 5000 and 6000 handling interactivity for the upper and lower windows respectively.
Program Analysis
Program Structure
The program is divided into several functional phases:
- Lines 10–60: Fill the screen with a rotating checkerboard pattern using block-graphic string
Z$. - Lines 70–140: Slide the “SYNCHRO-SETTE PRESENTS” title onto the screen from the right, then flash it in normal and inverse video.
- Lines 150–200: Switch to scroll mode (
POKE 16418,2) and scroll the checkerboard upward. - Lines 210–370: Scroll in a framed bulletin board header identifying “THE BULLETIN BOARD FOR NOVEMBER 1983”, with block-graphic top and bottom borders.
- Lines 390–550: Draw a full static frame around the screen using block-graphic border characters, with animated
Z$strips running inside the frame. - Lines 3000–3200: Main content loop — scrolls text from
A$through the upper window andB$through the lower window, with interactive keyboard handling. - Lines 5000–5190 / 6000–6190: Subroutines for keyboard-driven control (pause/back/forward) of the upper and lower text windows respectively.
- Lines 9998–9999: Save the program and loop back to line 10.
Display Memory and Scroll Control
POKE 16418,0 and POKE 16418,2 manipulate the ZX81 system variable RAMTOP… actually, address 16418 is CDFLAG — the centisecond/display flag. Setting bit 1 of CDFLAG (value 2) enables automatic scrolling in FAST mode, while clearing it (value 0) suppresses the scroll prompt and controls display behavior. This is used to transition cleanly between the full-screen intro and the scrolling phase.
Checkerboard Animation via String Rotation
The string Z$ is initialised at line 10 as 32 characters of alternating \@@ (▟ or similar block) and \## (another block graphic) pairs — 16 repetitions of a two-character cell. At each frame step, line 50 (and later lines 190, 360, 540) rotates Z$ by one character using the idiom:
LET Z$=Z$(32)+Z$( TO 31)
This takes the last character and prepends it to the first 31, creating a one-position rightward rotation. Printing this across all rows gives the illusion of horizontal motion in the checkerboard.
Title Slide-In Animation
Lines 90–110 implement a right-to-left slide of the title string. The loop counts N from 31 down to 0, and at each step prints a progressively longer leading substring of Y$ at column N:
PRINT AT 12,N;Y$( TO 32-N)
This reveals more of the string each frame while shifting the print position left, producing a smooth slide-in from the right edge.
Inverse Video Flash
Lines 130–140 flash the title by alternately printing X$ (the inverse-video version of the title, built with %-escaped characters) and Y$ (normal video) at the same position 20 times in rapid succession, creating a flicker effect without any PAUSE delay.
Block-Graphic Border Construction
The bulletin board frame (lines 400–510) is assembled entirely from ZX81 block-graphic characters:
- Top and bottom borders use
\:'\''\''...sequences (▛▀▀▀… style lines). - Left and right edges use
\:(▌ with space) and\ :(▐ with space). - Horizontal dividers inside the frame use
\:.\..\.....sequences (▙▄▄▄… style lines).
Lines 420 and 490 build the right and left vertical edges respectively using FOR loops printing one character per row.
Dual Scrolling Text Windows
The main loop at lines 3000–3200 scrolls A$ through the upper inner window (row 5, columns 2–29) and B$ through the lower inner window (row 18, columns 2–29). Each window displays a 28-character substring, advancing one character per iteration. Both loops call independent subroutines (5000 and 6000) for keyboard handling.
Interactive Keyboard Controls
The subroutines at lines 5000 and 6000 use INKEY$ polling (non-blocking) so scrolling continues when no key is pressed. Three keys are handled:
| Key | Action |
|---|---|
P | Pause scrolling (PAUSE 40000 ≈ long hold) |
B | Scroll backwards through the text |
F | Resume forward scrolling (exits the backward loop) |
The backward scroll subroutine (lines 5100–5190 and 6100–6190) decrements the index I from the current position down to 28 (the minimum displayable offset), stopping early if F is pressed, then sets N=I so forward scrolling resumes from the rewound position.
Bugs and Anomalies
A$andB$are never defined within the listing — they are expected to be loaded or set externally before this segment runs, as is typical for a loader/presenter program where data strings are POKEd or appended.- Line 3200
GOTO 3000creates an infinite loop replaying both text bands from the start, with no exit condition. - The backward scroll loops in the subroutines start at
Nand count down to 28 — but sinceNstarts at 1 (from theFORin lines 3010/3110), attempting to go back near the beginning whenN < 28would result in an empty or negative-step loop with no iterations, effectively a no-op rather than an error. - Line 390 is numbered 390 but line 380 is absent — this is harmless but suggests a deleted line.
Save and Auto-Run
Line 9998 saves the program as BULLETI%N, where %N is an inverse-video N — on the ZX81, this serves as the auto-run flag in the SAVE filename, causing the program to start automatically when loaded from tape.
Content
Source Code
10 LET Z$="\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##"
20 POKE 16418,0
30 FOR N=1 TO 24
40 PRINT Z$
50 LET Z$=Z$(32)+Z$( TO 31)
60 NEXT N
70 LET Y$="\@@\##\@@\##\@@SYNCHRO-SETTE PRESENTS\##\@@\##\@@\##"
80 LET X$="\@@\##\@@\##\@@%S%Y%N%C%H%R%O%-%S%E%T%T%E% %P%R%E%S%E%N%T%S\##\@@\##\@@\##"
90 FOR N=31 TO 0 STEP -1
100 PRINT AT 12,N;Y$( TO 32-N)
110 NEXT N
120 FOR N=1 TO 20
130 PRINT AT 12,0;X$;AT 12,0;Y$
140 NEXT N
150 POKE 16418,2
160 FOR N=1 TO 13
170 SCROLL
180 PRINT Z$
190 LET Z$=Z$(32)+Z$( TO 31)
200 NEXT N
210 LET W$="\@@\##\@@\##\@@\##\: THE BULLETIN BOARD\ :\@@\##\@@\##\@@\##"
220 LET V$="\##\@@\##\@@\##\@@\: FOR NOVEMBER 1983\ :\##\@@\##\@@\##\@@"
230 LET Y$="\##\@@\##\@@\##\@@\:'\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\':\##\@@\##\@@\##\@@"
240 LET U$="\@@\##\@@\##\@@\##\:.\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\.:\@@\##\@@\##\@@\##"
250 SCROLL
260 PRINT Y$
270 SCROLL
280 PRINT W$
290 SCROLL
300 PRINT V$
310 SCROLL
320 PRINT U$
330 FOR N=1 TO 8
340 SCROLL
350 PRINT Z$
360 LET Z$=Z$(32)+Z$( TO 31)
370 NEXT N
390 POKE 16418,0
395 PRINT AT 22,0;Z$
400 PRINT AT 0,0;"\:'\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\':"
410 FOR N=1 TO 22
420 PRINT AT N,31;"\ :"
430 NEXT N
440 LET W$="\:.\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\.:"
450 FOR N=31 TO 0 STEP -1
460 PRINT AT 23,N;W$(N+1)
470 NEXT N
480 FOR N=22 TO 1 STEP -1
490 PRINT AT N,0;"\: "
500 NEXT N
510 PRINT AT 4,1;"\:'\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\':";AT 5,1;"\: ";AT 5,30;"\ :";AT 6,1;"\:.\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\.:";AT 17,1;"\:'\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\':";AT 18,1;"\: ";AT 18,30;"\ :";AT 19,1;"\:.\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\.:"
520 FOR N=1 TO 20
530 PRINT AT 5,2;Z$( TO 28);AT 18,2;Z$( TO 28)
540 LET Z$=Z$(32)+Z$( TO 31)
550 NEXT N
\n3000 LET A=0
\n3010 FOR N=1 TO LEN A$-28
\n3020 PRINT AT 5,2;A$(N TO N+27)
\n3030 GOSUB 5000
\n3040 NEXT N
\n3100 LET A=1
\n3110 FOR N=1 TO LEN B$-28
\n3120 PRINT AT 18,2;B$(N TO N+27)
\n3130 GOSUB 6000
\n3140 NEXT N
\n3200 GOTO 3000
\n5000 LET Q$=INKEY$
\n5010 IF Q$="" THEN RETURN
\n5020 IF Q$="P" THEN PAUSE 40000
\n5040 IF Q$="B" THEN GOTO 5100
\n5050 RETURN
\n5100 FOR I=N TO 28 STEP -1
\n5130 PRINT AT 5,2;A$(I TO I+27)
\n5140 IF INKEY$="F" THEN GOTO 5180
\n5150 IF INKEY$="P" THEN PAUSE 40000
\n5160 NEXT I
\n5180 LET N=I
\n5190 RETURN
\n6000 LET Q$=INKEY$
\n6010 IF Q$="" THEN RETURN
\n6020 IF Q$="P" THEN PAUSE 40000
\n6040 IF Q$="B" THEN GOTO 6100
\n6050 RETURN
\n6100 FOR I=N TO 28 STEP -1
\n6130 PRINT AT 18,2;B$(I TO I+27)
\n6140 IF INKEY$="F" THEN GOTO 6180
\n6150 IF INKEY$="P" THEN PAUSE 40000
\n6160 NEXT I
\n6180 LET N=I
\n6190 RETURN
\n9998 SAVE "BULLETI%N"
\n9999 GOTO 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
