Draw 512

Products: Draw 512
Developer(s): William McBrine
Date: 1989
Type: Program
Platform(s): TS 2068
Tags: Art

Draws and edits monochrome pictures at the TS2068’s full 512×192 resolution, or in the standard 256×192 mode, using the keyboard cursor keys or a joystick (left, right or Kempston). The cursor wraps around the screen edges, and holding CAPS SHIFT with a direction scrolls the whole picture one pixel at a time instead. Single keypresses select plot, unplot and over modes, lines, circles, boxes and filled boxes, mirror and flip, invert, and expand and compress in either direction. Two memory buffers, M1 and M2, hold extra screens, which can be swapped with the display or combined with it by OR, AND and XOR. Pictures can be moved between the narrow and wide modes, saved and loaded as screen files, and printed to a TS2040 or in two sizes to an Epson-type printer.

The zip holds two tapes. Version 1.1 (1989) is the main one: DRAW.BA and the 30 KB code file DRAW.CD, which also carries the HELP screen in M1 and the wide title screen in M2. It is followed by TITLE.C1 and TITLE.C2, a sample wide picture that loads with CAPS SHIFT+J and the name TITLE. Version 1.0 (1988) is on the second tape as DRAW.B1 and draw.C1. Version 1.1 adds RLE picture load and save (CAPS SHIFT+A and D) and all the SYMBOL SHIFT functions, including the zoom-style expand and compress. William McBrine’s two-part manual and his shareware notice (McBrine Computer Products, Salisbury, NC, suggested donation $10) are included as text.

Program Analysis

Program Structure

Nearly all of Draw 512 is machine code. The v1.1 BASIC is a set of short I/O lines that the code jumps to whenever it needs to load, save or print, so that the storage commands can be edited for another device. The manual lists the lines:

  • Line 10: RANDOMIZE USR 33024 to start the machine code
  • Lines 20–31: save a narrow screen, or a wide screen as two files
  • Lines 40–51: load a narrow or a two-part wide screen
  • Line 60: ask for a left margin and run the small Epson dump
  • Line 70: back up the program as name.BA and name.CD (code from 33024, 30208 bytes, which includes both buffers)
  • Line 80: return to the machine code after a tape operation
  • Lines 90–101: load an RLE file into the buffer area at 38656 and convert it, or convert the screen to RLE and save it
  • Lines 200–220: shared setup that sets the screen buffer address s=50944, length l=6144 and return line r=80
  • Line 9999: autorun loader that loads the code, does CLEAR 33023, initialises and runs

Files saved by the program are monochrome 6144-byte display files, without the attribute area. Each screen is first copied to M2 and saved from there, so the save prompts don’t end up in the picture. A wide screen is saved as two files. The buffers sit above the code: M1 at 38656 and 44800, M2 at 50944 and 57088, each 6144 bytes. In wide mode the program uses the second display file at 24576 and sets the ink and paper pair through port 255, choosing from the eight combinations that mode allows.

Version 1.0

Version 1.0 has its code at 35072 (15872 bytes) and returns to it at 35075. Its I/O lines prompt separately for the first and second file names of a wide screen, and the backup always saves under the fixed names DRAW.B1 and draw.C1. The loader shows the title for up to 30 seconds (PAUSE 1800) before the program starts.

Notable Techniques

  • The machine code handles all drawing and screen work, and uses BASIC only for device I/O. This kept the program easy to adapt to tape, disk or other storage.
  • Wide mode runs the TS2068’s two interleaved display files: even 8-pixel columns come from the first file and odd columns from the second. The expand, compress and convert functions move pictures between the modes.
  • The combine functions perform OR, AND and XOR between the display and a buffer. XOR can be undone by applying it a second time.
  • VAL "n" stands in for numeric constants throughout the BASIC, to save memory.
  • The RLE functions convert between a screen and the run-length-encoded ASCII picture format then exchanged by modem users. A file can be up to 24K, using both buffers as workspace.

Potential Issues

  • Version 1.1 appends .C1 and .C2 to screen file names, not the 1 and 2 the manual describes. On tape the base name can therefore be no more than seven characters. Narrow screens also get .C1.
  • Loading, saving and the small printout all overwrite M2. The manual warns that a picture kept there will be lost.
  • The manual warns that loading an RLE file longer than 24K will probably crash the program. A save whose RLE data exceeds 24K stops with error B, and the contents of M1 and M2 are lost.
  • In v1.0 the backup prompt only tests for an upper-case N, so any other key, including n, goes ahead with the save.

This copy comes from a Larken disk in the TS User Group collection (disk l-36). It was converted for tape: the LKDOS RANDOMIZE USR 100, OPEN #4 and PRINT #4: prefixes were removed, the disk CAT in v1.1 was replaced, and its stream variable was redirected to the screen. Both versions were tested in ZEsarUX.

Related Products

Drawing package. Works in 256×192 or 512×192. Draw, line, box, square, circle, invert, block invert, block erase, merge screens and more.

Image Gallery

Source Code

    0 REM DRAW 512 V1.1          *1989 Wm J. McBrine III
   10 RANDOMIZE USR VAL "33024"
   20 GO SUB VAL "200": INPUT " SAVE name: ";a$: IF LEN a$ THEN PRINT #f: SAVE a$+".C1"CODE s,l
   21 GO TO r
   30 GO SUB VAL "200": INPUT " SAVE name W: ";a$: IF LEN a$ THEN PRINT #f: SAVE a$+".C1"CODE s,l: PRINT #f: SAVE a$+".C2"CODE s+l,l
   31 GO TO r
   40 GO SUB VAL "200": INPUT " LOAD name: ";a$: IF LEN a$ THEN PRINT #f: LOAD a$+".C1"CODE s,l
   41 GO TO r
   50 GO SUB VAL "200": INPUT " LOAD name W: ";a$: IF LEN a$ THEN PRINT #f: LOAD a$+".C1"CODE s,l: PRINT #f: LOAD a$+".C2"CODE s+l,l
   51 GO TO r
   60 INPUT "Left margin: ";a: POKE VAL "33033",a+SGN PI: RANDOMIZE USR VAL "33030"
   70 GO SUB VAL "200": INPUT "BACKUP name: ";a$: IF LEN a$ THEN PRINT #f: SAVE a$+".BA" LINE VAL "9999": PRINT #f: SAVE a$+".CD"CODE VAL "33024",VAL "30208"
   80 INPUT INKEY$: RANDOMIZE USR VAL "33027"
   90 GO SUB VAL "200": INPUT " LOAD RLE name: ";a$: IF LEN a$ THEN PRINT #f: LOAD a$CODE VAL "38656": RANDOMIZE USR VAL "33038"
   91 GO TO r
  100 GO SUB VAL "200": INPUT " SAVE RLE name: ";a$: IF LEN a$ THEN LET a=USR VAL "33041": PRINT #f: SAVE a$CODE VAL "38656",a: RANDOMIZE USR VAL "33044"
  101 GO TO r
  200 ON ERR GO TO VAL "210"
  205 CLS : LET f=VAL "4": PRINT #f: CAT "",
  210 ON ERR RESET 
  215 LET s=VAL "50944": LET l=VAL "6144": LET r=VAL "80"
  220 RETURN 
 9999 RANDOMIZE USR VAL "100": OPEN #VAL "4","dd": PRINT #VAL "4": LOAD a$+".CD"CODE : CLEAR VAL "33023": RANDOMIZE USR VAL "33035": RUN

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