Graph

Date: 198x
Type: Program
Platform(s): TS 2068

This program is an interactive user-defined graphic (UDG) editor that lets the user design a custom character by entering binary pixel data row by row. It first draws a bordered graph grid using PLOT and DRAW commands, then prompts the user to select which UDG letter (a–u) they want to define. For each of the eight rows of the 8×8 character, the user inputs eight bits (0 or 1) one keypress at a time, with a “2” option to restart the current row; the program converts each row’s binary sequence to a decimal value using powers of 2 and writes it directly to UDG memory with POKE USR. After all eight rows are entered, the finished character is displayed on screen, and the user can either send output to a printer with COPY or restart to define another UDG.


Program Structure

The program divides into four logical phases:

  1. Grid drawing (lines 10–95): Uses PLOT and DRAW to construct a bordered graph grid on the lower portion of the screen, with vertical and horizontal divider lines drawn using nested FOR loops.
  2. UDG selection (lines 140–188): Prompts the user — with FLASH 1 — to type the letter (a–u) of the UDG slot to define, then clears the top lines.
  3. Pixel entry loop (lines 190–420): The main editor. For each of the 8 rows (FOR a=0 TO 7) and each of the 8 bit columns (FOR b=0 TO 7), the program reads a keypress of 0, 1, or 2, accumulates a binary-to-decimal value, displays the pixel state, then POKEs the result into UDG memory.
  4. Output and restart (lines 424–490): Clears the status area, displays the finished UDG character, offers a COPY to printer or RUN to restart.

Key BASIC Idioms

  • INKEY$ debounce pair (lines 223–224): IF INKEY$ <>"" THEN GO TO 223 waits for any held key to be released, then IF INKEY$="" THEN GO TO 224 waits for a new keypress — a classic reliable single-keypress capture idiom.
  • Binary-to-decimal conversion (lines 240–260): Each bit’s contribution is computed as c * 2↑(7-b) and accumulated in f, correctly building the byte value with the most-significant bit first.
  • POKE USR (line 415): POKE USR a$+a,f writes each computed row byte directly to the UDG definition table in RAM, which is the standard method for defining custom characters at runtime.
  • Row restart (line 235): Entering “2” branches back to GO TO 210, resetting f=0 and re-running the inner bit loop for that row, allowing corrections.

Variable Usage

VariablePurpose
a$UDG letter chosen by user (a–u)
aCurrent row index (0–7)
bCurrent bit/column index within row (0–7)
cCurrent bit value (0 or 1) from keypress
dPlace value: 2↑(7-b)
eBit contribution: c*d
fAccumulated byte value for the current row
g, hLoop counters for grid drawing and screen clearing
c$User’s choice at end: copy or new

Notable Techniques

  • The grid is drawn entirely with PLOT/DRAW primitives rather than PRINT, giving pixel-precise placement independent of the character grid.
  • The pixel preview at line 270–280 uses PRINT AT 7+a,14+b to display a filled block or space in the correct screen position as each bit is entered, giving real-time visual feedback.
  • Line 290 additionally prints the numeric bit value (c) at column b, and line 410 prints the running decimal total f at column 27, so the user can verify the conversion.

Bugs and Anomalies

  • Variable h reused as loop variable: h is used as the outer loop counter in multiple independent FOR/NEXT blocks (lines 97, 424), and also as the inner loop counter at line 105 while still nominally active at line 97. This works only because the outer h loop at line 97 is effectively replaced, but it is fragile and non-standard.
  • Case inconsistency (line 430): The program instructs the user to enter lowercase letters, stores the input in a$, but displays A$ (uppercase variable name) at line 430. In Sinclair BASIC, a$ and A$ are the same variable, so this works correctly but is stylistically inconsistent with the rest of the program.
  • INKEY$ race at lines 225–235: The three consecutive IF INKEY$=... tests each independently read the keyboard. If the key is released between tests, only the first matching condition fires; if held, all three are evaluated. For keys “0” and “1” this is harmless, but pressing “2” could theoretically also pass the “0” or “1” tests if the key state changes between lines — in practice the fast sequential execution makes this unlikely.
  • No input validation: If the user enters a character outside the 0/1/2 set, the variable c retains its previous value and the row silently accumulates a repeated bit, with no error message.

Image Gallery

Source Code

   5 REM USER DEFINED GRAPHIC
   8 BORDER 4
  10 PLOT 112 ,119
  20 DRAW 63,0
  30 DRAW 0,-63
  40 DRAW -63,0
  50 DRAW 0,63
  60 DRAW 7,0
  65 FOR g=1 TO 6
  70 DRAW 0,-63
  80 DRAW 8,0
  90 DRAW 0,63
  92 NEXT g
  95 DRAW 8,0
  97 FOR h=1 TO 4
 100 DRAW 0,-8
 105 FOR h=1 TO 6
 110 DRAW -63,0
 120 DRAW 0,-8
 130 DRAW 63,0
 135 NEXT h
 140 FLASH 1:PRINT "ENTER YOUR LETTER ":FLASH 0
 150 PRINT "(a-u,in small case)"
 160 PRINT "FOR USER GRAPHIC"
 170 INPUT a$
 180 FOR h=0 TO 2
 185 FOR g=0 TO 31:PRINT AT h,g;" ":NEXT g
 188 NEXT h
 190 PRINT ; AT 0,0;"ENTER EITHER 0 FOR BLANK"
 193 PRINT "             1 FOR █"
 195 PRINT "             2 TO REWRITE LINE"
 200 FOR a=0 TO 7
 210 LET f=0
 220 FOR b=0 TO 7
 223 IF INKEY$ <>"" THEN GO TO 223
 224 IF INKEY$="" THEN GO TO 224
 225 IF INKEY$="1" THEN LET c=1
 230 IF INKEY$="0" THEN LET c=0
 235 IF INKEY$="2" THEN GO TO 210
 237 REM  Bin to Dec
 240 LET d=2↑(7-b)
 250 LET e=c*d
 260 LET f=e+f
 270 IF c=1 THEN PRINT AT 7+a,14+b;"█"
 280 IF c=0 THEN PRINT AT 7+a,14+b;" "
 290 PRINT AT 7+a,b;c
 400 NEXT b
 410 PRINT AT 7+a,27;f
 415 POKE USR a$+a,f
 417 BEEP 0.25,0
 420 NEXT a
 424 FOR h=0 TO 2
 425 FOR g=0 TO 31:PRINT AT h,g;" ":NEXT g
 426 NEXT h
 430 PRINT AT 4,16;A$;"= "; CHR$ (CODE A$+47)
 450 BEEP 1,3
 460 REM COPY
 470 INPUT "Press (c) for COPY---(n) for new";c$
 480 IF c$="c" THEN COPY 
 490 IF c$="n" THEN RUN 

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