
  '    PC AND AMIGA PLOTTER
  '    BY DALE HOLT, 1 SEPTEMBER 1987
  '    ROUTE 3, BOX 3532
  '    MANCHESTER, TN  37355

START:
 IF FRE(0)<25000 THEN  CLEAR ,120000&,4096   'FOR THE AMIGA

 MAXPTS=500
 MAXROWS=448/8
 MAXCOLS=448
 MAXCURVES=9
 DIM PLOTARRAY%(MAXROWS,MAXCOLS), DOTMASK%(7)
 DIM X%(MAXPTS,MAXCURVES), Y%(MAXPTS,MAXCURVES)
 DIM PT(MAXPTS,1), SCALEVALUE(1,14), GRIDPOS(1,14)
 DIM PLOTSIZE(1), SCALEMIN(1), SCALEMAX(1), SCALEFAC(1)
 DIM NUMSTEPS(1), LABELWID(1)
 DIM NUMPTS(MAXCURVES), FILENAME$(MAXCURVES)
 DIM SEGMENTS(MAXCURVES), MARKERS(MAXCURVES), YESNO$(1)
 DIM MINVAL(1), MAXVAL(1), XY$(1), LEXP$(1), AXISTYPE$(1)

 ' AXIS=0 FOR X AXIS, AXIS=1 FOR Y AXIS
 ' PLOTSIZE(AXIS) = PLOT SIZE IN DOTS

PLOTTER:
 'SCREEN 0 : COLOR 2,1       'FOR THE IBM
 CLS

 PRINT "DATA PLOTTER V3.0"
 PRINT "COPYRIGHT (C) 1987 by DALE HOLT"

 FOR J=0 TO 7 :DOTMASK%(J)=2^J :NEXT
 YESNO$(0)="NO"
 YESNO$(1)="YES"
 XY$(0)="X"
 XY$(1)="Y"
 X=0
 Y=1
 NO=0
 YES=1
 FIRST=YES
 CURVE=0
 SCREENDUMP=NO
 LOG10=LOG(10)
 INTERACTIVE=YES
 GOSUB DEFAULTS

 PRINT "The X - Y Plotter Program by Dale Holt."
 PRINT "HELP is available as an OPTION."

 NUMOPTS=0

MORE:
 LINE INPUT "OPTION? [NONE] ",OPTLINE$
 GOSUB TRIMOPTION
 IF OPTLINE$="" GOTO PROCESS
 GOSUB PROCESSOPTION
 GOTO MORE


PROCESS:
 PRINT NUMOPTS;"options applied."
 INTERACTIVE=NO

 ' ******************************************
 ' *   GET DATA POINT PLOT PARAMETERS       *
 ' ******************************************

SCREENPLOT:
 GOSUB NEWFILE      ' GET A FILE OF DATA

 IF FIRST=YES THEN
   T1=TIMER
   W=500*XFACTOR
   H=160*YFACTOR
   PLOTSIZE(X)=W-1
   PLOTSIZE(Y)=H-1
 END IF

 IF FIRST=YES THEN GOSUB XMAX

 GOSUB SCALE

 T2=TIMER-T1
 PRINT "Plot calculations fininshed in ";T2;" seconds."

 'SCREEN SCRMODE      'FOR THE IBM
 CLS

   IF NUMERICS=YES THEN
   
   ' PRINT Y GRID VALUES
     FOR J=0 TO NUMSTEPS(Y)
       PARM$=STR$(SCALEVALUE(Y,J))
       GOSUB TRIMSTR
       PARM$=LEXP$(Y)+PARM$
       LOCATE 22-J*20/NUMSTEPS(Y),(10-LEN(PARM$))*XFACTOR
       PRINT PARM$; 
     NEXT

     ' PRINT X GRID VALUES
     LOCATE 23,12*XFACTOR
     PARM$=STR$(SCALEVALUE(X,0))
     GOSUB TRIMSTR
     PARM$=LEXP$(X)+PARM$
     PRINT PARM$;  ' X MIN
     PARM$=STR$(SCALEVALUE(X,NUMSTEPS(X)))
     GOSUB TRIMSTR
     PARM$=LEXP$(X)+PARM$
     LOCATE 23,(76-LEN(PARM$))*XFACTOR
     PRINT PARM$;  ' X MAX
   END IF

   ' DRAW THE GRIDS
   IF GRIDS=YES THEN
     XOFF=100*XFACTOR
     YOFF=170*YFACTOR
     XE=GRIDPOS(X,NUMSTEPS(X))
     YE=GRIDPOS(Y,NUMSTEPS(Y))
     FOR J=0 TO NUMSTEPS(Y)       ' HORIZONTAL LINES
       LINE (XOFF+2,YOFF-GRIDPOS(Y,J))-(XOFF+XE,YOFF-GRIDPOS(Y,J)),2
     NEXT

     FOR J=0 TO NUMSTEPS(X)       ' VERTICAL LINES
       LINE (XOFF+GRIDPOS(X,J),YOFF-2)-(XOFF+GRIDPOS(X,J),YOFF-YE),2
     NEXT
   END IF

   LOCATE 1,(45-LEN(TITLE$)/2)*XFACTOR
   PRINT TITLE$;

   LOCATE 1,10*XFACTOR
   PRINT YLABEL$;

   LOCATE 23,(45-LEN(XLABEL$)/2)*XFACTOR
   PRINT XLABEL$;

   LINE (94*XFACTOR,7*YFACTOR)-(608*XFACTOR,174*YFACTOR),1,B :' PLOT BOX

  ' DRAW THE CURVE
  TINT=3  ' FOR THE AMIGA
  XOFFSET=100*XFACTOR
  YOFFSET=170*YFACTOR
  FOR CURV=0 TO CURVES
    'TINT=14-CURV       ' FOR THE IBM PC
    IF SEGMENTS(CURV)=YES THEN
      PSET (XOFFSET+X%(1,CURV),YOFFSET-Y%(1,CURV)),TINT
      FOR J=2 TO NUMPTS(CURV)
        LINE -(XOFFSET+X%(J,CURV),YOFFSET-Y%(J,CURV)),TINT
      NEXT
    END IF

    ' MARK THE DATA POINTS
    IF MARKERS(CURV)=YES THEN
      BOXSIZE=1
      XL=XOFFSET-1
      XH=XOFFSET+1
      YL=YOFFSET+1    :'   Y IS COUNTED FROM THE TOP DOWN!
      YH=YOFFSET-1
      FOR J=1 TO NUMPTS(CURV)
        LINE (XL+X%(J,CURV),YL-Y%(J,CURV))-(XH+X%(J,CURV),YH-Y%(J,CURV)),TINT,B
      NEXT
    END IF
  NEXT

 FIRST=NO

