This program continuously writes character codes into the ZX81/TS1000 display file to create a flashing visual effect across three fixed screen positions. It uses two parallel arrays: P holds three memory addresses within the display file (17531, 17210, 17484), and C holds three character codes (27, 23, 0) that are cycled through. For each combination of position and character, it also writes the same value to eight surrounding cells—horizontal neighbours (±Z columns) and vertical neighbours (±33*Z rows, since each display-file row is 33 bytes wide including the NEWLINE byte). The program loops infinitely via RUN at line 60, creating an animated pattern, and line 70 saves the program under a filename.
Program Analysis
Program Structure
The program is divided into two phases: initialisation (lines 1–8) and execution (lines 10–80). Lines 1–4 populate a three-element array P with absolute addresses in the display file. Lines 5–8 populate a three-element array C with character codes to write. Lines 10–50 form a triple nested loop that POKEs values into the display file, and line 60 restarts the whole program via RUN, creating an infinite animation loop.
Array Usage
| Array | Index | Value | Role |
|---|---|---|---|
P | 1 | 17531 | Display-file address, position 1 |
P | 2 | 17210 | Display-file address, position 2 |
P | 3 | 17484 | Display-file address, position 3 |
C | 1 | 27 | Character code (typically a block graphic or keyword token) |
C | 2 | 23 | Character code |
C | 3 | 0 | Character code 0 (space/clear) |
Display File Geometry
Each row in the ZX81/TS1000 display file occupies 33 bytes: 32 character cells plus a trailing NEWLINE (76H) byte. The program exploits this directly: horizontal neighbours are reached by ±Z, and vertical neighbours by ±33*Z. The eight POKEs in the inner loop (lines 31–38) therefore write to all eight cells in a diamond/square pattern around the central address, with Z ranging from 1 to 3, producing concentric rings of the same character.
Notable Techniques
- Flat-address POKEing: Rather than computing screen coordinates, the program stores pre-calculated display-file addresses directly in array
P, avoiding any coordinate arithmetic at runtime. - Eight-directional flood fill: Lines 31–38 methodically cover all eight compass directions around the centre point, effectively stamping a filled square of side
2*Z+1for each value ofZ. - Infinite loop via RUN:
RUNat line 60 reinitialises variables and restarts from line 1 each iteration, so the arrays are rebuilt every cycle. This means the visual effect is re-applied from scratch each loop rather than being incremental. - No PAUSE or input: The animation runs at full interpreter speed with no deliberate delay, so the cycling effect will be rapid.
Bugs and Anomalies
- No boundary checking: The POKE expressions
P(X)±ZandP(X)±33*Zcan potentially write into NEWLINE bytes or adjacent rows when a position is near the start or end of a display-file row, corrupting the display-file structure. - Overwrite sequence: Because the outer loop cycles through all three values of
Cfor each position in a single pass, only the last value written (C(3)=0) will remain visible after the innerYloop completes, effectively clearing everything beforeRUNrestarts. The intermediate writes produce flicker rather than a lasting pattern. - Line 80 unreachable: The
SAVEat line 70 andRUNat line 80 are never reached during normal execution because line 60 always loops back to the start.
Content
Source Code
1 DIM P(3)
2 LET P(1)=17531
3 LET P(2)=17210
4 LET P(3)=17484
5 DIM C(3)
6 LET C(1)=27
7 LET C(2)=23
8 LET C(3)=00
10 FOR X=1 TO 3
20 FOR Y=1 TO 3
25 POKE P(X),C(Y)
30 FOR Z=1 TO 3
31 POKE P(X)+Z,C(Y)
32 POKE P(X)-Z,C(Y)
33 POKE P(X)-33*Z,C(Y)
34 POKE P(X)+33*Z,C(Y)
35 POKE P(X)-Z-33*Z,C(Y)
36 POKE P(X)-Z+33*Z,C(Y)
37 POKE P(X)+Z-33*Z,C(Y)
38 POKE P(X)+Z+33*Z,C(Y)
39 NEXT Z
40 NEXT Y
50 NEXT X
60 RUN
70 SAVE "1009%4"
80 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
