! This program produces a plot of '.PRINT' statements in SPICE output

! for VAX
!%include "Imp_include:PAM.INC"
!%include "EDWIN_DIR:CONSTS.INC"
!%include "EDWIN_DIR:SPECS.INC"
!%external %routine %spec set default (%string (5) def)

! for APM
%include "INC:UTIL.IMP"
%include "EDWIN:CONSTS.INC"
%include "EDWIN:SPECS.INC"

! for EMAS
!%include "ECSLIB.EDWIN_CONSTS"
!%include "ECSLIB.EDWIN_INC"
!%include "IMP77SPECS"
!%system %integer %map %spec COMREG (%integer no24)
!%external %routine %spec CONVERT (%string (255) parm)
!%external %routine %spec set default (%string (5) def)

%begin
! Number of divisions on the axis.
%own %integer Xdiv = 100, X big div = 10, Xfactor = 0
%own %integer Ydiv = 100, Y big div = 10, Yfactor = 0
%const %integer num words = 5
%const %string (31) %array words (1:num words) = "DC TRANSFER CURVES",
 "AC ANALYSIS", "TRANSIENT ANALYSIS", ".TITLE", "DISTORTION"
%string (15) %array variable (1:9)
%real %array mins (1:9), maxs (1:9)
%real %array val of coor (1:2000, 1:9)
%real big, small, real value
%own %integer lx = 373, rx = 1013, by = 70, ty = 710
%string (255) title, dummy, date, time, name, file name
%integer i, vcount, point, mantissa
%const %integer %array VX ('1':'5') = 20 * 4, 28 * 2, 20 * 2, 28, 20
%const %integer %array VY ('1':'5') = 28 * 2, 20 * 2, 28, 20, 14

%routine readaword (%string (*) %name word)
   skip symbol %while next symbol=' ' %or next symbol=nl
   word=""
   %while next symbol>' ' %cycle
      word=word.to string (next symbol)
      skip symbol
   %repeat
%end

%routine read line (%string (*) %name word)
   %integer S

   read symbol (S) %until S > ' '
   word = to string (s)
   %cycle
      read symbol (s)
      %exit %if s=nl
      word = word.to string(s)
   %repeat
%end

%routine skipspaces
   skipsymbol %while nextsymbol=' '
%end

%routine get date (%string (*) %name date)
   skip symbol %until next symbol = '*'
   skip symbol %until next symbol # '*'
   readaword (date)
%end

%routine get time (%string (*) %name time)
   skip symbol %until next symbol='.'
   skip symbol %until next symbol='*'
   skip symbol %until next symbol#'*' %and next symbol > ' '
   readaword (time)
   %if time->time. ("*") %start ; %finish
%end

%string (255)%fn stop at first word
   ! Get to the next line with a significant word on it -
   ! ie. Line must start with "****"
   ! must contain a valid word.
   ! The result is the line - the stars at the front.
   %integer I

   %cycle
      read line (dummy) %until length (dummy)>4 %and sub string (dummy,2,4)="***"
      dummy = substring (dummy, 5, length(dummy))
      %for I=1,1,num words %cycle
           %result = dummy %if dummy -> (words (I))
      %repeat
   %repeat
%end

%routine test (%integer vcount, point)
   ! Just print out values again
   %integer I,J
   Printstring (title);   newline
   %for J=1,1,vcount %cycle
     printstring (variable (J))
     spaces (14-length (variable (J)))
   %repeat
   newline
   %for I=1,1,point %cycle
     %for J=1,1,vcount %cycle
        print fl (val of coor (I,J),3)
        spaces (5)
     %repeat
     newline
   %repeat
   newlines (3)
%end


%routine find extremes (%integer vcount, point, %real %name small, big)
   %integer I, J, min, max
   %real this
   %for I=2,1,vcount %cycle
     mins (I) = val of coor (1,I)
     maxs (I) = mins (I)
     %for J = 2,1,point %cycle
        this = val of coor (J,I)
        mins (I) = this %if this<mins (I)
        maxs (I) = this %if this>maxs (I)
     %repeat
   %repeat
   min = 2
   max = 2
   %for I=3,1,vcount %cycle
        min = I %if mins(I) < mins(min)
        max = I %if maxs(I) > maxs(max)
   %repeat
   small = mins (min)
   big = maxs (max)
   %if -50 < mins(min) < 50 %and -50 < maxs(max) < 50  %and maxs(max)-mins(min) > 2 %start
       min = int (mins(min)-0.5)
       max = int (maxs(max)+0.5)
       Ydiv = max - min
       %if Ydiv <=10 %start
           Y big div = 10
       %finish %else %if Ydiv <= 25 %start
           Y big div = 5
       %finish %else Y big div = 1
   %finish %else Ydiv = 10
   Ydiv = Ydiv * Y big div