ANOTH:
 LOCATE 22,1
 PRINT "Add";
 LOCATE 23,1
 INPUT "Curve[N]? ",A$
 IF A$="" THEN A$="N"
 A$=CHR$(ASC(LEFT$(A$,1)) AND 95)
 IF A$="Y" THEN
   CURVE=CURVE+1
   CURVES=CURVES+1
   GOTO SCREENPLOT
 END IF
 IF A$<>"N" THEN BEEP : GOTO ANOTH
   
 LOCATE 23,1
 INPUT "Print[N]?",A$
 IF A$="" THEN END
'A$=CHR$(ASC(LEFT$(A$,1)) AND 95)       'FOR IBM
 A$=UCASE$(A$) 'FOR AMIGA
 IF A$="N" THEN END
 IF A$<>"Y" THEN
   LOCATE 23,1
   PRINT "INVALID!  ";: BEEP
   GOTO ANOTH
 END IF

 SCREENDUMP=YES
 DEVICE$="PRINTER"
 FIRST=YES
 CURVE=0
 T1=TIMER
' SCREEN 0 : COLOR 2,1      ' FOR THE IBM
 CLS

PRINTERPLOT:

 IF T1=0 THEN T1=TIMER
 GOSUB NEWFILE           ' GET A FILE OF DATA
 
 '**************************************
 '*   GET PLOT POSITION VALUES         *
 '**************************************

PW:
 INPUT "Plot Width in cm (4.5-18) [18]?",W
 IF W=0 THEN W=18
 W=INT(W*23.6)     :' 23.6 DOTS PER CM
 IF (W<100) OR (W>448) THEN PRINT "INVALID! "; :BEEP :GOTO PW

PH:
 INPUT "Plot Height in cm (4.5-16) [16]? ",H
 IF H=0 THEN H=16
 H=INT(H*28.3)     :' 28.3 DOTS PER CM
 IF (H<100) OR (H>452) THEN PRINT "INVALID! "; :BEEP :GOTO PH
 HM=INT(H/8)
 H=HM*8
 WM=W+1

 PLOTSIZE(X)=W-1
 PLOTSIZE(Y)=H-1

XM:
 GOSUB XMAX      ' FIND MAX AND MIN, THEN SCALE THE AXIS
 GOSUB SCALE

 IF W<=472-LABELWID(X)*6 GOTO LMSET
 W=472-LABELWID(X)*6  :' WIDTH MUST BE MADE SMALLER
 GOTO XM

LMSET:
 LX=INT((472-W)/6)-LABELWID(X)
 IF LX<1 GOTO DRAWCURVE
 PRINT "Left Margin in characters (0 -";LX;") [0]";
 INPUT " ",LN
 LN=INT(LN)
 IF (LN<0) OR (LN>LX) THEN PRINT "INVALID! "; :BEEP :GOTO LMSET
 LM=LN+LABELWID(X)

DRAWGRIDS:
 IF GRIDS=YES THEN
   PRINT "Drawing the grids."
   FOR J=0 TO NUMSTEPS(Y)
     R=GRIDPOS(Y,J)
     FOR C=1 TO W STEP 3
       GOSUB POINTON
     NEXT
   NEXT

   FOR J=0 TO NUMSTEPS(X)
     C=GRIDPOS(X,J)
     FOR R=1 TO H STEP 3
       GOSUB POINTON
     NEXT
   NEXT
 END IF

DRAWCURVE:
 PRINT
 PRINT
 LOCATE 22,1
 PRINT "Drawing line segment:          of";NUMPTS(CURVE)-1;
 PRINT "for curve ";CURVE+1
 IF SEGMENTS(CURVE)=YES THEN
   XBEGIN=X%(1,CURVE)
   YBEGIN=Y%(1,CURVE)
   FOR J=2 TO NUMPTS(CURVE)
     LOCATE 22,22
     PRINT J-1;
     XEN=X%(J,CURVE)
     YEN=Y%(J,CURVE)
     GOSUB DRAWLINE
   NEXT
   PRINT
   PRINT
 END IF

 IF MARKERS(CURVE)=YES THEN
   FOR J=1 TO NUMPTS(CURVE)
     XBEGIN=X%(J,CURVE)
     YBEGIN=Y%(J,CURVE)
     GOSUB MARKER
   NEXT
 END IF

 IF SCREENDUMP=YES AND CURVE<CURVES THEN
   FIRST=NO
   CURVE=CURVE+1
   GOSUB NEWFILE         ' GET NEXT DATA FILE
   GOSUB SCALE
   GOTO DRAWCURVE
 END IF
 SCREENDUMP=NO


