
	    An Introduction to Integral PC Technical BASIC Graphics

			      GVG / 13 October 1986


+ IPC Technical BASIC has a large command set; this command set includes many
operations for display graphics that allow a user to create sophisticated
imagery with little effort.  This note describes most of Tech BASIC's commands
for display graphics and provides examples for their use.

The Integral PC's built-in electroluminescent display has a display resolution
of 255 by 512 dots; when any Tech BASIC graphics command is invoked, Tech BASIC
brings up a graphics window that covers the entire display (except for the menu
keys, if they are left visible).

Tech BASIC regards this screen as a plotter that it draws on with an invisible
"pen".   Tech BASIC describes points on the display with the following
coordinate system:


       (0,100)                                                  (200,100)
	  +---------------------------------------------------------+
	  |                                                         |
	  |                                                         |
	  |                                                         |
	  |                                                         |
	  |                                                         |
	  |                                                         |
	  |                                                         |
	  |                                                         |
	  |                                                         |
	  |                                                         |
	  |                                                         |
	  |                                                         |
	  |                                                         |
	  +---------------------------------------------------------+
        (0,0)                                                    (200,0)


BASIC documentation refers to these coordinates as "graphics units", or GUs for
short.  

BASIC can move the pen from GU to GU without drawing a line with the MOVE
command, which has the form:

	MOVE x_coordinate, y_coordinate

Alternatively, BASIC can draw from point to point, using the DRAW command,
which has the form:

	DRAW x_coordinate, y_coordinate

                                                                             2

The program listed below uses the MOVE and DRAW commands to draw a little
triangle in the lower-left-hand corner of the display:

   example_1:

   10 ! This program demonstrates "absolute" moves and draws a tringle in    
   20 ! "graphics" coordinates.
   30 !
   40 PEN 1 @ GCLEAR @ LINE TYPE 1 @ SETGU !  Initializations (ignore for now).
   50 !
   60 MOVE 0,0 @ DRAW 10,0 @ DRAW 5,10 @ DRAW 0,0 
   70 !
   80 END 

Not much to this, except maybe for line 40, which performs some
initializations.  Except for the GCLEAR command (which wipes the graphics
display clean), pay no heed - they will all be explained quickly enough.


+ Anyone who tries to generate graphics with this limited amount of knowledge
will quickly realize that the coordinate system specified by Tech BASIC is not
convenient for many purposes.  For example, suppose a user wants to plot a
function that varies from -1 to +1; the user will then be forced to do a lot of
clumsy rescaling of from the values returned by the function to the actual
coordinates of the screen ...

