--- title: "Plotter" id: 55068 type: "computer_media" slug: "plotter" url: "http://localhost/computer_media/plotter/" markdown_url: "http://localhost/computer_media/plotter.md" published_at: "2024-06-14T01:24:05+00:00" modified_at: "2026-03-30T21:44:45+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "A cursor-driven freehand plotter lets you draw, erase, and annotate the high-resolution screen with keyboard controls, then save or print your artwork." 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 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "Gary Swartz" slug: "gary-swartz" taxonomy: "indiv" url: "http://localhost/indiv/gary-swartz/" - name: "Harry Johnson III" slug: "harry-johnson-iii" taxonomy: "indiv" url: "http://localhost/indiv/harry-johnson-iii/" genre: - name: "Art" slug: "art" taxonomy: "genre" url: "http://localhost/type/art/" - name: "Graphics" slug: "graphics" taxonomy: "genre" url: "http://localhost/type/graphics/" media_type: "Program" programmers: - name: "Harry Johnson III" slug: "harry-johnson-iii" taxonomy: "indiv" url: "http://localhost/indiv/harry-johnson-iii/" - name: "Gary Swartz" slug: "gary-swartz" taxonomy: "indiv" url: "http://localhost/indiv/gary-swartz/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Plotter%20%28198x%29%28Johnson%2C%20Harry%3B%20Swartz%2C%20Gary%3B%20Marion%2C%20John%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "1984" related_content: - id: 16182 title: "Listing: A Text and Graphics Program" type: "article" url: "http://localhost/article/listing-a-text-and-graphics-program/" media_type_tags: "Art, Graphics" --- # Plotter This program is a freehand drawing utility that allows the user to move a cursor around the high-resolution graphics screen using the arrow keys (5, 6, 7, 8), toggling between a draw mode and a move/erase mode. It supports text placement at an arbitrary screen position, screen save and load via SCREEN$ commands, and hardcopy output via the COPY statement to a compatible printer. The program uses OVER 1 plotting to draw and OVER 0 to erase, exploiting the XOR-like behavior of the OVER attribute for pixel toggling. Originally written by Harry W. Johnson and Gary L. Swartz in 1984, it was subsequently revised for the TS2068 by John Marion. *** ## Program Analysis ### Program Structure The program is organized into several distinct functional blocks: 1. **Lines 10–190:** Main initialization and drawing loop. Sets up the screen, initializes cursor position at (110, 80), and continuously polls `INKEY$` to move the cursor and dispatch to subroutines. 2. **Lines 200–450:** Help/intro subroutine displaying key bindings across two screenfuls, waiting for a keypress between pages using `PAUSE 4E4`. 3. **Lines 500–640:** Text placement mode — moves a `>` cursor character around the text grid, then accepts an `INPUT` string and prints it at the chosen position. 4. **Lines 700–730:** Screen save routine using `SAVE A$SCREEN$`. 5. **Lines 750–770:** Screen load routine using `LOAD A$SCREEN$`. 6. **Lines 800–810:** Program self-save with `SAVE "PLOTTER" LINE 10` followed by `RUN` (never reached in normal execution). ### Drawing Mechanism The draw/move toggle is controlled by the variable `MODE`. In draw mode (`MODE=1`, lines 160), the program executes `OVER 1: PLOT X,Y: OVER 0: PLOT X,Y`. The first `PLOT` with `OVER 1` XORs the pixel on, and the immediate second `PLOT` with `OVER 0` sets it unconditionally — the net result is that the pixel is always set, leaving a trail. In move/erase mode (`MODE=0`, lines 180), the sequence is reversed: `OVER 0: PLOT X,Y: OVER 1: PLOT X,Y`, which sets then XORs, toggling the pixel off and allowing the cursor to move without drawing. This double-plot idiom is a well-known Spectrum technique for cursor visibility: the pixel under the cursor is always visible to the user regardless of the background, though here it is repurposed for draw/erase switching. ### Key Bindings | Key | Action | | --- | --- | | 5 / 8 | Move cursor left / right (X axis) | | 6 / 7 | Move cursor down / up (Y axis) | | D | Enter draw mode | | M | Enter move/erase mode | | I | Enter text placement mode | | Z | COPY screen to printer | | V | Clear screen (CLS) | | S | Save screen to tape | | L | Load screen from tape | | Q | Quit to line 1000 (non-existent — exits to BASIC) | ### Movement and Boundary Clamping Cursor movement is handled by evaluating boolean expressions as integers: `LET X=X+(INKEY$="8")-(INKEY$="5")` adds 1 or subtracts 1 in a single statement, a standard Sinclair BASIC idiom. Boundary checks at lines 60–90 clamp `Y` to 0–175 and `X` to 0–255, matching the Spectrum/TS2068 high-resolution pixel grid of 256×176. Note the Y upper bound of 175 rather than 176, leaving one pixel row unreachable at the top. ### Text Placement Mode (Lines 500–640) When the user presses `I`, the program switches to a character-cell cursor mode. A `>` marker is printed at the current text row (`L`) and column (`C`), and a short delay loop (`FOR V=1 TO 10`) provides a simple blink effect before erasing it with a space. Navigation uses keys 5/6/7/8 mapped to column/row movement. When `P` is pressed, an `INPUT` prompt collects a string `H$` which is then printed at that position. This lets the user annotate their drawing with arbitrary text. ### Notable Techniques and Anomalies - `POKE 23658,8` at line 10 sets the system variable `FLAGS2` to enable caps lock, ensuring key comparisons against uppercase letters work reliably without the user needing to engage caps lock manually. - `PAUSE 4E4` (40,000 frames ≈ 27 minutes) in the help pages is effectively a “wait for any key” idiom on this platform, since any keypress interrupts `PAUSE`. - The main loop polls `INKEY$` independently on nearly every line (40 through 145), meaning a key held during movement could simultaneously trigger a mode switch or command dispatch — a minor input-handling weakness. - `GO TO 1000` at line 135 (the Q/quit action) targets a non-existent line, which causes the program to terminate and return to the BASIC prompt — a deliberate exit technique. - The title screen references “2968” (line 250) where “2068” (TS2068) is clearly intended — this is a typo in the original listing. - Lines 800–810 provide a self-save block that is never reached during normal operation but allows the developer to save the program by manually running from line 800. ## Source Code ``` 10 POKE 23658,8: GO SUB 200 20 LET X=110: LET Y=80 30 LET MODE=1 40 LET X=X+(INKEY$="8")-(INKEY$="5") 50 LET Y=Y+(INKEY$="7")-(INKEY$="6") 60 IF Y>175 THEN LET Y=175 70 IF Y<0 THEN LET Y=0 80 IF X>255 THEN LET X=255 90 IF X<0 THEN LET X=0 100 IF INKEY$="M" THEN LET MODE=0 110 IF INKEY$="D" THEN LET MODE=1 120 IF INKEY$="Z" THEN COPY 125 IF INKEY$="V" THEN CLS 130 IF INKEY$="I" THEN GO TO 500 135 IF INKEY$="Q" THEN GO TO 1000 140 IF INKEY$="S" THEN GO TO 700 145 IF INKEY$="L" THEN GO TO 750 150 IF MODE=0 THEN GO TO 180 160 OVER 1: PLOT X,Y: OVER 0: PLOT X,Y 170 GO TO 40 180 OVER 0: PLOT X,Y: OVER 1: PLOT X,Y 190 GO TO 40 200 CLS 210 PRINT AT 1,10;"*PLOTTER*" 220 PRINT ,," BY HARRY W. JOHNSON " 230 PRINT ,," AND GARY L. SWARTZ 1984 " 240 PRINT ,," " 250 PRINT ,,"REVISED FOR 2968 BY JOHN MARION " 260 PRINT ,,"KEY ""M"" TO MOVE WITH OUT" 270 PRINT "PLOTTING OR TO ERASE." 280 PRINT ,,"KEY ""D"" TO DRAW." 290 PRINT ,, "KEY ""Z"" TO COPY TO 2040 PRINTER." 300 PRINT ,,"MOVE USING THE ARROW KEYS." 310 PRINT ,," PRESS ANY KEY TO CONTINUE " 320 PAUSE 4E4 330 CLS 340 PRINT AT 1,10;"*PLOTTER*" 350 PRINT ,,"KEY ""I"" TO ENTER TEXT." 360 PRINT "POSITION CURSOR THEN KEY ""P""" 370 PRINT "ENTER YOUR TEXT, IT WILL APPEAR" 380 PRINT "AT CURSOR POINT." 390 PRINT ,,"KEY ""S"" TO SAVE SCREEN" 400 PRINT ,,"KEY ""L"" TO LOAD SCREEN" 405 PRINT ,,"KEY ""V"" TO CLEAR SCREEN" 410 PRINT ,,"KEY ""Q"" TO QUIT PROGRAM" 420 PRINT ,," PRESS ANY KEY TO CONTINUE " 430 PAUSE 4E4 440 CLS 450 RETURN 500 OVER 0: LET L=21: LET C=0 510 IF L>21 THEN LET L=21 520 IF L<0 THEN LET L=0 530 IF C>31 THEN LET C=31 540 IF C<0 THEN LET C=0 550 PRINT AT L,C;">" 555 FOR V=1 TO 10: NEXT V 560 PRINT AT L,C;" " 570 LET L=L+(INKEY$="6")-(INKEY$="7") 580 LET C=C+(INKEY$="8")-(INKEY$="5") 590 IF INKEY$="P" THEN GO TO 610 600 GO TO 510 610 PRINT AT L,C;">" 620 INPUT H$ 630 PRINT AT L,C;" ";H$ 640 GO TO 40 700 INPUT "SAVE NAME";A$ 710 IF A$="" THEN GO TO 40 720 SAVE A$SCREEN$ 730 GO TO 40 750 INPUT "LOAD NAME";A$ 760 LOAD A$SCREEN$ 770 GO TO 40 800 SAVE "PLOTTER" LINE 10 810 RUN ```