ANOTHER:
 IF CURVES<MAXCURVES THEN
   INPUT "Overlay another curve [N]? ",A$
   IF A$="" THEN A$="N"
   A$=CHR$(ASC(LEFT$(A$,1)) AND 95)
   IF A$="Y" THEN
     CURVE=CURVE+1
     CURVES=CURVES+1
     GOTO PRINTERPLOT
   END IF
   IF A$="N" GOTO PRINTPLOT
   PRINT "INVALID!  ";
   BEEP
   GOTO ANOTHER
 END IF

 ' **********************************
 ' *        START THE PLOT          *
 ' **********************************

PRINTPLOT:
 PRINT: PRINT "Printing the plot of ";TITLE$

 OPEN "PAR:" FOR OUTPUT AS #1     ' FOR AMIGA
 'OPEN "LPT1:" FOR OUTPUT AS #1    ' FOR IBM
 WIDTH #1,255

 C=INT(LM+W/12-LEN(TITLE$)*.5)
 IF (C+LEN(TITLE$))>80 THEN C=80-LEN(TITLE$)
 PRINT #1,SPC(C);TITLE$
 PRINT #1,""
 PRINT #1,SPC(LM-4);YLABEL$ :' Y AXIS LABEL

 PRINT
 PRINT
 LOCATE 23,1
 PRINT "Lines left to print: ";

 ' ***************************************************
 ' *           SEND MX 80 ESCAPE SEQUENCE            *
 ' ***************************************************
 PRINT #1,GLFDOTS$; :' (8) DOTS PER LF
 DW=W+8
 IF DW>255 THEN N2=INT(DW/256)
 N1=DW-N2*256
 DW$=CHR$(27)+CHR$(75)+CHR$(N1)+CHR$(N2)
 PRINT #1,SPC(LM);DW$;CHR$(15);CHR$(15);
 FOR J=1 TO W+4
  PRINT #1,CHR$(12);
 NEXT
 PRINT #1,CHR$(15);CHR$(15)
 YGRID=NUMSTEPS(Y)
 FOR J=HM-1 TO 0 STEP -1
   LOCATE 23,23
   PRINT J+1;
   IF NUMERICS=YES AND J<=GRIDPOS(Y,YGRID)/8 THEN
     PARM$=STR$(SCALEVALUE(1,YGRID))
     GOSUB TRIMSTR
     PARM$=LEXP$(Y)+PARM$
     PRINT #1,SPC(LM-1-LEN(PARM$));
     PRINT #1,PARM$;" ";
     YGRID=YGRID-1
   ELSE
     PRINT #1,SPC(LM);
   END IF
   PRINT #1,DW$;CHR$(255);CHR$(255);CHR$(0);CHR$(0);
   FOR N=1 TO W
     PRINT #1,CHR$(PLOTARRAY%(J,N));
   NEXT
   PRINT #1,CHR$(0);CHR$(0);CHR$(255);CHR$(255)
 NEXT
 PRINT #1,SPC(LM);DW$;CHR$(240);CHR$(240);
 FOR J=1 TO W+4
   PRINT #1,CHR$(48);
 NEXT
 PRINT #1,CHR$(240);CHR$(240)

 SC=0
 IF NUMERICS=YES THEN
   FOR J=0 TO NUMSTEPS(X)-1
     PARM$=STR$(SCALEVALUE(X,J))
     GOSUB TRIMSTR
     PARM$=LEXP$(X)+PARM$
     C=LM+GRIDPOS(X,J)/6-LEN(PARM$)/2
     PRINT #1,SPC(C-SC);PARM$;
     SC=C+LEN(PARM$)
   NEXT
   PARM$=STR$(SCALEVALUE(X,NUMSTEPS(X)))
   GOSUB TRIMSTR
   PARM$=LEXP$(X)+PARM$
   C=LM+GRIDPOS(X,NUMSTEPS(X))/6-LEN(PARM$)
   PRINT #1,SPC(C-SC);PARM$;
 END IF
 PRINT #1,NLFDOTS$  ' RESET PRINTER (DOTS PER LF)
 C=INT(LM+W/12+.5-LEN(XLABEL$)*.5)
 IF (C+LEN(XLABEL$))>80 THEN C=80-LEN(XLABEL$)
 PRINT #1,SPC(C);XLABEL$ ' X AXIS LABEL
 PRINT #1,"" : PRINT #1,"": PRINT #1,""
 CLOSE #1
 BEEP
 T2=TIMER-T1
 PRINT
 PRINT "Plot finished in ";T2;" seconds."
 END



 ' *********************************
 ' *       SUBROUTINES             *
 ' *********************************


NEWFILE:

 IF SCREENDUMP=YES THEN
   DATAFILE$=FILENAME$(CURVE)
 ELSE
   INPUT "Disk Data File [DATA, (?path for files)]? ",DATAFILE$
   IF DATAFILE$="" THEN DATAFILE$="DATA"
   FILENAME$(CURVE)=DATAFILE$

   IF LEFT$(DATAFILE$,1)="?" THEN
     FILES RIGHT$(DATAFILE$,LEN(DATAFILE$)-1)
     GOTO NEWFILE
   END IF
 END IF

 ON ERROR GOTO NOFILE
 OPEN DATAFILE$ FOR INPUT AS #1
 ON ERROR GOTO 0

 PRINT "Reading file ";DATAFILE$

 NUMOPTS=0
 OPTLINES=0
