This is a Christmas-themed scrolling bulletin board display for the December 1982 issur of Synchro-Sette. It draws a bordered screen using block graphics and inverse-video characters, then animates two text strings (B$ and C$) rotating in opposite directions by slicing and reassembling the strings each loop iteration. After the animation, it alternately scrolls two long message strings (D$ and E$) across fixed screen rows one character at a time, with a keypress pause facility using INKEY$. Line 3 executes machine code at address 16514 via RAND USR, and line 4 POKEs the system variable at 16418 to suppress the usual display behaviour.
Program Analysis
Program Structure
The program divides into clearly distinct phases executed in sequence, looping back via GOTO 1 at line 9999:
- Initialisation (lines 1–14): Machine code call, system variable POKE, screen border drawing, static decorative lines.
- Rotating banner animation (lines 500–590): Two strings scroll in opposite directions, followed by alternating normal/inverse-video rendering of “MERRY CHRISTMAS” and “HAPPY NEW YEAR”, then a bulletin board title box is drawn.
- Bidirectional message scroll (lines 1000–2030): Strings
D$andE$are scrolled across rows 8 and 17 respectively, alternating between the two. - Save and loop (lines 9998–9999): Saves the program to tape then restarts.
Machine Code and System Variable Usage
Line 3 executes RAND USR 16514, invoking machine code at address 16514 in RAM. This is a common ZX81 technique for performing setup tasks—such as clearing memory, initialising variables, or patching the display—that are impractical in BASIC alone. Line 4 executes POKE 16418,0; address 16418 is the ZX81 system variable CDFLAG, which controls whether the machine is in FAST or SLOW mode at the hardware level. Writing 0 here resets this flag directly, complementing the surrounding FAST/SLOW keywords at lines 2 and 14.
Screen Border Drawing
The border is constructed entirely from block graphic characters rather than any graphics hardware:
- Line 5 fills row 22 with 64 inverse-space (
\@@) characters forming a solid bottom bar. - Lines 6–8 iterate over all 32 columns printing
\;;(▀) on row 0 and\!!(▒) on row 23. - Lines 9–10 iterate over all 24 rows printing
%(an inverse space) at columns 0 and 31 to form left and right side walls. - Line 13 prints a decorative string
A$across several rows to form internal horizontal dividers.
Bidirectional String Rotation
Lines 520 and 530 implement a classic ZX81 string-rotation idiom. B$ rotates left: the first character is removed from the front and appended to the end each iteration (LET B$=B$(2 TO LEN B$)+B$(1)). C$ rotates right: the last character is moved to the front (LET C$=C$(LEN C$)+C$( TO LEN C$-1)). Only the first 27 characters of each rotated string are printed at line 510, creating the illusion of text scrolling in opposite directions within a fixed window.
Alternating Message Scrolling (Lines 1000–2030)
The two loops at lines 1000 and 2000 scroll D$ and E$ independently across rows 8 and 17. Each iteration prints a 30-character window D$(N TO N+29), advancing the start index N by 1 per frame. When N reaches LEN D$-30, the loop exits to the partner scroll loop, giving an alternating effect. This relies on the strings being longer than 30 characters plus at least one extra, since the terminal condition is LEN D$-1 for the loop bound and LEN D$-30 for the exit test.
Key BASIC Idioms
| Lines | Idiom | Purpose |
|---|---|---|
| 1015, 2015 | IF INKEY$<>"" THEN PAUSE 200 | Pauses the scroll when any key is held, allowing the reader to stop and read. |
| 520–530 | String slicing and concatenation | In-place circular rotation of display strings without arrays. |
| 560 | Printing normal then inverse-video text at same position | Creates a flashing effect by overwriting text with its inverse form in rapid succession inside a 50-iteration loop. |
| 9998 | SAVE "BULLETI%N" | Saves the running program back to tape; the %N is inverse-video ‘N’ in the filename. |
Notable Techniques
- The REM at line 1 contains block graphic characters, which on the ZX81 are stored as their character codes in the program area. This is sometimes used to embed data or machine code, though here it appears decorative.
- The
FAST/SLOWbracketing of the initialisation section (lines 2 and 14) ensures the border drawing is done as quickly as possible without display flicker, switching back toSLOWmode before the animated content begins. - The inverse-video “MERRY CHRISTMAS” and “HAPPY NEW YEAR” are printed over their normal-video versions inside a 50-iteration loop at line 560, producing a rapid alternating flash without any additional timing or PAUSE calls.
- The bulletin board title box at line 580 uses
\:(▌) and\ :(▐) for left and right vertical edges, with\!!and\;;for top and bottom edges, forming a complete graphic box using only character-cell block graphics.
Content
Source Code
1 REM Y\@@\.'\. :%KNOT $TAB \@@RND\: TAB \'.RNDTAN
2 FAST
3 RAND USR 16514
4 POKE 16418,0
5 PRINT AT 22,0;"\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@"
6 FOR N=0 TO 31
7 PRINT AT 0,N;"\;;";AT 23,N;"\!!"
8 NEXT N
9 FOR N=0 TO 23
10 PRINT AT N,0;"% ";AT N,31;"% "
11 NEXT N
13 PRINT AT 6,0;A$;AT 10,0;A$;AT 19,0;A$;AT 15,0;A$
14 SLOW
500 FOR N=1 TO 24
510 PRINT AT 8,4;B$( TO 27);AT 17,1;C$( TO 27)
520 LET B$=B$(2 TO LEN B$)+B$(1)
530 LET C$=C$(LEN C$)+C$( TO LEN C$-1)
540 NEXT N
550 FOR N=1 TO 50
560 PRINT AT 8,8;"MERRY CHRISTMAS";AT 17,8;"HAPPY NEW YEAR";AT 8,8;"%M%E%R%R%Y\@@%C%H%R%I%S%T%M%A%S";AT 17,8;"%H%A%P%P%Y\@@%N%E%W\@@%Y%E%A%R"
570 NEXT N
580 PRINT AT 2,6;"\: THE SYNCHRO-SETTE\ :";AT 3,6;"\: BULLETIN BOARD \ :";AT 1,6;"\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!";AT 4,6;"\;;\;;\;;\;;\;;\;;\;;\;;\;;\;;\;;\;;\;;\;;\;;\;;\;;\;;\;;"
590 PRINT AT 7,0;A$;AT 8,0;A$;AT 9,0;A$;AT 16,0;A$;AT 17,0;A$;AT 18,0;A$;AT 21,9;"%D%E%C%E%M%B%E%R\@@%1%9%8%2"
\n1000 FOR N=1 TO LEN D$-1
\n1010 PRINT AT 8,1;D$(N TO N+29)
\n1015 IF INKEY$<>"" THEN PAUSE 200
\n1020 IF N=LEN D$-30 THEN GOTO 2000
\n1030 NEXT N
\n2000 FOR N=1 TO LEN E$-1
\n2010 PRINT AT 17,1;E$(N TO N+29)
\n2015 IF INKEY$<>"" THEN PAUSE 200
\n2020 IF N=LEN E$-30 THEN GOTO 1000
\n2030 NEXT N
\n9998 SAVE "BULLETI%N"
\n9999 GOTO 1
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
