--- title: "Quilter" id: 56817 type: "computer_media" slug: "quilter" url: "http://localhost/computer_media/quilter/" markdown_url: "http://localhost/computer_media/quilter.md" published_at: "2024-09-29T02:32:50+00:00" modified_at: "2026-03-30T21:20:55+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/09/306_Quil.png" excerpt: "Navigate a cursor with diagonal and cardinal keys to stamp repeating dot-grid patterns or erase them — a surprisingly capable lo-res drawing tool in under 40 lines of BASIC." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Demo" slug: "demo" taxonomy: "genre" url: "http://localhost/type/demo/" media_contents: - id: 56738 title: "Timex Sinclair Public Domain Library Tape 1007" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1007/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/09/306_Quil.png" media_type_tags: "Demo" --- 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. 1. **Initialisation** (lines 2–4): Variables `Z`, `C`, and `D` are zeroed. `D` is the horizontal (X) coordinate and `C` is the vertical (Y) coordinate. 2. **Main loop** (lines 5–84): A `FOR B=1 TO 9999` loop polls `INKEY$` repeatedly to update cursor position, plots the current point, optionally stamps a grid pattern via subroutine, displays coordinates, and pauses. 3. **Grid subroutine** (lines 90–99): Nested `FOR` loops 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**: `C` and `D` are not clamped to valid `PLOT` ranges (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 the `GOSUB 90` at line 75. However, this also skips the `PLOT` at line 60, so pressing `"0"` only updates the coordinate display without drawing. ## 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 ```