OPTIONLINE:
 IF EOF(1) THEN            ' FILE MAY ONLY CONTAIN OPTION
   PRINT NUMOPTS;"options applied."
   CURVES=CURVES+1
   CURVE=CURVE+1
   GOTO NEWFILE
 END IF
 LINE INPUT #1,OPTLINE$
 IF ECHO=YES THEN PRINT OPTLINE$
 GOSUB TRIMOPTION
 FC$=LEFT$(OPTLINE$,1)             ' FIRST CHARACTER
 IF FC$="-" OR FC$="+" OR FC$="." OR (FC$=>"0" AND FC$<="9") GOTO READFILE
 GOSUB PROCESSOPTION
 OPTLINES=OPTLINES+1
 GOTO OPTIONLINE


READFILE:
 PRINT NUMOPTS;"options applied."

 CLOSE #1
 OPEN DATAFILE$ FOR INPUT AS #1

 FOR J=1 TO OPTLINES              ' SKIP OPTION LINES THIS TIME
   LINE INPUT #1,OPTLINE$
 NEXT J

 NUMPTS=0
 IF XCOL=0 THEN
   C1=0
   C2=1
 ELSE
   C1=1
   C2=0
 END IF

 WHILE NOT EOF(1)
 
   NUMPTS=NUMPTS+1
   IF DATATYPE$="X,Y" THEN INPUT #1,PT(NUMPTS,C1),PT(NUMPTS,C2)
   IF DATATYPE$="UNIFORM" THEN INPUT #1,PT(NUMPTS,Y): PT(NUMPTS,X)=NUMPTS
   IF ECHO=YES THEN PRINT PT(NUMPTS,X);TAB(12);PT(NUMPTS,Y)
   
 WEND
 
 NUMPTS(CURVE)=NUMPTS

 CLOSE #1

 PRINT
 PRINT "Data points read:";NUMPTS

 RETURN

NOFILE:
  PRINT "File ";FILENAME$;" cannot be opened!"
  BEEP
  IF SCREENDUMP=YES THEN
    PRINT "Cannot continue with the plot.  File is gone."
    SCREENDUMP=NO
  END IF
  RESUME NEWFILE

XMAX:
 ' FIND X MAX AND MIN
 LOW=PT(1,X)
 HIGH=LOW
 FOR J=1 TO NUMPTS(CURVE)
   IF PT(J,X)<LOW THEN LOW=PT(J,X)
   IF PT(J,X)>HIGH THEN HIGH=PT(J,X)
 NEXT

XSCALE:
 ' DETERMINE SCALE FOR X AXIS
 IF FIRST=YES THEN
   AXIS=X
   NSTEPS=INT((W+1)/40)
   IF DEVICE$="SCREEN" THEN NSTEPS=NSTEPS/2
   PRINT
   GOSUB SCALEAXIS
 END IF

YMAX:
 ' FIND Y MAX AND MIN
 LOW=PT(1,Y)
 HIGH=LOW
 FOR J=1 TO NUMPTS(CURVE)
   IF PT(J,Y)<LOW THEN LOW=PT(J,Y)
   IF PT(J,Y)>HIGH THEN HIGH=PT(J,Y)
 NEXT

YSCALE:
 ' DETERMINE SCALE FOR Y AXIS
 IF FIRST=YES THEN
   AXIS=Y
   NSTEPS=INT(H/45)
   GOSUB SCALEAXIS
 END IF

 RETURN

SCALE:
 PRINT "Scaling the values for curve ";CURVE+1
 ' SCALE VALUES TO NUMBER OF DOTS
 IF AXISTYPE$(X)="LOG" THEN
   FOR J=1 TO NUMPTS(CURVE)
     PT(J,X)=LOG(PT(J,X))/LOG10
   NEXT J
 END IF
 IF AXISTYPE$(Y)="LOG" THEN
   FOR J=1 TO NUMPTS(CURVE)
     PT(J,Y)=LOG(PT(J,Y))/LOG10
   NEXT J
 END IF
 FOR J=1 TO NUMPTS(CURVE)
   X%(J,CURVE)=INT((PT(J,X)-SCALEMIN(X))*SCALEFAC(X)+1)
   Y%(J,CURVE)=INT((PT(J,Y)-SCALEMIN(Y))*SCALEFAC(Y)+1)
 NEXT

 IF DEVICE$="SCREEN" THEN
   FOR J=1 TO NUMPTS(CURVE)
     IF X%(J,CURVE)<0 THEN X%(J,CURVE)=1
     IF X%(J,CURVE)>W THEN X%(J,CURVE)=W-2
     IF Y%(J,CURVE)<0 THEN Y%(J,CURVE)=1
     IF Y%(J,CURVE)>H THEN Y%(J,CURVE)=H-2
   NEXT
 END IF

 RETURN

 ' ********************
 ' *   AUTO SCALING   *
 ' ********************

SCALEAXIS:
 IF SCALE$="AUTO" THEN
   IF AXISTYPE$(AXIS)="LINEAR" GOTO LINAUTOSCALE
   IF AXISTYPE$(AXIS)="LOG" GOTO LOGAUTOSCALE
 ELSE
   IF AXISTYPE$(AXIS)="LINEAR" GOTO LINMANSCALE
   IF AXISTYPE$(AXIS)="LOG" GOTO LOGMANSCALE
 END IF

LOGMANSCALE:
 LOW=MINVAL(AXIS)
 HIGH=MAXVAL(AXIS)

LOGAUTOSCALE:
 IF LOW<=0 OR HIGH <=0 THEN
   PRINT "Only positive values can be plotted on a LOG scale!"
   BEEP
   LINE INPUT "Hit RETURN to continue.",A$
   GOTO PLOTTER
 END IF
 LMIN=INT(LOG(LOW)/LOG10)
 LMAX=INT(LOG(HIGH)/LOG10+.9999)
 NS=LMAX-LMIN-1
 IF NS>10 THEN
   LMIN=LMAX-10
   NS=9
   PRINT "RANGE TRUNCATED TO 10 DECADES."
 END IF
 LOW=LMIN
 HIGH=LMAX
 GOTO LINAUTOSCALE