%end

%routine xscale (%integer point)
   %real low, high
   %integer I, xlen, factor
   xlen=rx-lx
   low = val of coor (1, 1)
   high = val of coor (point, 1)
   %for factor = 0, 3, 12 %cycle
        Xfactor=factor %and %exit %if (high-low)*10\factor> 1
   %repeat
   move abs (lx-50, by-45)
   set char size (12)
   text (rtos(low*10\Xfactor, 3, 1))
   move abs (rx-70,by-45)
   text (rtos(high*10\Xfactor, 3, 1))
   xdiv = int ((high-low)*10\factor)
   xbigdiv = 10
   %if Xdiv <= 20 %start
       Xdiv = Xdiv * 10
   %finish
   %for I=0,1,xdiv %cycle
     move abs (int(lx + (I*xlen/xdiv)), by)
     %if rem (i,Xbigdiv)=0 %start
         line rel (0, -15)
     %else
         line rel (0, -10)
     %finish
   %repeat
%end

%routine get line type (%integer line num)
   line num = line num - 2
   %if device data_max colour > 4 %start
       set colour (line num & 7 + 2)
   %else
       set colour (line num&3+1)
       set line style (line num//4)
   %finish
%end

%routine draw (%integer vcount,point)
 %integer I,J,xlen,ylen
 %return %if big=small; ! No changes => nothing to draw
 xlen=rx-lx
 ylen=ty-by
 %for I=2,1,vcount %cycle
   get line type (I)
   move abs (lx,by+int ( ( (val of coor (1,I)-small)*ylen)/ (big-small)))
   %for J=2,1,point %cycle
      line abs (lx+ (J*xlen)//point, by+int ( ( (val of coor (J,I)-small)*ylen)/ (big-small)))
   %repeat
 %repeat
%end


%routine yscale
   %integer xlen, ylen, yval, I, J, end loop
   xlen = rx-lx
   ylen = ty-by
   set char size (12)
   %for i = 0, 3, 12 %cycle
      Yfactor = i %and %exit %if (big-small)*10\i > 1
   %repeat
   small = int (small - 0.5)
   big = int (big + 0.5)
   Ydiv = int ((big-small)*10\i)
   Ybigdiv=1
   %if Ydiv < 25 %start
       Y div = Y div * 10
       Y big div = 10
   %finish
   %for I=0,1,ydiv %cycle
        yval = int (by + (i*Ylen/Ydiv))
        move abs (lx, yval)
        %if rem (i, Y big div)=0 %start
            line rel (-15, 0)
            move rel (-135, -6)
            %if Ybigdiv>1 %or i=0 %or i=Ydiv %start
                J = int (small + (i/Ybigdiv))
                text (itos(j,8).".0")
                %if i#0 %and i#ydiv %start
                    %if j=0 %start
                        end loop = xdiv
                    %else
                        end loop = xbigdiv
                    %finish
                    %for J=1,1,end loop %cycle
                         marker abs (0, lx + int(j*xlen/end loop), yval)
                    %repeat
                %finish
            %finish
        %else
            line rel (-10, 0)
        %finish
   %repeat
%end

%routine do plot (%string (255) heading, %integer vcount, point)
   %string (255) TEMP, F, B
   %integer I

   %string (15) %fn Powers (%integer I)
      %const %string (15) %array Factors (-12 : 9) = 
          "pico", "", "", "nano", "", "", "micro", "", "", "mili",
          "", "", "", "", "", "kilo", "", "", "mega", "", "", "giga"
      %result = "" %if I = 0
      %result = Factors(I) %if -12<=I<=9 %and factors(I)#""
      %result = "ten to the power ".ItoS(I,0)." "
   %end

   find extremes (vcount, point, small, big)
   newframe
   set colour (1)

   temp = "" %unless heading -> heading. ("TEMP").temp
   temp = "TEMP".temp %if temp#""
   heading = f." ".b %while heading -> f.("  ").b
   heading = sub string (heading, 2, length(heading)) %while charno(heading,1)=' ' %or charno(heading,1)='*'
   length (heading) = length (heading) - 1 %if charno (heading,length (heading))=' '

   move abs (10,ty-40)
   set char size (12)
   text (title)

   set char size (6)
   move abs (50,ty-85)
   text (heading)
   move abs (50,ty-120)
   text (date."   ".time)
   move abs (50,ty-155)
   text (temp)

   set char size (12)
   move abs(10,ty-225)
   text("LEGEND:")
   %for I=2,1,vcount %cycle
        get line type(I)
        move abs(30,ty-I*45-200)
        text(variable(I))
        move abs(120,ty-I*45+6-200)
        line rel(90,0)
   %repeat

   set char size(12)
   set colour (1)
   set line style (0)
  
   ! Axis
   move abs (lx, ty);   line abs (lx, by);   line abs (rx, by)
   yscale
   %if yfactor > 0 %start
       move abs (10, 10)
       Text ("Y values are times 10")
       move rel (0, 6)
       text (itos(yfactor,0))
       set char size (12)
   %finish

   xscale (point)
   move abs (600, 12)
   text (variable(1))
   %if xfactor > 0 %start
       %if variable (1) = "TIME" %start
           text (" in ".powers(-xfactor)."-seconds")
       %else
           text (" times 10")
           move rel (0, 6)
           text (itos(-xfactor,0))
           set char size (12)
       %finish
   %finish
   draw (vcount,point)
%end


%routine OPEN IN FILE
   %on 3,9 %start
       PRINT STRING ("SPLOT fails - Cannot open input ".FILENAME)
       NEWLINE
       %stop
   %finish
   OPEN INPUT (1, FILE NAME)
%end

   %on 1, 2, 3, 4, 9, 14 %start
       UPDATE
       %if event_event=14 %start
           print string ("EDWIN error - ".edwin error (event_sub))
           newline
       %finish
       TERMINATE EDWIN
       %stop
   %finish

   i = default device
   filename = ""

   ! Get parameters
   define param ("Spice out file", file name, pam no default + pam major)
   define int param ("Device", i, pam major)
   process parameters (cli param)

   ! APM only, next line
   filename = filename.".DAT" %unless filename -> (".") %and charno(filename,1)#':'
   ! VAX & EMAS, next line
!   set default (".DAT")
   ! EMAS only , the next three lines -
!   CONVERT (FILENAME.",T#SPICE")
!   %signal 9 %if COMREG (24)#0
!   FILENAME = "T#SPICE"
   open in file

   initialise for (i)
   select output (0)
   print string ("Device set to ".device data_name);   newline
   set colour mode (or mode)
   %if device data_units per cm # 0 %start
       select input (0)
       prompt ("Size = A")
       read symbol (i) %until '2'<=i<='5'
       viewport (0, VX (i) * DEVICE DATA_UNITS PER CM ,
                 0, VY (i) * DEVICE DATA_UNITS PER CM)
   %finish
   set char quality (1) %if DEVICE DATA_NUM CHAR SIZES # 255
   window (0, 1023, 0, 730)

   select input (1)
   get date (date)
   get time (time)
   read line (title)
   title = sub string (title, 2, length(title)) %if char no (title,1) = '0'
   length (title) = length(title) - 1 %while charno(title,length(title))=' '
   length (title) = 26 %if length(title)> 26
   %cycle
      select input (1)
      name = stop at first word
      name = name." ".dummy %while name -> name. ("  ").dummy
      read line (dummy) %until charno (dummy,2)='*'
      vcount=0
      %cycle
         vcount=vcount+1
         readaword (variable (vcount))
         skipspaces
      %repeat %until next symbol = NL
      %continue %if vcount = 1
      skip symbol %until '0'<=next symbol<='9' %or next symbol='-'
      point=0
      %cycle
         point=point+1
         %for I=1,1,vcount %cycle
              read (real value)
              %if '@'<=next symbol<='E' %start
                  ! A true real number so get mantissa
                  skip symbol
                  skip symbol %unless next symbol = '-'
                  read (mantissa)
              %finish %else mantissa=0
              val of coor (point, i) = real value * 10 \ mantissa
         %repeat
         skip symbol %while next symbol <= ' '
      %repeat %until %not ('0'<next symbol<='9' %or next symbol='-')
      do plot (name,vcount,point)
   %repeat
%end

%endof %file
