QUILTER is an interactive pixel-drawing program that lets the user place individual points or repeating grid patterns on the ZX81/TS1000 lo-res display using keyboard controls. Movement keys 5/8/6/7 (and diagonal aliases X/H/N/D) adjust a cursor position stored in variables C and D. Pressing W activates an “unplot” mode that erases rather than draws, while the subroutine at line 90 stamps a repeating grid of points at 12-unit intervals across and down the screen from the current position. The PAUSE 65000 at line 82 introduces a deliberate long delay each iteration rather than waiting for a keypress, which combined with the INKEY$ polling loop gives a slow, step-by-step drawing rhythm.
Program Analysis
Program Structure
The program is organised into three logical sections: initialisation (lines 1–4), the main drawing loop (lines 5–88), and a grid-stamping subroutine (lines 90–99). Lines 100–120 are utility lines for saving and restarting the program and are not executed during normal operation.
- Initialisation (lines 2–4): Variables
Z,C, andDare zeroed.Dis the horizontal (X) coordinate andCis the vertical (Y) coordinate. - Main loop (lines 5–84): A
FOR B=1 TO 9999loop pollsINKEY$repeatedly to update cursor position, plots the current point, optionally stamps a grid pattern via subroutine, displays coordinates, and pauses. - Grid subroutine (lines 90–99): Nested
FORloops stamp (or unplot) points at every 12-unit interval from the current position to the screen edges.
Key Controls
| Key(s) | Effect |
|---|---|
5 / 8 | Decrease / increase D (horizontal) |
6 / 7 | Decrease / increase C (vertical) |
X | Decrease both D and C (diagonal up-left) |
H | Decrease D, increase C (diagonal up-right) |
N | Increase D, decrease C (diagonal down-left) |
D | Increase both D and C (diagonal down-right) |
W | Set Z=5 (activates unplot mode for next grid stamp) |
0 | Skip subroutine call (plot single point only) |
Notable Techniques
Diagonal movement is implemented by pairing two consecutive IF INKEY$= tests on the same key (e.g. lines 15 and 25 both test "X"), adjusting both D and C in sequence. Because each IF statement re-polls INKEY$ independently, a key that is released between the two tests could theoretically cause only one axis to update, though in practice key presses are held long enough to avoid this.
The PAUSE 65000 at line 82 introduces a very long delay (over a minute on real hardware at 50 Hz), which seems like an error intended to be a short pause for coordinate display. In practice this makes the program extremely slow to respond. A value such as PAUSE 5 would be more usable.
The subroutine’s STEP 12 value corresponds to the width of one character cell in the ZX81’s pixel coordinate system (each character cell is 8×8 pixels, but the screen is 64 wide and 44 tall in pixel coordinates — 12 is an aesthetic spacing choice rather than a cell boundary).
The unplot/erase mode uses Z=5 as a flag (line 65 sets it, line 95 tests it, line 98 resets it). The flag is only honoured inside the grid subroutine; a single direct PLOT at line 60 always draws regardless of Z.
Bugs and Anomalies
- PAUSE 65000: At line 82, this causes an approximately 21-minute wait per loop iteration on hardware running at 50 Hz interrupts, rendering the program nearly unusable as an interactive tool. Almost certainly a typo for a small value like
PAUSE 5. - No bounds checking:
CandDare not clamped to validPLOTranges (0–43 vertical, 0–63 horizontal on ZX81). Moving the cursor out of range will cause an error. - Single PLOT always draws: Even when
Z=5(unplot mode) is set, line 60 still plots the current point before the subroutine runs, so the point is drawn before any erasing takes place. - Key “0” skip logic: Line 70 jumps to line 80 if
"0"is pressed, bypassing theGOSUB 90at line 75. However, this also skips thePLOTat line 60, so pressing"0"only updates the coordinate display without drawing.
Content
Source Code
1 REM QUILTER
2 LET Z=0
3 LET C=0
4 LET D=0
5 FOR B=1 TO 9999
6 IF INKEY$="5" THEN LET D=D-1
7 IF INKEY$="8" THEN LET D=D+1
8 IF INKEY$="6" THEN LET C=C-1
9 IF INKEY$="7" THEN LET C=C+1
15 IF INKEY$="X" THEN LET D=D-1
25 IF INKEY$="X" THEN LET C=C-1
30 IF INKEY$="H" THEN LET D=D-1
35 IF INKEY$="H" THEN LET C=C+1
40 IF INKEY$="N" THEN LET D=D+1
45 IF INKEY$="N" THEN LET C=C-1
50 IF INKEY$="D" THEN LET D=D+1
55 IF INKEY$="D" THEN LET C=C+1
60 PLOT D,C
65 IF INKEY$="W" THEN LET Z=5
70 IF INKEY$="0" THEN GOTO 80
75 GOSUB 90
80 PRINT AT 0,0;D;",";C;" "
82 PAUSE 65000
84 NEXT B
86 PRINT AT 0,0;" "
88 STOP
90 FOR I=D TO 59 STEP 12
92 FOR L=C TO 35 STEP 12
94 PLOT I,L
95 IF Z=5 THEN UNPLOT I,L
96 NEXT L
97 NEXT I
98 LET Z=0
99 RETURN
100 CLEAR
110 SAVE "1030%6"
120 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