LINMANSCALE:
 LOW=MINVAL(AXIS)
 HIGH=MAXVAL(AXIS)
 NS=NSTEPS
 ST=(HIGH-LOW)/NS
 GOTO SETSCALE

LINAUTOSCALE:
 IF LOW=HIGH THEN LOW=.9*LOW: HIGH=1.1*HIGH
 IF LOW=HIGH THEN LOW=-1: HIGH=1
 ST=(HIGH-LOW)/NSTEPS
 POWER=0
 WHILE ST<.5
   POWER=POWER-1
   ST=ST*10
 WEND
 WHILE ST>5
   POWER=POWER+1
   ST=ST/10
 WEND
 IF ST<=1 THEN
   FS=1
 ELSEIF ST<=2 THEN
   FS=2
 ELSEIF ST<=3 THEN
   FS=3
 ELSE
   FS=5
 END IF
 ST=(FS)*10^POWER
 ST=VAL(STR$(ST))
 LOLIM=ST*INT(LOW/ST)
 IF LOW<LOLIM THEN LOLIM=LOLIM-ST
 LOW=LOLIM
 HILIM=ST*INT(HIGH/ST)
 IF HIGH > HILIM THEN HILIM=HILIM+ST
 HIGH=HILIM
 NS=INT((HIGH-LOW)/ST+.5)

SETSCALE:
 ' PRINT THE STEPS
 PRINT XY$(AXIS);" steps: ";
 LABELWID(AXIS)=0
 FOR J=0 TO NS
 SCALEVALUE(AXIS,J)=LOW+J*ST
 PRINT SCALEVALUE(AXIS,J);
 IF LEN(STR$(SCALEVALUE(AXIS,J)))>LABELWID(AXIS) THEN
   LABELWID(AXIS)=LEN(STR$(SCALEVALUE(AXIS,J)))
 END IF
 NEXT
 PRINT
 PRINT
 SCALEMIN(AXIS)=LOW
 SCALEMAX(AXIS)=HIGH
 NUMSTEPS(AXIS)=NS
 SCALEFAC(AXIS)=(PLOTSIZE(AXIS)-1)/(HIGH-LOW)
 FOR J=0 TO NS
 GRIDPOS(AXIS,J)=1+INT((SCALEVALUE(AXIS,J)-LOW)*SCALEFAC(AXIS)+.5)
 NEXT
 LABELWID(AXIS)=LABELWID(AXIS)+LEN(LEXP$(AXIS))+2
 RETURN

DRAWLINE:
 IF XEN=XBEGIN AND YEN=YBEGIN THEN
   C=XBEGIN
   R=YBEGIN
   GOSUB POINTON
 ELSEIF XEN=XBEGIN THEN
   C=XBEGIN
   FOR R=YBEGIN TO YEN STEP SGN(YEN-YBEGIN)
     GOSUB POINTON
   NEXT
 ELSEIF YEN=YBEGIN THEN
   R=YBEGIN
   FOR C=XBEGIN TO XEN STEP SGN(XEN-XBEGIN)
     GOSUB POINTON
   NEXT
 ELSE
   SLOPE=(YEN-YBEGIN)/(XEN-XBEGIN)
   RPAST=INT(YBEGIN)
   FOR C=XBEGIN TO XEN STEP SGN(XEN-XBEGIN)
     R=INT(YBEGIN+SLOPE*(C-XBEGIN)+.5)
     IF R=RPAST THEN
       GOSUB POINTON
     ELSE
       DIRECTION=SGN(R-RPAST)
       RTEMP=R
       FOR R=RPAST TO RTEMP STEP DIRECTION
         GOSUB POINTON
       NEXT
       R=RTEMP
     END IF
     RPAST=R
   NEXT
 END IF
 XBEGIN=XEN
 YBEGIN=YEN
 RETURN

POINTON:
 R1=INT(R/8)
 BIT=R-8*R1
 IF R1>-1 AND R1<HM AND C>-1 AND C<WM THEN
   PLOTARRAY%(R1,C)=PLOTARRAY%(R1,C) OR DOTMASK%(BIT)
 END IF
 RETURN

MARKER:
 FOR R=YBEGIN-1 TO YBEGIN+1
   FOR C=XBEGIN-1 TO XBEGIN+1
     GOSUB POINTON
   NEXT
 NEXT
 RETURN

DEFAULTS:
 XLABEL$="X"
 YLABEL$="Y"
 TITLE$="DATA PLOT"
 SCALE$="AUTO"
 DATATYPE$="X,Y"
 ECHO=NO
 XCOL=0
 YCOL=1
 NUMERICS=YES
 FOR J=0 TO MAXCURVES
   MARKERS(J)=YES
   SEGMENTS(J)=YES
 NEXT J
 AXISTYPE$(X)="LINEAR"
 AXISTYPE$(Y)="LINEAR"
 GRIDS=YES
 MINVAL(X)=.1
 MAXVAL(X)=10
 MINVAL(Y)=.1
 MAXVAL(Y)=10
 LEXP$(X)=""
 LEXP$(Y)=""
 GLFDOTS$=CHR$(27)+"A"+CHR$(8)
 NLFDOTS$=CHR$(27)+"A"+CHR$(11)
 PRTYPE$="MX80"
 GMODE$="MEDIUM, 640 X 200"
 SCRMODE=2     'FOR IBM
 YFACTOR=1
 XFACTOR=1
 DEVICE$="SCREEN"
 RETURN

