--- title: "Sketch" id: 56813 type: "computer_media" slug: "sketch" url: "http://localhost/computer_media/sketch/" markdown_url: "http://localhost/computer_media/sketch.md" published_at: "2024-09-29T02:29:03+00:00" modified_at: "2026-03-30T21:20:57+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/09/303_Sket.png" excerpt: "A keyboard-driven pixel sketching tool that lets you plot and move a cursor around the screen, lift the pen, and save your artwork — all with single-key presses." 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: "Art" slug: "art" taxonomy: "genre" url: "http://localhost/type/art/" 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/303_Sket.png" media_type_tags: "Art" --- This program is a simple interactive pixel-drawing tool for the ZX81/TS1000’s 64×44 character-cell graphics display. The user enters a title string, then uses keys 5/6/7/8 to move a cursor left, down, up, and right respectively, with key 0 toggling the pen up and key 1 toggling the pen down to plot pixels. The variable A is initialised to 1 and used as the movement step size throughout, while P acts as a pen-state flag (P=A means draw, P=0 means move without drawing). A SAVE command triggered by key “S” stores the program under the user-supplied title string directly from within the drawing loop. *** ## Program Analysis ### Program Structure The program is divided into three logical phases: 1. **Initialisation (lines 5–13):** Sets `A=1`, `X=A`, `Y=A`, and `P=A`, placing the cursor at position (1,1) with the pen down. 2. **Title entry (lines 15–27):** Prompts for a title string `A$`, clears the screen, and prints the title. 3. **Main drawing loop (lines 30–140):** Continuously polls `INKEY$` for movement and pen-state commands, plots or unplots the current pixel, then loops back to line 30. Lines 150–170 are dead code — they are unreachable because the loop at line 140 always jumps back to line 30. Lines 180–200 appear to be a bootstrap/loader stub that would only execute if the program were run from line 180 directly. ### Drawing Loop Mechanics Each iteration of the main loop performs an `UNPLOT` at the current position (line 40) and then conditionally re-`PLOT`s it (line 45) if `P=A` (i.e., pen is down). This erase-then-redraw pattern is used rather than maintaining a separate cursor graphic, so the “cursor” and the drawn trail are the same pixel. Movement keys map as follows: | Key | Action | | --- | --- | | `"5"` | Move left: `X = ABS(X - A)` | | `"6"` | Move down: `Y = ABS(Y - A)` | | `"7"` | Move up: `Y = Y + A` | | `"8"` | Move right: `X = X + A` | | `"0"` | Pen up: `P = 0` | | `"1"` | Pen down: `P = A` | | `"S"` | Save program as `A$` | These key assignments (5=left, 6=down, 7=up, 8=right) mirror the standard ZX81 cursor-key convention used in many games of the era. ### Boundary Clamping Lines 120 and 130 implement simple boundary checks: if `X` exceeds 63 or `Y` exceeds 41, the coordinate is decremented by `A` (i.e., 1). This prevents the cursor from leaving the 64×44 pixel display area on the right and top edges. However, there is no explicit lower-bound check for `X` or `Y` going negative — instead, line 50 uses `ABS(X - A)` and line 60 uses `ABS(Y - A)`, which means moving left or down past zero reflects the coordinate back to a positive value rather than clamping to zero. This produces a bounce rather than a hard stop at the left and bottom edges. ### Use of Variable A as a Constant Rather than using the literal `1` throughout the program, the step size is stored in `A`. This means that modifying line 5 alone would change the movement granularity across the entire program, making `A` an effective configuration constant. It also means the pen-state flag `P` uses the same value: `P=A` means pen down, `P=0` means pen up, so the pen-down test on line 45 (`IF P=A`) would remain correct even if `A` were changed. ### Notable Techniques and Anomalies - The `INKEY$` polling on lines 50–110 is not mutually exclusive — each line independently reads the keyboard. On a real machine this is fine since only one key is pressed at a time, but it does mean multiple checks are performed per loop iteration. - The loop does not contain any `PAUSE` or delay, so cursor movement speed is governed purely by the speed of the BASIC interpreter executing lines 30–140. - Lines 150–170 are entirely unreachable via normal flow due to the unconditional `GOTO 30` at line 140. They appear to be vestigial code or an earlier draft of the loop exit logic. - The `SAVE A$` command on line 110 saves the program under the user’s chosen title, providing a convenient in-sketch save function, though it saves the entire program rather than just the drawing state. - Line 190 contains a `SAVE` with an inverse digit in the filename, serving as the auto-run loader entry point. ## Source Code ``` 5 LET A=1 10 LET X=A 12 LET Y=A 13 LET P=A 15 PRINT "ENTER TITLE" 20 INPUT A$ 25 CLS 27 PRINT A$ 30 PLOT X,Y 40 UNPLOT X,Y 45 IF P=A THEN PLOT X,Y 50 IF INKEY$="5" THEN LET X=ABS (X-A) 60 IF INKEY$="6" THEN LET Y=ABS (Y-A) 70 IF INKEY$="7" THEN LET Y=Y+A 80 IF INKEY$="8" THEN LET X=X+A 90 IF INKEY$="0" THEN LET P=0 100 IF INKEY$="1" THEN LET P=A 110 IF INKEY$="S" THEN SAVE A$ 120 IF X>63 THEN LET X=X-A 130 IF Y>41 THEN LET Y=Y-A 140 GOTO 30 150 IF INKEY$="0" THEN GOTO 30 160 IF INKEY$="S" THEN SAVE A$ 170 GOTO 100 180 CLEAR 190 SAVE "1030%3" 200 RUN ```