--- title: "Draw" id: 57020 type: "computer_media" slug: "draw-2" url: "http://localhost/computer_media/draw-2/" markdown_url: "http://localhost/computer_media/draw-2.md" published_at: "2024-10-02T07:43:03+00:00" modified_at: "2026-03-30T21:20:06+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/44_Draw.png" excerpt: "A pixel-drawing program with cursor keys 5–8 and toggleable draw/erase modes, showing boundary clamping and mode-switching techniques in under 20 lines." 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: "Graphics" slug: "graphics" taxonomy: "genre" url: "http://localhost/type/graphics/" media_contents: - id: 56732 title: "Timex Sinclair Public Domain Library Tape 1001" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1001/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/44_Draw.png" media_type_tags: "Graphics" --- # Draw This is an interactive drawing program that lets the user move a cursor around the ZX81/TS1000 screen using keys 5, 6, 7, and 8 (left, up, down, right) and toggle between draw and erase modes with keys R and D. The program uses PLOT and UNPLOT to set and clear individual pixels, with the cursor constrained to the plotting area (X: 0–50, Y: 10–43). Mode switching is handled by storing the current mode in the string variable F$, where “R” means erase (UNPLOT before each PLOT) and “D” means draw. The SAVE command on line 500 includes an inverse-video character in the filename, which acts as an auto-run flag. *** ## Program Analysis ### Program Structure The program is divided into logical blocks by line number ranges: 1. Lines 5–30: Initialisation — title print, cursor position (`X=0`, `Y=10`), and default mode (`F$="R"`). 2. Lines 100–110: Mode-switching input — checks for `R` (erase) or `D` (draw). 3. Lines 190–230: Erase step and movement input — conditionally UNPLOTs, then reads directional keys. 4. Lines 300–330: Boundary clamping — keeps cursor within the drawable area. 5. Line 340: Plots the new cursor position. 6. Line 400: Main loop jump back to line 100. 7. Lines 500–510: SAVE and LIST utilities, not part of the running program. ### Drawing Modes The variable `F$` controls whether the program is in draw or erase mode. When `F$="R"`, line 190 executes `UNPLOT X,Y` before the new position is plotted at line 340, effectively erasing the previous pixel and producing a moving cursor with no trail. When `F$="D"`, line 190 is skipped, leaving every visited pixel set — this is the actual drawing mode. The naming is slightly counter-intuitive: “R” (for “Rubber”?) erases, while “D” draws. ### Input Handling All input is polled via `INKEY$` inside the main loop with no debouncing or waiting. Movement uses the classic ZX81 cursor key layout: `5`=left, `6`=up, `7`=down, `8`=right. Mode switching on lines 100 and 110 re-reads `INKEY$` independently on each line, meaning the key must still be held when each line executes — a potential race condition where a quick keypress might be missed or partially registered. ### Boundary Clamping Lines 300–330 clamp `X` and `Y` to the valid plotting range before the PLOT on line 340. The Y range of 10–43 keeps the cursor out of the text area used by the title on line 5. The X range of 0–50 is well within the ZX81’s 64-pixel-wide display. Clamping is done with simple IF/LET pairs rather than MIN/MAX functions (which are not available in this BASIC). ### Notable Techniques and Anomalies - The program uses separate INKEY$ reads for mode switching (lines 100, 110) and movement (lines 200–230), meaning up to five independent key polls happen per loop iteration — potentially causing inconsistent behaviour at borderline key timings. - In erase mode (`F$="R"`), UNPLOT is applied to the current position before the move is processed, so the old pixel is cleared and then the new position is plotted, giving a single-pixel travelling cursor effect. - The default mode at startup is `F$="R"` (erase/cursor), so the user must press D to begin drawing. - There is no mechanism to detect or handle `INKEY$` returning an empty string differently from no input — movement simply does not occur if no key is held, which is the expected ZX81 idiom for real-time control. ### Variable Summary | Variable | Purpose | | --- | --- | | `X` | Horizontal cursor position (0–50) | | `Y` | Vertical cursor position (10–43) | | `F$` | Mode flag: “R” = erase/cursor, “D” = draw | ## Source Code ``` 5 PRINT "%D%R%A%W%I%N%G" 10 LET X=0 20 LET Y=10 30 LET F$="R" 100 IF INKEY$="R" THEN LET F$=INKEY$ 110 IF INKEY$="D" THEN LET F$=INKEY$ 190 IF F$="R" THEN UNPLOT X,Y 200 IF INKEY$="5" THEN LET X=X-1 210 IF INKEY$="6" THEN LET Y=Y-1 220 IF INKEY$="7" THEN LET Y=Y+1 230 IF INKEY$="8" THEN LET X=X+1 300 IF X>50 THEN LET X=50 310 IF X<0 THEN LET X=0 320 IF Y>43 THEN LET Y=43 330 IF Y<10 THEN LET Y=10 340 PLOT X,Y 400 GOTO 100 500 SAVE "1004%4" 510 LIST ```