PRINTHELP:
 PRINT
 PRINT "This program plots X,Y data on the screen or on a dot matrix printer"
 PRINT "which is Epson MX-80 or IBM compatible.  The default printer type is"
 PRINT "the Epson MX-80.  The default answers are in square brackets."
 PRINT
 PRINT "The data file consists of any number of option lines followed by"
 PRINT "the data points.  By default, each line of data consists of an X and Y"
 PRINT "value separated by a comma.  The default is also for the first column of data"
 PRINT "to be the X axis values.  The DATA = UNIFORM option permits the data"
 PRINT "to consist of only the Y values, with the X values assumed to be"
 PRINT "uniformly spaced."  
 PRINT
 PRINT "An option line consists of an option name and an option value separated"
 PRINT "by an equal sign.  The spelling of the option can be truncated. "
 PRINT "Upper case is not required.  The option SHOW will result in a display"
 PRINT "of the current values of the options, which are:"
 PRINT
 
 LINE INPUT "Hit RETURN for more...",A$
 
 PRINT
 PRINT "TITLE = string                  (string for plot title)"
 PRINT "XLABEL = string                 (string for X axis label)"
 PRINT "YLABEL = string                 (string for Y axis label)"
 PRINT "PRINTER = IBM or MX80           (sets the escape code for dots/lf)"
 PRINT "MARKERS = YES or NO             (draw a marker for each data point)"
 PRINT "SEGMENTS = YES or NO            (draw line segments between data points)"
 PRINT "XCOLUMN = 0 or 1                (which column has the x values)"
 PRINT "ECHO = YES or NO                (print X - Y data to the screen)"
 PRINT "GRIDS = YES or NO               (draw grid lines)"
 PRINT "REMARK = comment                (ignore this comment line)"
 PRINT "DATA = X,Y or UNIFORM           (data is X,Y or just Y uniformly spaced)"
 PRINT "NUMERICS = YES or NO            (print numbers along the grid axes)"
 PRINT

 LINE INPUT "Hit RETURN for more...",A$

 PRINT
 PRINT "****** The following options may NOT be set after the first file ******"
 PRINT
 PRINT "SCALE = MANUAL or AUTO          (manual or automatic scaling)"
 PRINT "XMINIMUM = value                (minimum X value for manual scaling)"
 PRINT "XMAXIMUM = value                (maximum X value for manual scaling)"
 PRINT "YMINIMUM = value                (minimum Y value for manual scaling)"
 PRINT "YMAXIMUM = value                (maximum Y value for manual scaling)"
 PRINT "XAXIS = LINEAR or LOGARITHMIC   (X axis type)"
 PRINT "YAXIS = LINEAR or LOGARITHMIC   (Y axis type)"
' PRINT "SCREEN = LOW, MEDIUM, or HIGH   (set the screen resolution)"
' PRINT "                                (320x200, 640x200, or 640x350)"
 PRINT
 PRINT "****** The following options may only be set from the keyboard ******"
 PRINT
 PRINT "DEVICE = SCREEN or PRINTER      (put the plot on the screen or printer)"
 PRINT "RESET                           (reset all options to default values)"
 PRINT "HELP                            (print this information)"
 PRINT
 PRINT "Any contribution would be appreciated.  Dale Holt"
 PRINT "    ($10 perhaps?)                      Rt 3 Box 3532"
 PRINT "                                        Manchester, TN 37355"
 RETURN

TRIMOPTION:
 PARM$=OPTLINE$
 GOSUB TRIMSTR
 OPTLINE$=PARM$
 RETURN

