Plotter

Date: 1984
Type: Program
Platform(s): TS 2068
Tags: Art, Graphics

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

KeyAction
5 / 8Move cursor left / right (X axis)
6 / 7Move cursor down / up (Y axis)
DEnter draw mode
MEnter move/erase mode
IEnter text placement mode
ZCOPY screen to printer
VClear screen (CLS)
SSave screen to tape
LLoad screen from tape
QQuit 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.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

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 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top