... except that BASIC will do all of that for the user!  BASIC provides a SCALE
command that allows the user to specify his (or her) own coordinates for the
display.  (BASIC documentation refers to the user-defined coordinates as "user
units", or UUs for short.)   The SCALE command has the form:

	SCALE left, right, bottom, top

- where each of the four parameters specifies the user coordinate assigned to
the given side of the display - left side, right side, bottom, and top.

									     3

The following example rescales the display and then draws exactly the same
figure as the previous example - but in UUs instead the default GUs.  (Once a
SCALE statement is invoked, MOVE and DRAW act in UUs until they're told
otherwise ... more on that later.)

   example_2:

   10  ! This program demonstrates the "scale" command by rescaling the entire
   20  ! screen into "user" units - and then plotting the same figure as 
   30  ! plotted in example 1.  (Try changing the four coordinates for fun.)
   40  !
   50  PEN 1 @ GCLEAR @ LINE TYPE 1 @ SETGU !  Initializations - ignore them.
   60  !
   70  left=0 
   80  right=20
   90  bottom=0 
   100 top=20 
   110 !
   120 SCALE left,right,bottom,top !  Perform the mapping.
   130 !
   140 MOVE 1,1 @ DRAW 9,1 @ DRAW 5,9 @ DRAW 1,1 !  Draw a triangle.
   150 !
   160 END 

It's fun to switch coordinate values; switching the bottom and top values
creates upside-down images, and switching the left and right values creates
mirror images.


+ BASIC graphics are optimized for plotting line graphs and provide special
functions to make such plots easy.

The AXES command draws a set of coordinate axes on the display.  AXES has the
syntax:

	AXES x_spacing, y_spacing, x_origin, y_origin, x_major, y_major, size 

All the parameters are optional.  Before I describe them, however, let me make
a subtle point to make the description easier.

As I pointed out earlier, BASIC graphics uses two coordinate systems - either
default coordinates (GUs) or user-specified coordinates (UUs).  Some commands
(or parameters associated with commands) ALWAYS use the default GU coordinates;
a SCALE command has no effect on them.  Other commands use whatever coordinate
system is currently in effect, either GUs or UUs; the MOVE and DRAW commands
are good examples.  BASIC documentation refers to the coordinate system
currently in effect as "current units" - which sounds good enough to me.

Ahem!  To continue ...

									     4

If no parameters are specified, AXES draws a set of axes through the display's
(0,0) coordinate (as specified in current units), without drawing any tick marks
on the axes.

The first two parameters specify the spacing of tick marks on the coordinate
axes (in current units).  If no other parameters are specified, the AXES
command draws the axes through the (0,0) coordinate, and draws the tick marks 
with the specified spacing, with each tick 2 GUs in size.

The second two parameters specify the coordinates of the origin (in current
units).  The tick-spacing parameters must be specified if the origin is, but
tick marks can be disabled by setting the spacing parameters to zero.

The third two parameters allow the user to specify that every second, third,
fourth, (et cetera) tick be twice the size of the others.  The previous four
coordinates must be specified if these two are.  

If the "size" coordinate is not specified, the major ticks will be 2 GUs in
size, and the minor ticks will be 1 GU in size.  The size coordinate allows the
user to specify the size of the major tick marks (in GUs); the minor tick marks
will then be half the size of the major tick marks.

The following example uses the AXES command to place a set of axes on the
display:

   example_3:

   10  ! This program demonstrates the "axes" statement.  Try playing with the
   20  ! parameters for fun.  Note that the display is remapped from the 
   30  ! default "graphics" units to "user" units using the "scale" command.  
   40  ! (Note that all the parameters do NOT have to be specified.)
   50  !
   60  PEN 1 @ GCLEAR @ LINE TYPE 1 @ SETGU @ SCALE -100,100,-50,50 
   70  !
   80  x_tick=5 !        X-tick-mark every 5 user's units.
   90  y_tick=10 !       Y-tick-mark every 10 user's units.
   100 x_origin=0 !      Origin at (x,y) = (0,20) in user's units.
   110 y_origin=20 
   120 x_big_tick=4 !    Every fourth x-tick-mark is a big tick.
   130 y_big_tick=2 !    Every second y-tick-mark is a big tick.
   140 size_of_tick=10 ! Big ticks are four graphics units long.
   150 !
   160 AXES x_tick,y_tick,x_origin,y_origin,x_big_tick,y_big_tick,size_of_tick 
   170 !                                      
   180 END 


									     5

+ The GRID command is similar to the AXES command, but it allows the user to
create a grid on the screen.  Its syntax is similar to that of the AXES
command:

	GRID x_spacing, y_spacing, x_origin, y_origin, x_grid, y_grid, size 

If GRID is executed without parameters, a grid is drawn over the entire
display, using the current units for spacing.

The first two parameters specify the spacing of grid lines (in current units).
The second two parameters specify the coordinates of the origin (in current
units).  

The third two parameters allow the user to specify tick marks between grid
lines, with a grid line every second, third, fourth, or so on, tick mark, as
specified by the user.  The size coordinate allows the user to specify the size
of the tick marks (in GUs); if the "size" coordinate is not specified, the 
ticks will be 2 GUs in size.  

The following example uses the GRID command to place a grid on the display:

   example_4:

   10  ! This program demonstrates the GRID command; note that all the 
   20  ! parameters do NOT have to be specified.  Note also that the screen is
   30  ! remapped from graphics units to user units.
   40  !
   50  PEN 1 @ GCLEAR @ LINE TYPE 1 @ SETGU @ SCALE -100,100,-50,50 
   60  !
   70  x_tick=5 !       Ticks every five user units.
   80  y_tick=5 
   90  x_origin=-40 !   Grid origin at (-40,20).
   100 y_origin=20 
   110 x_big_tick=2 !   Grid lines every two ticks.
   120 y_big_tick=2 
   130 size_of_tick=4 ! Tick marks are four graphic units long.
   140 !
   150 GRID x_tick,y_tick,x_origin,y_origin,x_big_tick,y_big_tick,size_of_tick
   160 !                                      
   170 END 


                                                                            6

+ As I said in the beginning of this note, BASIC draws on the display with an
invisible "pen".  The user can specify four different types of "ink" for this
pen with the PEN command:

	PEN ink_value

The "ink_value"  can have four different values:

	>= 1:	plots white dots
	   0:   doesn't plot anything
          -1:   plots black dots
	  -2:   exclusive-ORs dots; the pen always writes dots the opposite
		color they were originally.

The PEN command has some peculiar synergisms with the GCLEAR command.  If the
Integral PC is turned on and NO windows are inverted from the usual
black-characters-on-white-background mode, then, when BASIC is invoked, the
BASIC window will be also in the black characters-on-white-background mode.
In this state, executing the following command sequences will cause the
following changes in the graphics window:

	PEN 1 @ GCLEAR		Turns graphics display black.
	PEN 0 @ GCLEAR		No change in graphics display.
	PEN -1 @ GCLEAR		Turns graphics display light.
	PEN -2 @ GCLEAR		Turns graphics display light.

This gets strange when the user turns a window to light-characters-on-black-
background mode.  Depending on the point in the sequence of window creation,
the command sequences specified above will either act as specified - or
have the opposite results.  (Anybody who wants to investigate all the special
cases has my blessing, but I have better things to do.  However, as far as
printer dumps using the DUMP GRAPHICS command are concerned, the table of
commands above will give the proper printout polarities - no matter what the
display mode is.)

Try this program to play with the PEN command:

   example_5:

   10  ! This program demonstrates the various pen types by specifying a pen,
   20  ! clearing the screen, drawing a box, specifying another pen (but NOT
   30  ! clearing the screen!), and drawing a diagonal crisscross the screen.   
   40  ! (There are four pen types: -2,-1,0,1.  Try them all.)
   50  !
   60  PEN 1 @ GCLEAR @ LINE TYPE 1 @ SCALE 0,100,0,50 
   70  !
   80  PEN -1 @ GCLEAR !           Change pen, clear the screen.
   90  MOVE 10,10 @ DRAW 90,10 @ DRAW 90,40 @ DRAW 10,40 @ DRAW 10,10 
   100 !               
   110 PEN -2 !                    Change the pen again.
   120 DRAW 90,40 @ DRAW 10,10 !   Draw a diagonal.
   130 !
   140 END 

									    7

+ The graphics pen can draw in eight different line types, as specified by the
LINE TYPE command - which has the syntax:

	LINE TYPE <value from 1 to 8>

The eight line types are as follows:

	LINE TYPE 1: solid line (default)
        LINE TYPE 2: no line ("null" line)
	LINE TYPE 3: dots
	LINE TYPE 4: short dashes
	LINE TYPE 5: long dashes
	LINE TYPE 6: dash-and-dot
	LINE TYPE 7: long-dash / short-dash
	LINE TYPE 8: long-dash / double short-dash

The following example illustrates the 8 line types:

   example_6:

   10  ! This program demonstrates the "line type" command by drawing figures 
   20  ! using the eight different line types.                                
   30  !
   40  PEN 1 @ GCLEAR @ SCALE 0,200,0,100 
   50  !
   60  MOVE 10,10 
   70  LINE TYPE 1 @ DRAW 10,90 
   80  LINE TYPE 2 @ DRAW 90,90 
   90  LINE TYPE 3 @ DRAW 90,10 
   100 LINE TYPE 4 @ DRAW 10,10 
   110 MOVE 110,10 
   120 LINE TYPE 5 @ DRAW 110,90 
   130 LINE TYPE 6 @ DRAW 190,90 
   140 LINE TYPE 7 @ DRAW 190,10 
   150 LINE TYPE 8 @ DRAW 110,10 
   160 !
   170 END 

									    8

+ So, far all the graphics examples have been drawn using ABSOLUTE grid
coordinates.  In some cases, however, it is more convenient to draw using
RELATIVE (or "incremental") coordinates - through the IMOVE (Incremental MOVE)
and IDRAW (Incremental DRAW) commands.  These commands have the syntax:

	IMOVE x_increment, y_increment

- and:

	IDRAW x_increment, y_increment

Suppose (X,Y) is a coordinate, specified in current units.  Then:

	IMOVE x_increment, y_increment 
	
 - moves the pen to the coordinate:  (X + x_increment, Y + y_increment). 

Incremental plotting is useful for drawing the same object at several places on
the display - as shown by the example below, which "bricks up" the display by
using IMOVE and IDRAW to draw a "brick" over and over again:

   example_7 ("Amontillado"):

   10  ! This program demonstrates the incrmental move and draw commands by 
   20  ! filling the screen up with "bricks".
   30  !
   40  PEN 1 @ GCLEAR @ LINE TYPE 1 @ SCALE 0,100,0,100 
   50  !
   60  MOVE 0,0 
   70  FOR rows=1 TO 10 
   80     FOR columns=1 TO 10 
   90        IMOVE 1,1 !               Draw a box.
   100       IDRAW 8,0 
   110       IDRAW 0,8 
   120       IDRAW -8,0 
   130       IDRAW 0,-8 
   140       IMOVE 9,-1 !              Move to the right and ...             
   150    NEXT columns !               ... draw the next box.
   160    IMOVE -100,10 !              Move up and back to the left side and ...
   170 NEXT rows !                     ... draw the next row of boxes.
   180 !               
   190 END 


                                                                            9

+ An interesting feature of incremental plotting is that it allows the
reference axes to be rotated though an angle - by using the PDIR (Plot
DIRECTION) command, which has the syntax:

	PDIR angle

What this means is simple enough.  Suppose a BASIC program has a command like
"IDRAW 9,0".  Given a scaling that doesn't do something silly like place
positive values to the left of the display, this command will draw a straight
line to the right.  However, if "PDIR 90" is executed, and BASIC is in DEGREES
mode, then "IDRAW 9,0" will draw the line straight up.

(Note that PDIR works only for incremental plotting.  Absolute plotting ignores
it.)

The following example uses PDIR to draw a "daisy wheel" on the display:

   example_8:

   10  ! This program demonstrates the "pdir" command (which changes the 
   20  ! drawing angle for incremental moves and draws) by drawing a "daisy 
   30  ! wheel".  (All the program does is draw a triangle with the starting 
   40  ! vertex at 0,0, then rotates ten degrees, draws the triangle again ... 
   50  ! and so on through the full circle.
   60  !
   70  PEN 1 @ GCLEAR @ DEG @ SCALE -100,100,-50,50 
   80  !    
   90  FOR angle=0 TO 360 STEP 10 
   100    PDIR angle !               Rotate ten degrees.
   110    MOVE 0,0 !                 Draw the triangle.
   120    IDRAW 40,0 
   130    IDRAW 0,3 
   140    IDRAW -40,-3 
   150 NEXT angle !                  Do it again.
   160 !               
   170 END 

(Users who are playing with PDIR should be careful to make sure that BASIC is
not in RADians mode when they are expressing PDIR in DEGrees, and vice-versa.)


+ As I said earlier, BASIC graphics are oriented towards plotting functions -
and, of course, plots needs labels.  Tech BASIC incorporates a number of
commands for making labels.

The first command is LABEL, which prints a label at the current pen position.
The label can be a string or a number, or any combination thereof; image
specifiers can be used as well.  (Indeed, the syntax of the LABEL command is
almost identical to that of the PRINT or DISP commands.)

									    10

The next command is CSIZE, which specifies the height of the characters in the
label (in GUs).  The syntax of CSIZE is:

	CSIZE size, aspect_ration, slant

The "size" parameter must be specified; the "aspect_ratio" (which specifies
the width/height ratio) and "slant" parameters are optional.  The following
program demonstrates the LABEL and CSIZE commands:

   example_9:

   10  ! This program illustrates the CSIZE command by showing the results of
   20  ! changing the size, aspect ration, and slant of the letter "M".
   30  ! 
   40  PEN 1 @ GCLEAR @ LORG 5 @ DEG @ SCALE 0,9,0,4 
   50  !
   60  size=1 !   Change sizes.
   70  FOR column=1 TO 8 
   80     MOVE column,3 @ CSIZE size @ LABEL USING "K" ; "M"
   90     size=size+5 
   100 NEXT column 
   110 !                             
   120 aspect_ratio=0.1 !   Change aspect ratios.
   130 FOR column=1 TO 8 
   140     MOVE column,2 @ CSIZE 8,aspect_ratio @ LABEL USING "K" ; "M"
   150     aspect_ratio=aspect_ratio+0.5 
   160 NEXT column 
   170 !                             
   180 slant=0 !   Change slants
   190 FOR column=1 TO 8 
   200    MOVE column,1 @ CSIZE 8,0.6,slant @ LABEL USING "K" ; "M"
   210    slant=slant+10 
   220 NEXT column 
   230 !                             
   240 END 

Note the LABEL USING "K" command ... the "K" image parameter needs to be
specified when using LABEL with a string parameter; the "K" parameter causes
all extraneous blanks to be removed from the string.

This is one of the peculiar differences between HP-86/87 BASIC and Tech BASIC.
HP-86/87 BASIC seems to work fine without using the "K" parameter, while labels
will almost invariably end up in the wrong place if the "K" parameter isn't
used.  For that reason: ALWAYS USE THE "K" PARAMETER WHEN LABELING WITH A
STRING IN TECH BASIC!  (I suspect the reason is that the internal data
structure of the string is different in the two BASICS - but I digress ... )

									    11

+ Labels can be written in different angles by using the LDIR (Label DIRection)
command.  This is similar to the PDIR command, but it works only for labels.
Its syntax is:

	LDIR angle

The following example demonstrates LDIR:

   example_10:

   10  ! This little program demonstrates the "label direction" command.    
   20  ! It prints the word "rotation" in a number of different angles.  
   30  !
   40  PEN 1 @ GCLEAR @ LORG 1 @ DEG @ CSIZE 6 @ SCALE -100,100,-50,50 
   50  !        
   60  FOR angle=0 TO 360 STEP 30 
   70     MOVE 0,0 
   80     LDIR angle 
   90     LABEL USING "K" ; "  rotation"
   100 NEXT angle 
   110 !
   120 END 

(As with the PDIR commands, users should be careful to remember whether they
are in RADians or DEGrees mode when they use this command.)


+ There's a fine point in plotting labels that I glossed over.  I said the
LABEL command plots a label at the current pen position ... but that begs the
question: where is the label situated on the display, relative to the pen
coordinate?  Above?  Below?  To the left?  To the right?  Centered on it?

The LORG (Label ORiGin) allows a user to specify the position of the label
relative to the pen.  LORG has the syntax:

	LORG label_origin

The "label_origin" parameter has values from 1 to 9.  Suppose the rectangle
shown below outlines a label;  the numbers on the rectangle are located at the
label origin given by the number:


			  3 ---------- 6 ---------- 9
			  |                         |
			  2            5            8
			  |                         |
			  1 ---------- 4 ---------- 7

									    12

The following example shows how LORG works:

   example_11:

   10  ! This program demonstrates the "lorg" (label origin) command by
   20  ! putting up a grid and then labeling the vertices of the grid -
   30  ! with the point of attachment of the label determined by the 
   40  ! "lorg" command.
   50  !
   60  PEN 1 @ GCLEAR @ CSIZE 8 @ LINE TYPE 1 @ FRAME 
   70  SCALE 0.75,3.25,0.75,3.25 @ GRID 1,1
   80  !        
   90  label_origin=1 
   100 FOR x_coordinate=1 TO 3 
   110    FOR y_coordinate=1 TO 3 
   120       MOVE x_coordinate,y_coordinate 
   130       LORG label_origin @ LABEL USING "K,DD" ; "LORG",label_origin
   140       label_origin=label_origin+1 
   150    NEXT y_coordinate 
   160 NEXT x_coordinate 
   170 !
   180 END 


+ Before I leave the subject of labels ... remember that I said LABEL can use
IMAGE statements, just like a PRINT or DISP statement?  The following example
demonstrates this by printing the same number using five different IMAGE
specifiers.

   example_12:

   10  ! This program demonstrates the "label using" statement by tacking up
   20  ! a number using different IMAGE formats.
   30  !
   40  PEN 1 @ GCLEAR @ CSIZE 11 @ LORG 5 
   50  LOCATE 0,200,0,100 @ SETGU @ SCALE -100,100,-50,50 
   60  !        
   70  number=1095.88376 
   80  !
   90  MOVE 50,25 @ LABEL USING "6Z" ; number
   100 MOVE -50,25 @ LABEL USING "6D.3D" ; number
   110 MOVE -50,-25 @ LABEL USING "6*.4D" ; number
   120 MOVE 50,-25 @ LABEL USING "DC3D.6D" ; number
   130 MOVE 0,0 @ LABEL USING "S5DE" ; number
   140 !
   150 END 

                                                                            13

+ Another thing that I glossed over earlier was a fine point about the SCALE
command.  I stated that the SCALE command was used to convert the display
window to user-defined coordinates.  This is the truth, but not the whole
truth - actually, a small chunk of the display window - call it a "windowpane"
- can be defined as the user's plotting area using the LOCATE command.  Once
this windowpane has been set aside, SCALE no longer scales the entire window
- it just scales the windowpane.

LOCATE has the syntax:

	LOCATE x_min, x_max, y_min, y_max

- where the four coordinates are in default GUs.

The following example sets aside a square in the middle of the display as the
user's plotting area, scales the square appropriately, and draws a lissajou
pattern in the square.

   example_13:

   10  ! This program demonstrates the "locate" command (and the "frame"
   20  ! command) by "locating" a user's plotting surface in a square in 
   30  ! in the center of the display - and plotting a lissajou pattern in
   40  ! the square.  (The phase and frequency of the sine function on the
   50  ! "y" axis relative to the sine function on the "x" axis can be
   60  ! adjusted by changing the "phase" and "rel_freq" variables.
   70  !
   80  PEN 1 @ GCLEAR @ LINE TYPE 1 @ RAD 
   90  !
   100 LOCATE 60,140,10,90 @ SCALE -1.1,1.1,-1.1,1.1 @ FRAME 
   110 !
   120 number_samples=300 
   130 angle_increment=2*PI/100 
   140 !
   150 phase=PI/6 
   160 rel_freq=3 
   170 !
   180 angle=0 
   190 MOVE SIN(angle),SIN(rel_freq*angle+phase) 
   200 !
   210 FOR sample=1 TO number_samples 
   220    angle=angle+angle_increment 
   230    DRAW SIN(angle),SIN(rel_freq*angle+phase) 
   240 NEXT sample 
   250 !                  
   260 END 

Note the use of the FRAME command; this draws a border around the area defined
by the LOCATE command.  (Note also that once a LOCATE has been put in effect,
SCALE commands refer to the windowpane defined by the LOCATE command.  To allow
the SCALE command to scale the entire graphics display window again, use the
command: LOCATE 0,200,0,100.)

									    14

By the way ... for those who don't know what a lissajou pattern is - it's a
plot created by using the value of one sine function as the x-value of a point
and the value of another sine function (at the same angle as the first) as the
y-value of the point; the resulting pattern can be be interpreted to discover
the relative phase and frequencies of the two sine waves.

Lissajou patterns were important in the days before sophisticated dual-trace
oscilloscopes; a engineer used the lissajou pattern to compare two signals by
plugging a reference signal into the x-axis input of a scope, and plugged the
signal to be measured into the y-axis input of a scope.  The resulting patterns
have a sort of hypnotic fascination; lissajou patterns are often seen on scopes
in old science-fiction movies and the like.  (You learn these things when you
get a vocational-school degree ... )

This example allows the user to tweak the relative phase and frequency of the
y-axis signal, and it is fun to do so and examine the results.  But, back to
the subject at hand ...


+ The AXES command allows the user to plot a set of axes, and the LABEL
statement allows the user to plot labels.  Since a user often wants to label
axes, BASIC provides a command that both plots axes and labels them: LAXES
(Label AXES).  

LAXES has the syntax:

	LAXES x_spacing, y_spacing, x_origin, y_origin, x_major, y_major, size 

The parameters are specified in exactly the same way as AXES; the only
important detail is that labels are plotted on each major tick.

The following example demonstrates the use of LAXES:

   example_14:

   10  PEN 1 @ GCLEAR @ CSIZE 4 @ LOCATE 20,180,20,80 @ SCALE 0,50,0,25 @ FRAME 
   20  !
   30  x_tick=5 
   40  y_tick=5 
   50  x_origin=0 
   60  y_origin=0 
   70  x_big_tick=1 
   80  y_big_tick=1 
   90  size_of_tick=10 
   100 !
   110 LAXES x_tick,y_tick,x_origin,y_origin,x_big_tick,y_big_tick,size_of_tick 
   120 !                                      
   130 END 

                                                                            15

The next example illustrates the use of LAXES in a practical application:
plotting a decaying sine wave:

   example_15:

   10  ! This program demonstrates the LAXES command by displaying a damped 
   20  ! sine wave.  (Note that the amplitude, time-constant, and frequency 
   30  ! can be modified.  Note also that, due to a bug, LAXES only works well 
   40  ! with integer labels.)
   50  !
   60  PEN 1 @ GCLEAR @ CSIZE 4 @ FRAME @ RAD @ LOCATE 20,180,20,80 
   70  !
   80  length_of_scan=10 @ number_samples=200 
   90  sample_size=length_of_scan/number_samples 
   100 !
   110 amp=5 @ tc=2 @ freq=1 
   120 !
   130 SCALE 0,length_of_scan,-amp,amp @ LAXES 1,1 
   140 !
   150 ctr=0 
   160 MOVE ctr,amp*EXP((-ctr)/tc)*SIN(2*PI*freq*ctr) 
   170 !
   180 FOR sample=1 TO number_samples 
   190    ctr=ctr+sample_size 
   200    DRAW ctr,amp*EXP((-ctr)/tc)*SIN(2*PI*freq*ctr) 
   210 NEXT sample 
   220 !                  
   230 END 

As the program notes, LAXES doesn't work worth a damn with fractional labels.
This is a clear bug in BASIC, but even if there wasn't a bug, LAXES doesn't
allow any way of specifying the format of the labels; other methods have to be
used if a specific format is desired.

									    16

The following program shows how to print fractional labels:

   example_16:

   10  ! This program draws a damped sine wave, like in the previous example
   20  ! except that the axis labels are not integers.  The actual labeling is
   30  ! done with two program loops.  Note that the loop that labels the "Y"
   40  ! axis has some special provisions for labeling the "0.0" value; this is
   50  ! necessary because Tech BASIC uses binary (not BCD!) numbers and the
   60  ! computation that was providing the "Y" axis values was providing a 
   70  ! value for "0.0" that was slightly less than zero.
   80  !
   90  PEN 1 @ GCLEAR @ CSIZE 3 @ RAD @ LOCATE 20,180,20,80 @ FRAME 
   100 !
   110 length_of_scan=1 @ number_samples=200 
   120 sample_size=length_of_scan/number_samples 
   130 !
   140 amp=1 @ tc=0.3 @ freq=10 
   150 !
   160 SCALE 0,length_of_scan,-amp,amp 
   170 !
   180 number_of_ticks=10 
   190 x_tick=length_of_scan/number_of_ticks 
   200 y_tick=amp/(number_of_ticks/2) 
   210 AXES x_tick,y_tick 
   220 !
   230 label_value=0 @ LDIR PI/2 @ LORG 8 !           Label the X-axis.
   240 Label_X_Axis: 
   250    MOVE label_value,-amp 
   260    LABEL USING "DZ.DD,K" ; label_value," "
   270    label_value=label_value+x_tick 
   280 IF label_value<=length_of_scan THEN GOTO Label_X_Axis 
   290 !
   300 label_value=-amp @ LDIR 0 @ LORG 8 !           Label the Y-axis.
   310 Label_Y_Axis: 
   320    MOVE 0,label_value 
   330    IF ABS(label_value)<y_tick/100000 THEN Label_Zero 
   340 !          
   350    LABEL USING "DZ.DD,K" ; label_value," "
   360    GOTO Increment_Value 
   370 !
   380 Label_Zero: 
   390    LABEL USING "K" ; "0.0  " !                 Label the "zero" case.
   400 !
   410 Increment_Value:   
   420    label_value=label_value+y_tick 
   430 IF label_value<=amp THEN GOTO Label_Y_Axis 
   440 !

									    17

   450 ctr=0 
   460 MOVE ctr,amp*EXP((-ctr)/tc)*SIN(2*PI*freq*ctr) 
   470 !
   480 FOR sample=1 TO number_samples 
   490    ctr=ctr+sample_size 
   500    DRAW ctr,amp*EXP((-ctr)/tc)*SIN(2*PI*freq*ctr) 
   510 NEXT sample 
   520 !                  
   530 END 

This program goes through two loops, counting up each axis and depositing a
label as it increments the count.  Note that the LABEL command pads a blank
after the label value; this keeps the label from butting up against the axis.

Note also the peculiar jiggery-pokery performed in the loop that labels the
y-axis.  This is necessary because Tech BASIC uses binary instead of BCD
numbers; adding up fractions that would equal zero in decimal do NOT exactly
equal zero when binary is used; before I included the adjustments, I kept
ending up with a negative "zero".


+ Back in the beginning of this document, I discussed the difference between
GUs (the default coordinate system) and UUs (the user-specified coordinate
system).  One of the points I brought out was that some commands - the DRAW
command, for example - used either GUs or UUS, depending on which was in effect
at the time.

The user can toggle between using GUs and UUs by using the SETGU and SETUU
commands.  If SETGU is executed, commands like DRAW will use GUs until told to
do different; if SETUU is executed, commands like DRAW will use UUs until told
to do different.

									    18

The following example illustrates the use of SETGU and SETUU by using exactly
the same instructions to draw a "picture frame" in UUs and GUs.  

   example_17:

   10  ! This program illustrates the concept of graphics units and user units
   20  ! (as well as the SETUU and SETGU commands) by plotting a frame and a 
   30  ! label in both graphics and user units - using exactly the same code.
   40  ! Note that the user units are scaled into a small region of the 
   50  ! display.  Note also that the labels do NOT scale, as labels are always
   60  ! measured in graphics units.
   70  !
   80  PEN 1 @ GCLEAR @ CSIZE 4 @ LINE TYPE 1 @ LORG 6 
   90  LOCATE 50,150,30,70 @ SCALE 0,200,0,100 
   100 !
   110 FOR units=1 TO 2 
   120    IF units=1 THEN SETUU @ a$="User Units" 
   130    IF units=2 THEN SETGU @ a$="Graphics Units" 
   140    MOVE 10,10 @ DRAW 10,90 @ DRAW 190,90 @ DRAW 190,10 @ DRAW 10,10 
   150    DRAW 15,15 @ DRAW 15,85 @ DRAW 10,90 @ MOVE 15,85 @ DRAW 185,85 
   160    DRAW 190,90 @ MOVE 185,85 @ DRAW 185,15 @ DRAW 190,10 @ MOVE 185,15 
   170    DRAW 15,15 
   180    MOVE 100,8 @ LABEL USING "K" ; a$
   190 NEXT units 
   200 SETUU 
   210 !
   220 END 


+ The SCALE command, as I explained earlier, allows a user to remap the
graphics display (or a portion of it, as defined by LOCATE) into any set of
coordinates the user wants.  The SHOW command is similar - except that SHOW
guarantees that both the x- and y-axis will have similar dimensions, no matter
what the user's coordinates are.

                                                                            19

What this means is that the distance between, say, x=0 and x=1, as measured on
the display will be the same as the distance between y=0 and y=1 on the
display - no matter what kind of grid the user specifies.  The following
example demonstrates SHOW:

   example_18:

   10  ! This program illustrates the difference between SCALE and SHOW by 
   20  ! comparing the same figure, drawn using exactly the same parameters
   30  ! for both commands.
   40  !
   50  DEG @ PEN 1 @ GCLEAR @ CSIZE 8 @ LORG 5 @ LINE TYPE 1 
   60  LOCATE 10,90,10,90 @ FRAME 
   70  !         
   80  xmin=-1 
   90  xmax=1 
   100 ymin=-2 
   110 ymax=2 
   120 !                                                        
   130 SCALE xmin,xmax,ymin,ymax @ GRID 1,1
   140 !                                                                     
   150 MOVE SIN(0),COS(0) 
   160 FOR angle=0 TO 360 STEP 5 
   170    DRAW SIN(angle),COS(angle) 
   180 NEXT angle 
   190 SETGU @ MOVE 50,5 @ LABEL USING "K" ; "Scale" @ SETUU 
   200 !
   210 LOCATE 110,190,10,90 @ FRAME 
   220 SHOW xmin,xmax,ymin,ymax @ GRID 1,1
   230 !                                                                     
   240 MOVE SIN(0),COS(0) 
   250 FOR angle=0 TO 360 STEP 5 
   260    DRAW SIN(angle),COS(angle) 
   270 NEXT angle 
   280 SETGU @ MOVE 150,5 @ LABEL USING "K" ; "Show" @ SETUU 
   290 !        
   300 END 

(Try as I might, I cannot think of a good use for this command, but here it is,
for anyone who wants to use it ...)

                                                                            20

+ The LOCATE command allows the user to set aside part of the display as a user
plotting area.  Another command, CLIP, allows the user to define a "windowpane"
in the user's plotting area to display plots within the plotting area.

CLIP has the syntax:

	CLIP x_min, x_max, y_min, y_max

The CLIP coordinates are in current units.  Once CLIP has been invoked, DRAW,
AXES, GRID, and other drawing commands are effective only in the CLIP
windowpane.  (LABELS ignore the CLIP boundary.)

The following example demonstrates the use of CLIP:

   example_19:	

   10  ! This example demonstrates the CLIP command by drawing grids and vectors
   20  ! inside clipped rectangles.
   30  !
   40  PEN 1 @ GCLEAR @ LINE TYPE 1 @ LOCATE 10,190,10,90 @ FRAME @ DEG 
   50  SCALE 0,20,0,10 
   60  !
   70  CLIP 2,8,2,8 @ GRID 1,1
   80  !                 
   90  CLIP 10,18,4,8 @ FRAME 
   100 FOR angle=0 TO 360 STEP 3 
   110    MOVE 14,6 
   120    PDIR angle 
   130    IDRAW 3,0 
   140 NEXT angle 
   150 !
   160 MOVE 10,1 @ CSIZE 8 @ LORG 5 @ LABEL USING "K" ; "Fun with clipping!"
   170 !         
   180 END 

                                                                            21

+ The next command I'll demonstrate allows a user to paint "bitmaps" on the
display.  It's called BPLOT, and has the syntax:

	BPLOT array_of_characters, byte_width

A bitmap is an array of binary bits that is mapped directly to a portion of the
display.  Each "1" bit in the bitmap turns on the corresponding pixel in the
display; each "0" bitmap turns off the corresponding pixel on the display. 

For example, a bitmap to display a tiny square on the display has the form:

				    00000000
				    01111110
				    01000010
				    01000010
				    01000010
				    01000010
				    01111110
				    00000000

BPLOT is a little fussy about how the bitmap is specified.  The bitmap can any
number of rows (within the limits of the display) but it must be some multiple
of 16 bits wide - 16, 32, 48, 64, et cetera ...

The bitmap is stored in a character array, which is the first parameter for
BPLOT.  The second parameter specifies how many bytes are used to make a single
row of the bitmap - and the second parameter MUST BE A MULTIPLE OF 2, due to
the 16-bit width restriction.

So - making a bitmap involves the following recipe:

	1: Create the bitmap as a grid of 1's and 0's; the grid must be
	   a multiple of 16 bits wide.

	2: Divide the divide the grid into 8-bit columns and convert each
	   8-bit quantity into its decimal equivalent.

	3: Create a list of the decimal codes for the bitmap (either as a 
	   file or as part of a DATA statement) for the BASIC program.

	4: The program should read the list into consecutive elements of a
	   character array, using the CHR$ command to convert the decimal
	   number into its 8-bit ASCII equivalent.  (The long way around from
	   8-bit binary to decimal and back to 8-bit binary again ... sorry, I
	   don't know a better way to do it.)

	5: The program should then move the pen to the desired point on the
	   display and use the BPLOT command (with the name of the character
	   array and the byte width as parameters) to dump the bitmap to the 
	   display.

Note that the bitmap will always be plotted "down" and "to-the-right", no
matter how the display has been SCALEd.

									    22

For example, consider the following bitmap, which defines a 16-by-19-bit chess
king.  The bitmap is expressed as a bit array, which is then compressed into
hexadecimal - to make it easier to convert to decimal.

                  bitmap pattern                     hex        decimal
         _________________________________          _____        _____

	 0 0 0 1 1 0 0 0   0 0 0 0 0 0 0 0          18 00         24,0
	 0 0 1 1 1 1 0 0   0 0 0 0 0 0 0 0          3C 00         60,0
	 0 0 1 1 1 1 0 0   0 0 0 0 0 0 0 0          3C 00         60,0
	 0 0 0 1 1 0 0 0   0 0 0 0 0 0 0 0          18 00         24,0
	 0 1 1 1 1 1 1 0   0 0 0 0 0 0 0 0          7E 00        126,0
	 0 0 1 1 1 1 0 0   0 0 0 0 0 0 0 0          3C 00         60,0
	 0 0 0 1 1 0 0 0   0 0 0 0 0 0 0 0          18 00         24,0
	 0 0 1 1 1 1 0 0   0 0 0 0 0 0 0 0          3C 00         60,0
	 0 0 0 1 1 0 0 0   0 0 0 0 0 0 0 0          18 00         24,0
	 0 0 0 1 1 0 0 0   0 0 0 0 0 0 0 0          18 00         24,0
	 0 0 0 1 1 0 0 0   0 0 0 0 0 0 0 0          18 00         24,0
	 0 0 0 1 1 0 0 0   0 0 0 0 0 0 0 0          18 00         24,0
	 0 0 1 1 1 1 0 0   0 0 0 0 0 0 0 0          3C 00         60,0
	 0 0 1 1 1 1 0 0   0 0 0 0 0 0 0 0          3C 00         60,0
	 0 0 1 1 1 1 0 0   0 0 0 0 0 0 0 0          3C 00         60,0
	 0 1 1 1 1 1 1 0   0 0 0 0 0 0 0 0          7E 00        126,0
	 0 1 1 1 1 1 1 0   0 0 0 0 0 0 0 0          7E 00        126,0
	 1 1 1 1 1 1 1 1   0 0 0 0 0 0 0 0          FF 00        255,0
	 1 1 1 1 1 1 1 1   0 0 0 0 0 0 0 0          FF 00        255,0
         _________________________________          _____        _____


This gives the following program statements:

   10  OPTION BASE 1
   20  DIM black_king$[38]
       ... 
   50  DATA 24,0,60,0,60,0,24,0,126,0,60,0,24,0,60,0,24,0,24,0,24,0,24,0
   60  DATA 60,0,60,0,60,0,126,0,126,0,255,0,255,0
       ...
   120 FOR counter=1 to 38
   130    READ temp @ black_king$[counter] = CHR$(temp)
   140 NEXT counter
       ...
   250 MOVE somewhere,someplace
   260 BPLOT black_king$, 2

									    23

The following example creates a chessboard on the display using BPLOT:

   example_20:

   10  ! This program demonstrates the BPLOT command with a chessboard.
   20  !
   30  PEN 1 @ GCLEAR @ LINE TYPE 1 @ LOCATE 0,200,0,100 @ SCALE 0,511,0,254 
   40  CLIP 139,371,11,243 @ FRAME @ GRID 29,29,139,11 @ OPTION BASE 1
   50  !
   60  DIM black_pawn$[38],black_rook$[38],black_bishop$[38],black_knight$[38]
   70  DIM black_king$[38],black_queen$[38]
   80  !
   90  DIM white_pawn$[38],white_rook$[38],white_bishop$[38],white_knight$[38]
   100 DIM white_king$[38],white_queen$[38]
   110 !
   120 DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,60,0
   130 DATA 60,0,24,0,60,0,24,0,24,0,24,0,60,0,126,0,126,0
   140 DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,90,0,126,0,126,0
   150 DATA 60,0,60,0,60,0,60,0,60,0,60,0,126,0,255,0,255,0
   160 DATA 0,0,0,0,0,0,0,0,24,0,24,0,60,0,126,0,60,0,24,0
   170 DATA 60,0,24,0,24,0,24,0,60,0,60,0,126,0,255,0,255,0
   180 DATA 0,0,0,0,0,0,0,0,0,0,24,0,60,0,122,0,255,0,255,0
   190 DATA 248,0,240,0,248,0,124,0,62,0,60,0,126,0,255,0,255,0
   200 DATA 24,0,60,0,60,0,24,0,126,0,60,0,24,0,60,0,24,0,24,0
   210 DATA 24,0,24,0,60,0,60,0,60,0,126,0,126,0,255,0,255,0
   220 DATA 0,0,0,0,90,0,60,0,60,0,24,0,24,0,60,0,24,0,24,0
   230 DATA 24,0,24,0,60,0,60,0,60,0,126,0,126,0,255,0,255,0
   240 !
   250 DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,36,0
   260 DATA 36,0,24,0,36,0,24,0,24,0,24,0,36,0,66,0,126,0
   270 DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,90,0,126,0,66,0
   280 DATA 36,0,36,0,36,0,36,0,36,0,36,0,66,0,129,0,255,0
   290 DATA 0,0,0,0,0,0,0,0,24,0,24,0,36,0,66,0,36,0,24,0
   300 DATA 36,0,24,0,24,0,24,0,36,0,36,0,66,0,129,0,255,0
   310 DATA 0,0,0,0,0,0,0,0,0,0,24,0,36,0,66,0,129,0,135,0
   320 DATA 136,0,144,0,136,0,68,0,34,0,36,0,66,0,129,0,255,0
   330 DATA 24,0,36,0,36,0,24,0,126,0,36,0,24,0,36,0,24,0,24,0
   340 DATA 24,0,24,0,36,0,36,0,36,0,66,0,66,0,129,0,255,0
   350 DATA 0,0,0,0,90,0,60,0,36,0,24,0,24,0,36,0,24,0,24,0
   360 DATA 24,0,24,0,36,0,36,0,36,0,66,0,66,0,129,0,255,0
   370 !
   380 FOR ctr=1 TO 38 @ READ bt @ black_pawn$[ctr,ctr]=CHR$(bt) @ NEXT ctr 
   390 FOR ctr=1 TO 38 @ READ bt @ black_rook$[ctr,ctr]=CHR$(bt) @ NEXT ctr 
   400 FOR ctr=1 TO 38 @ READ bt @ black_bishop$[ctr,ctr]=CHR$(bt) @ NEXT ctr 
   410 FOR ctr=1 TO 38 @ READ bt @ black_knight$[ctr,ctr]=CHR$(bt) @ NEXT ctr 
   420 FOR ctr=1 TO 38 @ READ bt @ black_king$[ctr,ctr]=CHR$(bt) @ NEXT ctr 
   430 FOR ctr=1 TO 38 @ READ bt @ black_queen$[ctr,ctr]=CHR$(bt) @ NEXT ctr 

									    24

   440 !
   450 FOR ctr=1 TO 38 @ READ bt @ white_pawn$[ctr,ctr]=CHR$(bt) @ NEXT ctr 
   460 FOR ctr=1 TO 38 @ READ bt @ white_rook$[ctr,ctr]=CHR$(bt) @ NEXT ctr 
   470 FOR ctr=1 TO 38 @ READ bt @ white_bishop$[ctr,ctr]=CHR$(bt) @ NEXT ctr 
   480 FOR ctr=1 TO 38 @ READ bt @ white_knight$[ctr,ctr]=CHR$(bt) @ NEXT ctr 
   490 FOR ctr=1 TO 38 @ READ bt @ white_king$[ctr,ctr]=CHR$(bt) @ NEXT ctr 
   500 FOR ctr=1 TO 38 @ READ bt @ white_queen$[ctr,ctr]=CHR$(bt) @ NEXT ctr 
   510 !
   520 increment=29 
   530 x_count=139+11 
   540 y_1=12+24 
   550 y_2=y_1+increment 
   560 y_3=y_1+6*increment 
   570 y_4=y_3+increment 
   580 !
   590 FOR ctr=1 TO 8 
   600    !
   610    MOVE x_count,y_1 
   620    IF ctr=1 THEN BPLOT black_rook$,2 
   630    IF ctr=2 THEN BPLOT black_knight$,2 
   640    IF ctr=3 THEN BPLOT black_bishop$,2 
   650    IF ctr=4 THEN BPLOT black_king$,2 
   660    IF ctr=5 THEN BPLOT black_queen$,2 
   670    IF ctr=6 THEN BPLOT black_bishop$,2 
   680    IF ctr=7 THEN BPLOT black_knight$,2 
   690    IF ctr=8 THEN BPLOT black_rook$,2 
   700    !
   710    MOVE x_count,y_2 @ BPLOT black_pawn$,2 
   720    !
   730    MOVE x_count,y_3 @ BPLOT white_pawn$,2 
   740    !
   750    MOVE x_count,y_4 
   760    IF ctr=1 THEN BPLOT white_rook$,2 
   770    IF ctr=2 THEN BPLOT white_knight$,2 
   780    IF ctr=3 THEN BPLOT white_bishop$,2 
   790    IF ctr=4 THEN BPLOT white_king$,2 
   800    IF ctr=5 THEN BPLOT white_queen$,2 
   810    IF ctr=6 THEN BPLOT white_bishop$,2 
   820    IF ctr=7 THEN BPLOT white_knight$,2 
   830    IF ctr=8 THEN BPLOT white_rook$,2 
   840    !
   850    x_count=x_count+increment 
   860    !
   870 NEXT ctr 
   880 !
   890 END 

Note that the display has been given a SCALE that corresponds exactly to the
pixel resolution of the display; this gave me precise control over the
positioning of the different bitmaps.

                                                                            25

+ We have discussed a number of ways of scaling and selecting regions of the
display.  It's also (in principle) possible to specify a plotting area and
scale the display in metric units using the LIMIT and MSCALE commands.

The LIMIT command has the syntax:

	LIMIT x_min, x_max, y_min, y_max

Each of the parameters sets a corner of the plotting area, as measured in
millimeters, referenced to the zero coordinate of the plotting device.

The MSCALE command has the syntax:

	MSCALE x_offset, y_offset

This specifies a metric plotting scale; the offsets give the (0,0) coordinate,
relative to the lower-left corner of the plotting area.  (If SETGU has been
executed, MSCALE scales either the entire display, or the area specified by
LIMIT; otherwise it scales the area specified by the LOCATE command.)

These two commands are fine for external plotters, but trying to make them work
on the display itself is an exercise in frustration - I finally had to give up
and try another approach.

The results of my experiments are illustrated by the following program:

   example_21:
   
   10  ! This program demonstrates scaling in both English and metric units by
   20  ! drawing a six-inch ruler across the top of the display and a ten-
   30  ! centimeter ruler across the bottom of the display.   
   40  !
   50  ! Note that 1 centimeter is roughly 27 pixels, & that 1 inch is roughly 
   60  ! 68 pixels.  The display is rescaled into pixel units for convenience.
   70  !
   80  PEN 1 @ GCLEAR @ LINE TYPE 1 @ CSIZE 8 @ LORG 5 
   90  LOCATE 0,200,0,100 @ SCALE 0,511,0,254 
   100 !
   110 CLIP 52,460,157,225 @ FRAME !     Create 6" x 1" ruler.
   120 AXES 68,0,52,157,0,0,12 
   130 MOVE 255,140 @ LABEL USING "K" ; "Inches!"
   140 !        
   150 CLIP 93,417,50,77 @ FRAME !       Create 12 cm x 1 cm ruler.
   160 AXES 27,0,93,50,0,0,6 
   170 MOVE 255,25 @ LABEL USING "K" ; "Centimeters!"
   180 !        
   190 END 


									    26

+ That ends my discussion of BASIC graphics commands; the commands I have
discussed should be adequate for almost all graphics tasks in BASIC - but there
are a number of commands which I did not discuss.

The following list outlines the remaining graphics commands; the ambitious may
wish to pursue the matter further on their own.

   * BREAD - Like BPLOT but allows bitmaps to be read from the display.
   * DIGITIZE - Gets pen position from plotting device.
   * GLOAD - Display an old graphics display that has been stored by GSTORE.
   * GSTORE - Stores a graphics display into a specified file.
   * IPLOT - A command that merges the functions of IMOVE and IDRAW.
   * LGRID - Similar to LAXES but labels a grid.
   * PENUP - Lifts the plotting pen.
   * PLOT - A command that merges the functions of MOVE and DRAW.
   * RPLOT - Similar to IPLOT.
   * UNCLIP - Cancels boundaries set by CLIP or LOCATE.
   * XAXIS - Like AXES but draws x-axis only.
   * YAXIS - Like AXES but draws y-axis only.


+ Finally, a few comments.

Most of the examples used in this program are designed under the assumption
that the menu keys on the IPC's display are not visible.  It's easy to make
sure that the keys are off with the command:

   50  DISP CHR$(27)&"&j@" !          "50" is just some arbitrary line number.

The menu keys can be turned back on with:

   90  DISP CHR$(27)&"&jB"

All the examples in this document have assumed that the plotting device is the
display.  Of course, it can be an external plotter as well.  For example, if
the plotter were an HP-IB device at address 5, the following sequence of
commands would make it the active plotting device, instead of the display:

   30  ASSIGN 7 TO "hpib" @ PLOTTER IS 705

Similarly, a serial plotter would be installed as the active plotting device
with the command sequence:

   30 ASSIGN 5 TO "serial.a" @ PLOTTER IS 5

Note that the ASSIGN parameter is either "serial.a" or "serial.b", depending on
which I/O slot the serial card has been installed in.  Note also that this
command sequence does NOTHING to set the serial port up to the proper baud
rate, handshaking, parity, and so forth - they have to be set using serial
I/O commands, which is another sticky subject entirely.  (Use an HP-IB plotter
if at all possible.)

									    27

The display can be made the active plotting device again by invoking:

   150 PLOTTER IS 1

Display graphics can be dumped to the printer using the DUMP GRAPHICS command.
Note, unfortunately, that DUMP GRAPHICS has a bug; if any other command tries
to print anything while DUMP GRAPHICS is sending material to the printer, BAD
THINGS will happen.  Use the WAIT command to allow enough time to complete the
plot before trying any further printing ... WAIT 20000 (20 seconds) should be
long enough.