PROCESSOPTION:
 IF OPTLINE$="" THEN RETURN
 OPTIONVAL$=""
 PC=INSTR(OPTLINE$,"=")
 IF PC=0 THEN
   OPTIONVAL$=""
 ELSE
   OPTIONVAL$=MID$(OPTLINE$,PC+1,LEN(OPTLINE$))
   OPTLINE$=LEFT$(OPTLINE$,PC-1)
   WHILE RIGHT$(OPTLINE$,1)=" "
     OPTLINE$=LEFT$(OPTLINE$,LEN(OPTLINE$)-1)
   WEND
   WHILE LEFT$(OPTIONVAL$,1)=" "
     OPTIONVAL$=RIGHT$(OPTIONVAL$,LEN(OPTIONVAL$)-1)
   WEND
 END IF
 LO=LEN(OPTLINE$)
 IF LO=0 THEN LO=1
 LOV=LEN(OPTIONVAL$)
 IF LOV=0 THEN LOV=1

 TEMP$=""       ' CONVERT OPTION TO UPPER CASE
 FOR L=1 TO LO
   C$=MID$(OPTLINE$,L,1)                   
   IF C$=>"a" AND C$<="z" THEN C$=CHR$(ASC(C$) AND 95)  'FOR IBM
   C$=UCASE$(C$)
   TEMP$=TEMP$+C$
 NEXT
 OPTLINE$=TEMP$

 TEMP$=""       ' CONVERT OPTION VALUE TO UPPER CASE
 LCOPTIONVAL$=OPTIONVAL$      'SAVE LOWERCASE VALUE
 FOR L=1 TO LOV
   C$=MID$(OPTIONVAL$,L,1)
 ' IF C$=>"a" AND C$<="z" THEN C$=CHR$(ASC(C$) AND 95)   'IBM
   C$=UCASE$(C$)  'AMIGA
   TEMP$=TEMP$+C$
 NEXT
 OPTIONVAL$=TEMP$


 IF OPTLINE$=LEFT$("TITLE",LO) THEN
   TITLE$=LCOPTIONVAL$
   NUMOPTS=NUMOPTS+1
   RETURN
 END IF

 IF OPTLINE$=LEFT$("XLABEL",LO) THEN
   XLABEL$=LCOPTIONVAL$
   NUMOPTS=NUMOPTS+1
   RETURN
 END IF

 IF OPTLINE$=LEFT$("YLABEL",LO) THEN
   YLABEL$=LCOPTIONVAL$
   NUMOPTS=NUMOPTS+1
   RETURN
 END IF

 IF OPTLINE$=LEFT$("MARKERS",LO) THEN
   IF OPTIONVAL$=LEFT$("YES",LOV) THEN
     MARKERS(CURVE)=YES
     NUMOPTS=NUMOPTS+1
   ELSEIF OPTIONVAL$=LEFT$("NO",LOV) THEN
     MARKERS(CURVE)=NO
     NUMOPTS=NUMOPTS+1
   ELSE
     GOTO OPTIONERR
   END IF
   RETURN
 END IF
 
 IF OPTLINE$=LEFT$("DATA",LO) THEN
   IF OPTIONVAL$=LEFT$("X,Y",LOV) THEN
     DATATYPE$="X,Y"
     NUMOPTS=NUMOPTS+1
   ELSEIF OPTIONVAL$=LEFT$("UNIFORM",LOV) THEN
     DATATYPE$="UNIFORM"
     NUMOPTS=NUMOPTS+1
   ELSE
     GOTO OPTIONERR
   END IF
   RETURN
 END IF

 IF OPTLINE$=LEFT$("NUMERICS",LO) THEN
   IF OPTIONVAL$=LEFT$("YES",LOV) THEN
     NUMERICS=YES
     NUMOPTS=NUMOPTS+1
   ELSEIF OPTIONVAL$=LEFT$("NO",LOV) THEN
     NUMERICS=NO
     NUMOPTS=NUMOPTS+1
   ELSE
     GOTO OPTIONERR
   END IF
   RETURN
 END IF

 IF OPTLINE$=LEFT$("PRINTER",LO) THEN
   IF OPTIONVAL$=LEFT$("MX80",LOV) THEN
     GLFDOTS$=CHR$(27)+"A"+CHR$(8)
     NLFDOTS$=CHR$(27)+"A"+CHR$(11)
     PRTYPE$="MX80"
     NUMOPTS=NUMOPTS+1
   ELSEIF OPTIONVAL$=LEFT$("IBM",LOV) THEN
     GLFDOTS$=CHR$(27)+"A"+CHR$(8)+CHR$(27)+"2"
     NLFDOTS$=CHR$(27)+"A"+CHR$(11)+CHR$(27)+"2"
     PRTYPE$="IBM"
     NUMOPTS=NUMOPTS+1
   ELSE
     GOTO OPTIONERR
   END IF
   RETURN
 END IF

 IF OPTLINE$=LEFT$("ECHO",LO) THEN
   IF OPTIONVAL$=LEFT$("YES",LOV) THEN
     ECHO=YES
     NUMOPTS=NUMOPTS+1
   ELSEIF OPTIONVAL$=LEFT$("NO",LOV) THEN
     ECHO=NO
     NUMOPTS=NUMOPTS+1
   ELSE
     GOTO OPTIONERR
   END IF
   RETURN
 END IF

 IF OPTLINE$=LEFT$("SEGMENTS",LO) THEN
   IF OPTIONVAL$=LEFT$("YES",LOV) THEN
     SEGMENTS(CURVE)=YES
     NUMOPTS=NUMOPTS+1
   ELSEIF OPTIONVAL$=LEFT$("NO",LOV) THEN
     SEGMENTS(CURVE)=NO
     NUMOPTS=NUMOPTS+1
   ELSE
     GOTO OPTIONERR
   END IF
   RETURN
 END IF

 IF OPTLINE$=LEFT$("XCOLUMN",LO) THEN
   IF OPTIONVAL$="0" THEN
     XCOL=0
     YCOL=1
     NUMOPTS=NUMOPTS+1
   ELSEIF OPTIONVAL$="1" THEN
     XCOL=1
     YCOL=0
     NUMOPTS=NUMOPTS+1
   ELSE
     GOTO OPTIONERR
   END IF
   RETURN
 END IF

 IF OPTLINE$=LEFT$("REMARK",LO) THEN
   RETURN
 END IF

 IF OPTLINE$=LEFT$("GRIDS",LO) THEN
   IF OPTIONVAL$=LEFT$("YES",LOV) THEN
     GRIDS=YES
     NUMOPTS=NUMOPTS+1
   ELSEIF OPTIONVAL$=LEFT$("NO",LOV) THEN
     GRIDS=NO
     NUMOPTS=NUMOPTS+1
   ELSE
     GOTO OPTIONERR
   END IF
   RETURN
 END IF

 IF OPTLINE$=LEFT$("SHOW",LO) THEN
   PRINT
   PRINT "The options are set as follows:"
   PRINT "PRINTER = ";PRTYPE$
   PRINT "SCREEN = ";GMODE$
   PRINT "DEVICE = ";DEVICE$
   PRINT "TITLE = ";TITLE$
   PRINT "XLABEL = ";XLABEL$
   PRINT "YLABEL = ";YLABEL$
   PRINT "SCALE = ";SCALE$
   PRINT "XCOLUMN = ";XCOL
   PRINT "YCOLUMN = ";YCOL
   PRINT "XAXIS = ";AXISTYPE$(X)
   PRINT "YAXIS = ";AXISTYPE$(Y)
   PRINT "GRIDS = ";YESNO$(GRIDS)
   PRINT "ECHO = ";YESNO$(ECHO)
   PRINT "DATA = ";DATATYPE$
   PRINT "NUMERICS = ";YESNO$(NUMERICS)
   PRINT "XMINIMUM = ";MINVAL(X)
   PRINT "XMAXIMUM = ";MAXVAL(X)
   PRINT "YMINIMUM = ";MINVAL(Y)
   PRINT "YMAXIMUM = ";MAXVAL(Y)
   PRINT
   
   LINE INPUT "Hit <ENTER> to continue...",A$
   
   PRINT
   FOR J=0 TO MAXCURVES
     PRINT "MARKERS (CURVE=";J+1;") = ";YESNO$(MARKERS(J))
     PRINT "SEGMENTS(CURVE=";J+1;") = ";YESNO$(SEGMENTS(J))
   NEXT J
   RETURN
 END IF

 IF FIRST=NO THEN GOTO OPTIONERR

 IF OPTLINE$=LEFT$("SCALE",LO) THEN
   IF OPTIONVAL$=LEFT$("AUTO",LOV) THEN
     SCALE$="AUTO"
     NUMOPTS=NUMOPTS+1
   ELSEIF OPTIONVAL$=LEFT$("MANUAL",LOV) THEN
     SCALE$="MANUAL"
     NUMOPTS=NUMOPTS+1
   ELSE
     GOTO OPTIONERR
   END IF
   RETURN
 END IF

 IF OPTLINE$=LEFT$("XAXIS",LO) THEN
   IF OPTIONVAL$=LEFT$("LINEAR",LOV) THEN
     AXISTYPE$(X)="LINEAR"
     LEXP$(X)=""
     NUMOPTS=NUMOPTS+1
   ELSEIF OPTIONVAL$=LEFT$("LOGARITHMIC",LOV) THEN
     AXISTYPE$(X)="LOG"
     LEXP$(X)="10^"
     NUMOPTS=NUMOPTS+1
   ELSE
     GOTO OPTIONERR
   END IF
   RETURN
 END IF

 IF OPTLINE$=LEFT$("YAXIS",LO) THEN
   IF OPTIONVAL$=LEFT$("LINEAR",LOV) THEN
     AXISTYPE$(Y)="LINEAR"
     LEXP$(Y)=""
     NUMOPTS=NUMOPTS+1
   ELSEIF OPTIONVAL$=LEFT$("LOGARITHMIC",LOV) THEN
     AXISTYPE$(Y)="LOG"
     LEXP$(Y)="10^"
     NUMOPTS=NUMOPTS+1
   ELSE
     GOTO OPTIONERR
   END IF
   RETURN
 END IF

 IF OPTLINE$=LEFT$("XMINIMUM",LO) THEN
   MINVAL(X)=VAL(OPTIONVAL$)
   NUMOPTS=NUMOPTS+1
   RETURN
 END IF

 IF OPTLINE$=LEFT$("YMINIMUM",LO) THEN
   MINVAL(Y)=VAL(OPTIONVAL$)
   NUMOPTS=NUMOPTS+1
   RETURN
 END IF

 IF OPTLINE$=LEFT$("XMAXIMUM",LO) THEN
   MAXVAL(X)=VAL(OPTIONVAL$)
   NUMOPTS=NUMOPTS+1
   RETURN
 END IF

 IF OPTLINE$=LEFT$("YMAXIMUM",LO) THEN
   MAXVAL(Y)=VAL(OPTIONVAL$)
   NUMOPTS=NUMOPTS+1
   RETURN
 END IF

' IF OPTLINE$=LEFT$("SCREEN",LO) THEN       'FOR IBM
'   IF OPTIONVAL$=LEFT$("LOW",LOV) THEN
'     GMODE$="LOW, 320 X 200"
'     SCRMODE=1
'     YFACTOR=1
'     XFACTOR=.5
'     NUMOPTS=NUMOPTS+1
'   ELSEIF OPTIONVAL$=LEFT$("MEDIUM",LOV) THEN
'     GMODE$="MEDIUM, 640 X 200"
'     SCRMODE=2
'     YFACTOR=1
'     XFACTOR=1
'     NUMOPTS=NUMOPTS+1
'   ELSEIF OPTIONVAL$=LEFT$("HIGH",LOV) THEN
'     GMODE$="HIGH, 640 X 350"
'     SCRMODE=9
'     YFACTOR=1.75
'     XFACTOR=1
'     NUMOPTS=NUMOPTS+1
'   ELSE
'     GOTO OPTIONERR
'   END IF
'   RETURN
' END IF

 IF INTERACTIVE=NO THEN GOTO OPTIONERR

 IF OPTLINE$=LEFT$("HELP",LO) THEN
   GOSUB PRINTHELP
   RETURN
 END IF

 IF OPTLINE$=LEFT$("RESET",LO) THEN
   GOSUB DEFAULTS
   RETURN
 END IF

 IF OPTLINE$=LEFT$("DEVICE",LO) THEN
   IF OPTIONVAL$=LEFT$("SCREEN",LOV) THEN
     DEVICE$="SCREEN"
     NUMOPTS=NUMOPTS+1
   ELSEIF OPTIONVAL$=LEFT$("PRINTER",LOV) THEN
     DEVICE$="PRINTER"
     NUMOPTS=NUMOPTS+1
   ELSE
     GOTO OPTIONERR
   END IF
   RETURN
 END IF

OPTIONERR:
 PRINT "UNPROCESSED OPTION!   ";OPTLINE$;
 IF OPTIONVAL$<>"" THEN PRINT "=" ;OPTIONVAL$ ELSE PRINT
 RETURN

TRIMSTR:                                
 WHILE LEFT$(PARM$,1)=" "
   PARM$=RIGHT$(PARM$,LEN(PARM$)-1)
 WEND
 WHILE RIGHT$(PARM$,1)=" "
   PARM$=LEFT$(PARM$,LEN(PARM$)-1)
 WEND
 RETURN


END  'END OF PROGRAM

